diff --git a/.metadata/.log b/.metadata/.log index 26ba6c2..d3b6dc3 100644 --- a/.metadata/.log +++ b/.metadata/.log @@ -10777,3 +10777,680 @@ Binding(ALT+T, ,,true),null), org.eclipse.ui.defaultAcceleratorConfiguration, org.eclipse.ui.contexts.window,,,system) +!SESSION 2021-01-03 17:13:07.317 ----------------------------------------------- +eclipse.buildId=4.13.0.I20190916-1045 +java.version=1.8.0_91 +java.vendor=Oracle Corporation +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_GB +Framework arguments: -product org.eclipse.epp.package.java.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.java.product + +!ENTRY org.eclipse.jface 2 0 2021-01-03 17:13:14.989 +!MESSAGE Keybinding conflicts occurred. They may interfere with normal accelerator operation. +!SUBENTRY 1 org.eclipse.jface 2 0 2021-01-03 17:13:14.989 +!MESSAGE A conflict occurred for ALT+T: +Binding(ALT+T, + ParameterizedCommand(Command(org.synthclipse.ide.command.TimelineShowView,Timeline / Show View, + , + Category(org.synthclipse.category,Synthclipse,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@58ca6ba3, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) +Binding(ALT+T, + ParameterizedCommand(Command(org.synthclipse.ide.command.GraphShowView,Graph / Show View, + , + Category(org.synthclipse.category,Synthclipse,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@74797b90, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) + +!ENTRY org.eclipse.ui 4 4 2021-01-03 17:13:19.649 +!MESSAGE Unable to create part +!STACK 1 +org.eclipse.ui.PartInitException: Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/ppu/PPU.java'. + at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3210) + at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3221) + at org.eclipse.ui.internal.EditorReference.initialize(EditorReference.java:353) + at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.create(CompatibilityPart.java:340) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:58) + at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:998) + at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:963) + at org.eclipse.e4.core.internal.di.InjectorImpl.internalInject(InjectorImpl.java:139) + at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:408) + at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:331) + at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:202) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.createFromBundle(ReflectionContributionFactory.java:91) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.doCreate(ReflectionContributionFactory.java:60) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.create(ReflectionContributionFactory.java:42) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer.createWidget(ContributedPartRenderer.java:132) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:1002) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer.showTab(StackRenderer.java:1293) + at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:105) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:680) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$1.run(PartRenderingEngine.java:547) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:531) + at org.eclipse.e4.ui.workbench.renderers.swt.ElementReferenceRenderer.createWidget(ElementReferenceRenderer.java:73) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:1002) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveRenderer.processContents(PerspectiveRenderer.java:51) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.showTab(PerspectiveStackRenderer.java:82) + at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:105) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.postProcess(PerspectiveStackRenderer.java:64) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:680) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer.processContents(WBWRenderer.java:665) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1086) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1049) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:633) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:557) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:150) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:660) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:597) + at org.eclipse.equinox.launcher.Main.run(Main.java:1468) +Caused by: org.eclipse.core.runtime.CoreException: Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/ppu/PPU.java'. + at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:239) + at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:115) + at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:563) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.createFileInfo(CompilationUnitDocumentProvider.java:1013) + at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:481) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.connect(CompilationUnitDocumentProvider.java:1277) + at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4212) + at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:260) + at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1478) + at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.internalDoSetInput(JavaEditor.java:2573) + at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.doSetInput(JavaEditor.java:2546) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.doSetInput(CompilationUnitEditor.java:1423) + at org.eclipse.ui.texteditor.AbstractTextEditor.lambda$1(AbstractTextEditor.java:3179) + at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2313) + at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3196) + ... 132 more +!SUBENTRY 1 org.eclipse.core.filebuffers 4 0 2021-01-03 17:13:19.651 +!MESSAGE Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/ppu/PPU.java'. +!STACK 1 +org.eclipse.core.runtime.CoreException: Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/ppu/PPU.java'. + at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:239) + at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:115) + at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:563) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.createFileInfo(CompilationUnitDocumentProvider.java:1013) + at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:481) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.connect(CompilationUnitDocumentProvider.java:1277) + at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4212) + at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:260) + at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1478) + at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.internalDoSetInput(JavaEditor.java:2573) + at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.doSetInput(JavaEditor.java:2546) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.doSetInput(CompilationUnitEditor.java:1423) + at org.eclipse.ui.texteditor.AbstractTextEditor.lambda$1(AbstractTextEditor.java:3179) + at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2313) + at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3196) + at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3221) + at org.eclipse.ui.internal.EditorReference.initialize(EditorReference.java:353) + at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.create(CompatibilityPart.java:340) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:58) + at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:998) + at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:963) + at org.eclipse.e4.core.internal.di.InjectorImpl.internalInject(InjectorImpl.java:139) + at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:408) + at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:331) + at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:202) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.createFromBundle(ReflectionContributionFactory.java:91) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.doCreate(ReflectionContributionFactory.java:60) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.create(ReflectionContributionFactory.java:42) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer.createWidget(ContributedPartRenderer.java:132) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:1002) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer.showTab(StackRenderer.java:1293) + at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:105) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:680) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$1.run(PartRenderingEngine.java:547) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:531) + at org.eclipse.e4.ui.workbench.renderers.swt.ElementReferenceRenderer.createWidget(ElementReferenceRenderer.java:73) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:1002) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveRenderer.processContents(PerspectiveRenderer.java:51) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.showTab(PerspectiveStackRenderer.java:82) + at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:105) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.postProcess(PerspectiveStackRenderer.java:64) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:680) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer.processContents(WBWRenderer.java:665) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1086) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1049) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:633) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:557) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:150) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:660) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:597) + at org.eclipse.equinox.launcher.Main.run(Main.java:1468) +!SUBENTRY 2 org.eclipse.core.filebuffers 4 0 2021-01-03 17:13:19.656 +!MESSAGE Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/ppu/PPU.java'. + +!ENTRY org.eclipse.ui 4 4 2021-01-03 17:13:19.695 +!MESSAGE Unable to create part +!STACK 1 +org.eclipse.ui.PartInitException: Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/application/Application.java'. + at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3210) + at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3221) + at org.eclipse.ui.internal.EditorReference.initialize(EditorReference.java:353) + at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.create(CompatibilityPart.java:340) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:58) + at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:998) + at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:963) + at org.eclipse.e4.core.internal.di.InjectorImpl.internalInject(InjectorImpl.java:139) + at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:408) + at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:331) + at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:202) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.createFromBundle(ReflectionContributionFactory.java:91) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.doCreate(ReflectionContributionFactory.java:60) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.create(ReflectionContributionFactory.java:42) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer.createWidget(ContributedPartRenderer.java:132) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:1002) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer.showTab(StackRenderer.java:1293) + at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:105) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:680) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$1.run(PartRenderingEngine.java:547) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:531) + at org.eclipse.e4.ui.workbench.renderers.swt.ElementReferenceRenderer.createWidget(ElementReferenceRenderer.java:73) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:1002) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveRenderer.processContents(PerspectiveRenderer.java:51) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.showTab(PerspectiveStackRenderer.java:82) + at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:105) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.postProcess(PerspectiveStackRenderer.java:64) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:680) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer.processContents(WBWRenderer.java:665) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1086) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1049) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:633) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:557) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:150) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:660) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:597) + at org.eclipse.equinox.launcher.Main.run(Main.java:1468) +Caused by: org.eclipse.core.runtime.CoreException: Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/application/Application.java'. + at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:239) + at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:115) + at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:563) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.createFileInfo(CompilationUnitDocumentProvider.java:1013) + at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:481) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.connect(CompilationUnitDocumentProvider.java:1277) + at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4212) + at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:260) + at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1478) + at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.internalDoSetInput(JavaEditor.java:2573) + at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.doSetInput(JavaEditor.java:2546) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.doSetInput(CompilationUnitEditor.java:1423) + at org.eclipse.ui.texteditor.AbstractTextEditor.lambda$1(AbstractTextEditor.java:3179) + at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2313) + at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3196) + ... 132 more +!SUBENTRY 1 org.eclipse.core.filebuffers 4 0 2021-01-03 17:13:19.696 +!MESSAGE Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/application/Application.java'. +!STACK 1 +org.eclipse.core.runtime.CoreException: Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/application/Application.java'. + at org.eclipse.core.internal.filebuffers.ResourceFileBuffer.create(ResourceFileBuffer.java:239) + at org.eclipse.core.internal.filebuffers.TextFileBufferManager.connect(TextFileBufferManager.java:115) + at org.eclipse.ui.editors.text.TextFileDocumentProvider.createFileInfo(TextFileDocumentProvider.java:563) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.createFileInfo(CompilationUnitDocumentProvider.java:1013) + at org.eclipse.ui.editors.text.TextFileDocumentProvider.connect(TextFileDocumentProvider.java:481) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider.connect(CompilationUnitDocumentProvider.java:1277) + at org.eclipse.ui.texteditor.AbstractTextEditor.doSetInput(AbstractTextEditor.java:4212) + at org.eclipse.ui.texteditor.StatusTextEditor.doSetInput(StatusTextEditor.java:260) + at org.eclipse.ui.texteditor.AbstractDecoratedTextEditor.doSetInput(AbstractDecoratedTextEditor.java:1478) + at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.internalDoSetInput(JavaEditor.java:2573) + at org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.doSetInput(JavaEditor.java:2546) + at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.doSetInput(CompilationUnitEditor.java:1423) + at org.eclipse.ui.texteditor.AbstractTextEditor.lambda$1(AbstractTextEditor.java:3179) + at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:2313) + at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3196) + at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3221) + at org.eclipse.ui.internal.EditorReference.initialize(EditorReference.java:353) + at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.create(CompatibilityPart.java:340) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:58) + at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:998) + at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:963) + at org.eclipse.e4.core.internal.di.InjectorImpl.internalInject(InjectorImpl.java:139) + at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:408) + at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:331) + at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:202) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.createFromBundle(ReflectionContributionFactory.java:91) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.doCreate(ReflectionContributionFactory.java:60) + at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.create(ReflectionContributionFactory.java:42) + at org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer.createWidget(ContributedPartRenderer.java:132) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:1002) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer.showTab(StackRenderer.java:1293) + at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:105) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:680) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$1.run(PartRenderingEngine.java:547) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:531) + at org.eclipse.e4.ui.workbench.renderers.swt.ElementReferenceRenderer.createWidget(ElementReferenceRenderer.java:73) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:1002) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:662) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveRenderer.processContents(PerspectiveRenderer.java:51) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.showTab(PerspectiveStackRenderer.java:82) + at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.postProcess(LazyStackRenderer.java:105) + at org.eclipse.e4.ui.workbench.renderers.swt.PerspectiveStackRenderer.postProcess(PerspectiveStackRenderer.java:64) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:680) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.SashRenderer.processContents(SashRenderer.java:140) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer.processContents(SWTPartRenderer.java:73) + at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer.processContents(WBWRenderer.java:665) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:676) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:768) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$0(PartRenderingEngine.java:739) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$2.run(PartRenderingEngine.java:733) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:717) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1086) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1049) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) + at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:633) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:557) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:150) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:498) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:660) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:597) + at org.eclipse.equinox.launcher.Main.run(Main.java:1468) +!SUBENTRY 2 org.eclipse.core.filebuffers 4 0 2021-01-03 17:13:19.697 +!MESSAGE Cannot determine URI for '/playing-coffee/src/main/java/playingcoffee/application/Application.java'. + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:13:51.518 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:13:51.526 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! + +!ENTRY org.eclipse.equinox.p2.metadata.repository 4 1000 2021-01-03 17:13:51.818 +!MESSAGE No repository found at jar:file:/E:/pdf/jd-eclipse-2.0.0.zip!/. + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:13:53.704 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:13:53.838 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:14:26.557 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:14:26.560 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:14:30.078 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:14:30.080 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:14:33.474 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! + +!ENTRY org.eclipse.m2e.logback.appender 2 0 2021-01-03 17:14:33.479 +!MESSAGE Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! diff --git a/.metadata/.mylyn/.tasks.xml.zip b/.metadata/.mylyn/.tasks.xml.zip index 9e80e3c..7deadf8 100644 Binary files a/.metadata/.mylyn/.tasks.xml.zip and b/.metadata/.mylyn/.tasks.xml.zip differ diff --git a/.metadata/.mylyn/tasks.xml.zip b/.metadata/.mylyn/tasks.xml.zip index 7deadf8..2cfa591 100644 Binary files a/.metadata/.mylyn/tasks.xml.zip and b/.metadata/.mylyn/tasks.xml.zip differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources index c944a5f..5cdc929 100644 Binary files a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources and b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources differ diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.launchbar.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.launchbar.core.prefs index 44f6751..8d15908 100644 --- a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.launchbar.core.prefs +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.launchbar.core.prefs @@ -1,7 +1,7 @@ LaunchTargetManager/org.eclipse.launchbar.core.launchTargetType.local,Local/arch=x86_64 LaunchTargetManager/org.eclipse.launchbar.core.launchTargetType.local,Local/name=Local LaunchTargetManager/org.eclipse.launchbar.core.launchTargetType.local,Local/os=win32 -configDescList=org.eclipse.launchbar.core.descriptorType.default\:CPUDebugger,org.eclipse.launchbar.core.descriptorType.default\:GameBoyTest,org.eclipse.launchbar.core.descriptorType.default\:Application +configDescList=org.eclipse.launchbar.core.descriptorType.default\:CPUDebugger,org.eclipse.launchbar.core.descriptorType.default\:Application eclipse.preferences.version=1 org.eclipse.launchbar.core.descriptorType.default\:Application/activeLaunchMode=run org.eclipse.launchbar.core.descriptorType.default\:Application/activeLaunchTarget=org.eclipse.launchbar.core.launchTargetType.local\:Local diff --git a/.metadata/.plugins/org.eclipse.debug.core/.launches/CPUDebugger.launch b/.metadata/.plugins/org.eclipse.debug.core/.launches/CPUDebugger.launch index 9a303a3..033586d 100644 --- a/.metadata/.plugins/org.eclipse.debug.core/.launches/CPUDebugger.launch +++ b/.metadata/.plugins/org.eclipse.debug.core/.launches/CPUDebugger.launch @@ -1,14 +1,14 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps b/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps index dee1862..5a4497c 100644 Binary files a/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps and b/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat index 1c10a55..fc9946e 100644 Binary files a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat and b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat differ diff --git a/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log index ae744ae..b13b7e5 100644 --- a/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log +++ b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log @@ -13128,3 +13128,25 @@ 2021-01-01 22:55:38,268 [Worker-195: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource 2021-01-01 22:55:38,271 [Worker-195: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! 2021-01-01 22:55:38,273 [Worker-195: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:13:24,251 [Worker-1: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read. +2021-01-03 17:13:51,134 [Worker-11: Building workspace] INFO o.e.m.c.i.l.LifecycleMappingFactory - Using org.eclipse.m2e.jdt.JarLifecycleMapping lifecycle mapping for MavenProject: sixtenhugosson:playing-coffee:0.0.1-SNAPSHOT @ C:\dev\playing-coffee\playing-coffee\pom.xml. +2021-01-03 17:13:51,517 [Worker-11: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:13:51,523 [Worker-11: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:13:51,526 [Worker-11: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:13:51,527 [Worker-11: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:13:53,704 [Worker-0: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:13:53,835 [Worker-0: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:13:53,837 [Worker-0: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:13:53,855 [Worker-0: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:14:26,557 [Worker-3: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:14:26,558 [Worker-3: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:14:26,559 [Worker-3: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:14:26,560 [Worker-3: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:14:30,077 [Worker-9: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:14:30,078 [Worker-9: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:14:30,079 [Worker-9: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:14:30,080 [Worker-9: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:14:33,474 [Worker-6: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:14:33,475 [Worker-6: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource +2021-01-03 17:14:33,478 [Worker-6: Building workspace] WARN o.e.m.c.i.embedder.EclipseLogger - Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! +2021-01-03 17:14:33,479 [Worker-6: Building workspace] INFO o.e.m.c.i.embedder.EclipseLogger - Copying 0 resource diff --git a/.metadata/version.ini b/.metadata/version.ini index af83e1b..cbcffbc 100644 --- a/.metadata/version.ini +++ b/.metadata/version.ini @@ -1,3 +1,3 @@ -#Sat Jan 02 08:08:01 CET 2021 +#Sun Jan 03 17:13:12 CET 2021 org.eclipse.core.runtime=2 org.eclipse.platform=4.13.0.v20190916-1045 diff --git a/playing-coffee - Copy/.classpath b/playing-coffee - Copy/.classpath deleted file mode 100644 index 271ce0c..0000000 --- a/playing-coffee - Copy/.classpath +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/playing-coffee - Copy/.gitignore b/playing-coffee - Copy/.gitignore deleted file mode 100644 index b83d222..0000000 --- a/playing-coffee - Copy/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/playing-coffee - Copy/.project b/playing-coffee - Copy/.project deleted file mode 100644 index 8e61026..0000000 --- a/playing-coffee - Copy/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - playing-coffee - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/playing-coffee - Copy/.settings/org.eclipse.jdt.core.prefs b/playing-coffee - Copy/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index cac0df4..0000000 --- a/playing-coffee - Copy/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,11 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/playing-coffee - Copy/.settings/org.eclipse.m2e.core.prefs b/playing-coffee - Copy/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/playing-coffee - Copy/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/playing-coffee - Copy/dmg_boot.bin b/playing-coffee - Copy/dmg_boot.bin deleted file mode 100644 index afa0ee4..0000000 Binary files a/playing-coffee - Copy/dmg_boot.bin and /dev/null differ diff --git a/playing-coffee - Copy/gb-test-roms-master.zip b/playing-coffee - Copy/gb-test-roms-master.zip deleted file mode 100644 index b66c88f..0000000 Binary files a/playing-coffee - Copy/gb-test-roms-master.zip and /dev/null differ diff --git a/playing-coffee - Copy/log.txt b/playing-coffee - Copy/log.txt deleted file mode 100644 index 9fd27a9..0000000 --- a/playing-coffee - Copy/log.txt +++ /dev/null @@ -1,646 +0,0 @@ -[19:39:15.741] Info: Initialized logger -[19:39:15.830] Info: Pushing 0x 2b to the stack. -[19:39:15.831] Info: Pushing 0x 4ce to the stack. -[19:39:15.832] Info: Pushing 0x 39d to the stack. -[19:39:15.832] Info: Pushing 0x 23a to the stack. -[19:39:15.832] Info: Pushing 0x 175 to the stack. -[19:39:15.832] Info: Returning from 0x a8 to 0x 2b -[19:39:15.832] Info: Pushing 0x 2e to the stack. -[19:39:15.833] Info: Pushing 0x 4eb to the stack. -[19:39:15.833] Info: Pushing 0x 3d7 to the stack. -[19:39:15.833] Info: Pushing 0x 2af to the stack. -[19:39:15.833] Info: Pushing 0x 15e to the stack. -[19:39:15.833] Info: Returning from 0x a8 to 0x 2e -[19:39:15.834] Info: Pushing 0x 2b to the stack. -[19:39:15.834] Info: Pushing 0x 4ed to the stack. -[19:39:15.834] Info: Pushing 0x 3db to the stack. -[19:39:15.834] Info: Pushing 0x 2b7 to the stack. -[19:39:15.835] Info: Pushing 0x 16f to the stack. -[19:39:15.835] Info: Returning from 0x a8 to 0x 2b -[19:39:15.835] Info: Pushing 0x 2e to the stack. -[19:39:15.835] Info: Pushing 0x 4de to the stack. -[19:39:15.835] Info: Pushing 0x 3bd to the stack. -[19:39:15.835] Info: Pushing 0x 27b to the stack. -[19:39:15.835] Info: Pushing 0x 1f7 to the stack. -[19:39:15.835] Info: Returning from 0x a8 to 0x 2e -[19:39:15.836] Info: Pushing 0x 2b to the stack. -[19:39:15.836] Info: Pushing 0x 466 to the stack. -[19:39:15.836] Info: Pushing 0x 3cc to the stack. -[19:39:15.836] Info: Pushing 0x 299 to the stack. -[19:39:15.836] Info: Pushing 0x 132 to the stack. -[19:39:15.836] Info: Returning from 0x a8 to 0x 2b -[19:39:15.836] Info: Pushing 0x 2e to the stack. -[19:39:15.836] Info: Pushing 0x 465 to the stack. -[19:39:15.836] Info: Pushing 0x 3ca to the stack. -[19:39:15.837] Info: Pushing 0x 295 to the stack. -[19:39:15.837] Info: Pushing 0x 12b to the stack. -[19:39:15.837] Info: Returning from 0x a8 to 0x 2e -[19:39:15.837] Info: Pushing 0x 2b to the stack. -[19:39:15.837] Info: Pushing 0x 466 to the stack. -[19:39:15.837] Info: Pushing 0x 3cc to the stack. -[19:39:15.837] Info: Pushing 0x 299 to the stack. -[19:39:15.837] Info: Pushing 0x 132 to the stack. -[19:39:15.838] Info: Returning from 0x a8 to 0x 2b -[19:39:15.838] Info: Pushing 0x 2e to the stack. -[19:39:15.838] Info: Pushing 0x 465 to the stack. -[19:39:15.838] Info: Pushing 0x 3ca to the stack. -[19:39:15.838] Info: Pushing 0x 295 to the stack. -[19:39:15.838] Info: Pushing 0x 12b to the stack. -[19:39:15.838] Info: Returning from 0x a8 to 0x 2e -[19:39:15.838] Info: Pushing 0x 2b to the stack. -[19:39:15.839] Info: Pushing 0x 4cc to the stack. -[19:39:15.839] Info: Pushing 0x 399 to the stack. -[19:39:15.839] Info: Pushing 0x 232 to the stack. -[19:39:15.839] Info: Pushing 0x 165 to the stack. -[19:39:15.839] Info: Returning from 0x a8 to 0x 2b -[19:39:15.839] Info: Pushing 0x 2e to the stack. -[19:39:15.839] Info: Pushing 0x 4ca to the stack. -[19:39:15.839] Info: Pushing 0x 395 to the stack. -[19:39:15.840] Info: Pushing 0x 22b to the stack. -[19:39:15.840] Info: Pushing 0x 156 to the stack. -[19:39:15.840] Info: Returning from 0x a8 to 0x 2e -[19:39:15.840] Info: Pushing 0x 2b to the stack. -[19:39:15.840] Info: Pushing 0x 40d to the stack. -[19:39:15.840] Info: Pushing 0x 31a to the stack. -[19:39:15.840] Info: Pushing 0x 234 to the stack. -[19:39:15.840] Info: Pushing 0x 169 to the stack. -[19:39:15.841] Info: Returning from 0x a8 to 0x 2b -[19:39:15.841] Info: Pushing 0x 2e to the stack. -[19:39:15.841] Info: Pushing 0x 4d2 to the stack. -[19:39:15.841] Info: Pushing 0x 3a4 to the stack. -[19:39:15.841] Info: Pushing 0x 248 to the stack. -[19:39:15.841] Info: Pushing 0x 190 to the stack. -[19:39:15.841] Info: Returning from 0x a8 to 0x 2e -[19:39:15.841] Info: Pushing 0x 2b to the stack. -[19:39:15.841] Info: Pushing 0x 400 to the stack. -[19:39:15.842] Info: Pushing 0x 300 to the stack. -[19:39:15.842] Info: Pushing 0x 200 to the stack. -[19:39:15.842] Info: Pushing 0x 100 to the stack. -[19:39:15.842] Info: Returning from 0x a8 to 0x 2b -[19:39:15.842] Info: Pushing 0x 2e to the stack. -[19:39:15.842] Info: Pushing 0x 400 to the stack. -[19:39:17.652] Info: Pushing 0x 300 to the stack. -[19:39:17.652] Info: Pushing 0x 200 to the stack. -[19:39:17.652] Info: Pushing 0x 100 to the stack. -[19:39:17.652] Info: Returning from 0x a8 to 0x 2e -[19:39:17.652] Info: Pushing 0x 2b to the stack. -[19:39:17.652] Info: Pushing 0x 40b to the stack. -[19:39:17.652] Info: Pushing 0x 316 to the stack. -[19:39:17.653] Info: Pushing 0x 22c to the stack. -[19:39:17.653] Info: Pushing 0x 159 to the stack. -[19:39:17.653] Info: Returning from 0x a8 to 0x 2b -[19:39:17.653] Info: Pushing 0x 2e to the stack. -[19:39:17.653] Info: Pushing 0x 4b3 to the stack. -[19:39:17.653] Info: Pushing 0x 366 to the stack. -[19:39:17.653] Info: Pushing 0x 2cc to the stack. -[19:39:17.653] Info: Pushing 0x 198 to the stack. -[19:39:17.653] Info: Returning from 0x a8 to 0x 2e -[19:39:17.654] Info: Pushing 0x 2b to the stack. -[19:39:17.654] Info: Pushing 0x 403 to the stack. -[19:39:17.654] Info: Pushing 0x 306 to the stack. -[19:39:17.654] Info: Pushing 0x 20c to the stack. -[19:39:17.654] Info: Pushing 0x 118 to the stack. -[19:39:17.654] Info: Returning from 0x a8 to 0x 2b -[19:39:17.654] Info: Pushing 0x 2e to the stack. -[19:39:17.654] Info: Pushing 0x 431 to the stack. -[19:39:17.655] Info: Pushing 0x 362 to the stack. -[19:39:17.655] Info: Pushing 0x 2c4 to the stack. -[19:39:17.655] Info: Pushing 0x 188 to the stack. -[19:39:17.655] Info: Returning from 0x a8 to 0x 2e -[19:39:17.655] Info: Pushing 0x 2b to the stack. -[19:39:17.655] Info: Pushing 0x 473 to the stack. -[19:39:17.655] Info: Pushing 0x 3e6 to the stack. -[19:39:17.655] Info: Pushing 0x 2cd to the stack. -[19:39:17.655] Info: Pushing 0x 19a to the stack. -[19:39:17.655] Info: Returning from 0x a8 to 0x 2b -[19:39:17.655] Info: Pushing 0x 2e to the stack. -[19:39:17.656] Info: Pushing 0x 435 to the stack. -[19:39:17.656] Info: Pushing 0x 36a to the stack. -[19:39:17.656] Info: Pushing 0x 2d5 to the stack. -[19:39:17.656] Info: Pushing 0x 1ab to the stack. -[19:39:17.656] Info: Returning from 0x a8 to 0x 2e -[19:39:17.656] Info: Pushing 0x 2b to the stack. -[19:39:17.656] Info: Pushing 0x 400 to the stack. -[19:39:17.657] Info: Pushing 0x 300 to the stack. -[19:39:17.657] Info: Pushing 0x 200 to the stack. -[19:39:17.657] Info: Pushing 0x 100 to the stack. -[19:39:17.657] Info: Returning from 0x a8 to 0x 2b -[19:39:17.658] Info: Pushing 0x 2e to the stack. -[19:39:17.658] Info: Pushing 0x 400 to the stack. -[19:39:17.658] Info: Pushing 0x 300 to the stack. -[19:39:17.658] Info: Pushing 0x 200 to the stack. -[19:39:17.658] Info: Pushing 0x 100 to the stack. -[19:39:17.658] Info: Returning from 0x a8 to 0x 2e -[19:39:17.658] Info: Pushing 0x 2b to the stack. -[19:39:17.658] Info: Pushing 0x 483 to the stack. -[19:39:17.658] Info: Pushing 0x 307 to the stack. -[19:39:17.658] Info: Pushing 0x 20e to the stack. -[19:39:17.660] Info: Pushing 0x 11c to the stack. -[19:39:17.660] Info: Returning from 0x a8 to 0x 2b -[19:39:17.660] Info: Pushing 0x 2e to the stack. -[19:39:17.660] Info: Pushing 0x 439 to the stack. -[19:39:17.667] Info: Pushing 0x 373 to the stack. -[19:39:17.668] Info: Pushing 0x 2e6 to the stack. -[19:39:17.668] Info: Pushing 0x 1cc to the stack. -[19:39:17.668] Info: Returning from 0x a8 to 0x 2e -[19:39:17.668] Info: Pushing 0x 2b to the stack. -[19:39:17.668] Info: Pushing 0x 400 to the stack. -[19:39:17.668] Info: Pushing 0x 300 to the stack. -[19:39:17.668] Info: Pushing 0x 200 to the stack. -[19:39:17.668] Info: Pushing 0x 100 to the stack. -[19:39:17.668] Info: Returning from 0x a8 to 0x 2b -[19:39:17.668] Info: Pushing 0x 2e to the stack. -[19:39:17.668] Info: Pushing 0x 400 to the stack. -[19:39:17.669] Info: Pushing 0x 300 to the stack. -[19:39:17.669] Info: Pushing 0x 200 to the stack. -[19:39:17.669] Info: Pushing 0x 100 to the stack. -[19:39:17.669] Info: Returning from 0x a8 to 0x 2e -[19:39:17.669] Info: Pushing 0x 2b to the stack. -[19:39:17.669] Info: Pushing 0x 40c to the stack. -[19:39:17.669] Info: Pushing 0x 318 to the stack. -[19:39:17.669] Info: Pushing 0x 230 to the stack. -[19:39:17.669] Info: Pushing 0x 161 to the stack. -[19:39:17.669] Info: Returning from 0x a8 to 0x 2b -[19:39:17.670] Info: Pushing 0x 2e to the stack. -[19:39:17.670] Info: Pushing 0x 4c2 to the stack. -[19:39:17.670] Info: Pushing 0x 384 to the stack. -[19:39:17.670] Info: Pushing 0x 208 to the stack. -[19:39:17.670] Info: Pushing 0x 110 to the stack. -[19:39:17.670] Info: Returning from 0x a8 to 0x 2e -[19:39:17.670] Info: Pushing 0x 2b to the stack. -[19:39:17.670] Info: Pushing 0x 400 to the stack. -[19:39:17.670] Info: Pushing 0x 300 to the stack. -[19:39:17.670] Info: Pushing 0x 200 to the stack. -[19:39:17.670] Info: Pushing 0x 100 to the stack. -[19:39:17.671] Info: Returning from 0x a8 to 0x 2b -[19:39:17.671] Info: Pushing 0x 2e to the stack. -[19:39:17.671] Info: Pushing 0x 400 to the stack. -[19:39:17.671] Info: Pushing 0x 300 to the stack. -[19:39:17.671] Info: Pushing 0x 200 to the stack. -[19:39:17.671] Info: Pushing 0x 100 to the stack. -[19:39:17.671] Info: Returning from 0x a8 to 0x 2e -[19:39:17.671] Info: Pushing 0x 2b to the stack. -[19:39:17.671] Info: Pushing 0x 40d to the stack. -[19:39:17.671] Info: Pushing 0x 31a to the stack. -[19:39:17.671] Info: Pushing 0x 234 to the stack. -[19:39:17.671] Info: Pushing 0x 169 to the stack. -[19:39:17.671] Info: Returning from 0x a8 to 0x 2b -[19:39:17.671] Info: Pushing 0x 2e to the stack. -[19:39:17.672] Info: Pushing 0x 4d2 to the stack. -[19:39:17.672] Info: Pushing 0x 3a4 to the stack. -[19:39:17.672] Info: Pushing 0x 248 to the stack. -[19:39:17.672] Info: Pushing 0x 190 to the stack. -[19:39:17.672] Info: Returning from 0x a8 to 0x 2e -[19:39:17.672] Info: Pushing 0x 2b to the stack. -[19:39:17.672] Info: Pushing 0x 400 to the stack. -[19:39:17.672] Info: Pushing 0x 300 to the stack. -[19:39:17.672] Info: Pushing 0x 200 to the stack. -[19:39:17.672] Info: Pushing 0x 100 to the stack. -[19:39:17.672] Info: Returning from 0x a8 to 0x 2b -[19:39:17.672] Info: Pushing 0x 2e to the stack. -[19:39:17.673] Info: Pushing 0x 400 to the stack. -[19:39:17.673] Info: Pushing 0x 300 to the stack. -[19:39:17.673] Info: Pushing 0x 200 to the stack. -[19:39:17.673] Info: Pushing 0x 100 to the stack. -[19:39:17.673] Info: Returning from 0x a8 to 0x 2e -[19:39:17.673] Info: Pushing 0x 2b to the stack. -[19:39:17.673] Info: Pushing 0x 408 to the stack. -[19:39:17.673] Info: Pushing 0x 310 to the stack. -[19:39:17.673] Info: Pushing 0x 220 to the stack. -[19:39:17.673] Info: Pushing 0x 141 to the stack. -[19:39:17.673] Info: Returning from 0x a8 to 0x 2b -[19:39:17.673] Info: Pushing 0x 2e to the stack. -[19:39:17.673] Info: Pushing 0x 482 to the stack. -[19:39:17.673] Info: Pushing 0x 304 to the stack. -[19:39:17.674] Info: Pushing 0x 208 to the stack. -[19:39:17.674] Info: Pushing 0x 110 to the stack. -[19:39:17.674] Info: Returning from 0x a8 to 0x 2e -[19:39:17.674] Info: Pushing 0x 2b to the stack. -[19:39:17.674] Info: Pushing 0x 411 to the stack. -[19:39:17.674] Info: Pushing 0x 322 to the stack. -[19:39:17.674] Info: Pushing 0x 244 to the stack. -[19:39:17.674] Info: Pushing 0x 188 to the stack. -[19:39:17.674] Info: Returning from 0x a8 to 0x 2b -[19:39:17.674] Info: Pushing 0x 2e to the stack. -[19:39:17.674] Info: Pushing 0x 410 to the stack. -[19:39:17.675] Info: Pushing 0x 320 to the stack. -[19:39:17.675] Info: Pushing 0x 240 to the stack. -[19:39:17.675] Info: Pushing 0x 180 to the stack. -[19:39:17.675] Info: Returning from 0x a8 to 0x 2e -[19:39:17.675] Info: Pushing 0x 2b to the stack. -[19:39:17.675] Info: Pushing 0x 41f to the stack. -[19:39:17.675] Info: Pushing 0x 33e to the stack. -[19:39:17.675] Info: Pushing 0x 27c to the stack. -[19:39:17.675] Info: Pushing 0x 1f9 to the stack. -[19:39:17.675] Info: Returning from 0x a8 to 0x 2b -[19:39:17.675] Info: Pushing 0x 2e to the stack. -[19:39:17.675] Info: Pushing 0x 4f3 to the stack. -[19:39:17.675] Info: Pushing 0x 3e6 to the stack. -[19:39:17.676] Info: Pushing 0x 2cc to the stack. -[19:39:17.676] Info: Pushing 0x 198 to the stack. -[19:39:17.676] Info: Returning from 0x a8 to 0x 2e -[19:39:17.676] Info: Pushing 0x 2b to the stack. -[19:39:17.676] Info: Pushing 0x 488 to the stack. -[19:39:17.676] Info: Pushing 0x 311 to the stack. -[19:39:17.676] Info: Pushing 0x 222 to the stack. -[19:39:17.676] Info: Pushing 0x 145 to the stack. -[19:39:17.676] Info: Returning from 0x a8 to 0x 2b -[19:39:17.676] Info: Pushing 0x 2e to the stack. -[19:39:17.676] Info: Pushing 0x 48a to the stack. -[19:39:17.676] Info: Pushing 0x 315 to the stack. -[19:39:17.676] Info: Pushing 0x 22a to the stack. -[19:39:17.677] Info: Pushing 0x 154 to the stack. -[19:39:17.677] Info: Returning from 0x a8 to 0x 2e -[19:39:17.677] Info: Pushing 0x 2b to the stack. -[19:39:17.677] Info: Pushing 0x 489 to the stack. -[19:39:17.677] Info: Pushing 0x 313 to the stack. -[19:39:17.677] Info: Pushing 0x 226 to the stack. -[19:39:17.677] Info: Pushing 0x 14d to the stack. -[19:39:17.677] Info: Returning from 0x a8 to 0x 2b -[19:39:17.677] Info: Pushing 0x 2e to the stack. -[19:39:17.677] Info: Pushing 0x 49a to the stack. -[19:39:17.678] Info: Pushing 0x 335 to the stack. -[19:39:17.678] Info: Pushing 0x 26a to the stack. -[19:39:17.678] Info: Pushing 0x 1d4 to the stack. -[19:39:17.678] Info: Returning from 0x a8 to 0x 2e -[19:39:17.678] Info: Pushing 0x 2b to the stack. -[19:39:17.678] Info: Pushing 0x 400 to the stack. -[19:39:17.678] Info: Pushing 0x 300 to the stack. -[19:39:17.678] Info: Pushing 0x 200 to the stack. -[19:39:17.678] Info: Pushing 0x 100 to the stack. -[19:39:17.678] Info: Returning from 0x a8 to 0x 2b -[19:39:17.678] Info: Pushing 0x 2e to the stack. -[19:39:17.678] Info: Pushing 0x 400 to the stack. -[19:39:17.678] Info: Pushing 0x 300 to the stack. -[19:39:17.678] Info: Pushing 0x 200 to the stack. -[19:39:17.680] Info: Pushing 0x 100 to the stack. -[19:39:17.680] Info: Returning from 0x a8 to 0x 2e -[19:39:17.680] Info: Pushing 0x 2b to the stack. -[19:39:17.680] Info: Pushing 0x 40e to the stack. -[19:39:17.680] Info: Pushing 0x 31c to the stack. -[19:39:17.680] Info: Pushing 0x 238 to the stack. -[19:39:17.680] Info: Pushing 0x 171 to the stack. -[19:39:17.680] Info: Returning from 0x a8 to 0x 2b -[19:39:17.680] Info: Pushing 0x 2e to the stack. -[19:39:17.681] Info: Pushing 0x 4e3 to the stack. -[19:39:17.681] Info: Pushing 0x 3c6 to the stack. -[19:39:17.681] Info: Pushing 0x 28c to the stack. -[19:39:17.681] Info: Pushing 0x 118 to the stack. -[19:39:17.681] Info: Returning from 0x a8 to 0x 2e -[19:39:17.681] Info: Pushing 0x 2b to the stack. -[19:39:17.681] Info: Pushing 0x 4dc to the stack. -[19:39:17.681] Info: Pushing 0x 3b9 to the stack. -[19:39:17.681] Info: Pushing 0x 272 to the stack. -[19:39:17.682] Info: Pushing 0x 1e5 to the stack. -[19:39:17.682] Info: Returning from 0x a8 to 0x 2b -[19:39:17.682] Info: Pushing 0x 2e to the stack. -[19:39:17.682] Info: Pushing 0x 4ca to the stack. -[19:39:17.682] Info: Pushing 0x 395 to the stack. -[19:39:17.682] Info: Pushing 0x 22b to the stack. -[19:39:17.682] Info: Pushing 0x 156 to the stack. -[19:39:17.682] Info: Returning from 0x a8 to 0x 2e -[19:39:17.682] Info: Pushing 0x 2b to the stack. -[19:39:17.682] Info: Pushing 0x 4cc to the stack. -[19:39:17.682] Info: Pushing 0x 399 to the stack. -[19:39:17.682] Info: Pushing 0x 232 to the stack. -[19:39:17.682] Info: Pushing 0x 165 to the stack. -[19:39:17.683] Info: Returning from 0x a8 to 0x 2b -[19:39:17.683] Info: Pushing 0x 2e to the stack. -[19:39:17.683] Info: Pushing 0x 4ca to the stack. -[19:39:17.683] Info: Pushing 0x 395 to the stack. -[19:39:17.683] Info: Pushing 0x 22b to the stack. -[19:39:17.683] Info: Pushing 0x 156 to the stack. -[19:39:17.683] Info: Returning from 0x a8 to 0x 2e -[19:39:17.683] Info: Pushing 0x 2b to the stack. -[19:39:17.683] Info: Pushing 0x 46e to the stack. -[19:39:17.683] Info: Pushing 0x 3dc to the stack. -[19:39:17.683] Info: Pushing 0x 2b9 to the stack. -[19:39:17.683] Info: Pushing 0x 173 to the stack. -[19:39:17.683] Info: Returning from 0x a8 to 0x 2b -[19:39:17.683] Info: Pushing 0x 2e to the stack. -[19:39:17.684] Info: Pushing 0x 4e7 to the stack. -[19:39:17.684] Info: Pushing 0x 3ce to the stack. -[19:39:17.684] Info: Pushing 0x 29d to the stack. -[19:39:17.684] Info: Pushing 0x 13b to the stack. -[19:39:17.684] Info: Returning from 0x a8 to 0x 2e -[19:39:17.684] Info: Pushing 0x 2b to the stack. -[19:39:17.684] Info: Pushing 0x 4e6 to the stack. -[19:39:17.684] Info: Pushing 0x 3cd to the stack. -[19:39:17.684] Info: Pushing 0x 29b to the stack. -[19:39:17.684] Info: Pushing 0x 136 to the stack. -[19:39:17.684] Info: Returning from 0x a8 to 0x 2b -[19:39:17.684] Info: Pushing 0x 2e to the stack. -[19:39:17.684] Info: Pushing 0x 46d to the stack. -[19:39:17.684] Info: Pushing 0x 3db to the stack. -[19:39:17.685] Info: Pushing 0x 2b7 to the stack. -[19:39:17.685] Info: Pushing 0x 16f to the stack. -[19:39:17.685] Info: Returning from 0x a8 to 0x 2e -[19:39:17.685] Info: Pushing 0x 2b to the stack. -[19:39:17.685] Info: Pushing 0x 4dd to the stack. -[19:39:17.685] Info: Pushing 0x 3bb to the stack. -[19:39:17.685] Info: Pushing 0x 276 to the stack. -[19:39:17.685] Info: Pushing 0x 1ed to the stack. -[19:39:17.686] Info: Returning from 0x a8 to 0x 2b -[19:39:17.686] Info: Pushing 0x 2e to the stack. -[19:39:17.686] Info: Pushing 0x 4da to the stack. -[19:39:17.686] Info: Pushing 0x 3b5 to the stack. -[19:39:17.686] Info: Pushing 0x 26b to the stack. -[19:39:17.686] Info: Pushing 0x 1d6 to the stack. -[19:39:17.686] Info: Returning from 0x a8 to 0x 2e -[19:39:17.686] Info: Pushing 0x 2b to the stack. -[19:39:17.686] Info: Pushing 0x 4dd to the stack. -[19:39:17.686] Info: Pushing 0x 3bb to the stack. -[19:39:17.686] Info: Pushing 0x 276 to the stack. -[19:39:17.686] Info: Pushing 0x 1ed to the stack. -[19:39:17.686] Info: Returning from 0x a8 to 0x 2b -[19:39:17.686] Info: Pushing 0x 2e to the stack. -[19:39:17.688] Info: Pushing 0x 4da to the stack. -[19:39:17.688] Info: Pushing 0x 3b5 to the stack. -[19:39:17.688] Info: Pushing 0x 26b to the stack. -[19:39:17.688] Info: Pushing 0x 1d6 to the stack. -[19:39:17.689] Info: Returning from 0x a8 to 0x 2e -[19:39:17.689] Info: Pushing 0x 2b to the stack. -[19:39:17.689] Info: Pushing 0x 4d9 to the stack. -[19:39:17.689] Info: Pushing 0x 3b3 to the stack. -[19:39:17.689] Info: Pushing 0x 266 to the stack. -[19:39:17.689] Info: Pushing 0x 1cd to the stack. -[19:39:17.689] Info: Returning from 0x a8 to 0x 2b -[19:39:17.689] Info: Pushing 0x 2e to the stack. -[19:39:17.689] Info: Pushing 0x 49a to the stack. -[19:39:17.689] Info: Pushing 0x 335 to the stack. -[19:39:17.689] Info: Pushing 0x 26b to the stack. -[19:39:17.689] Info: Pushing 0x 1d6 to the stack. -[19:39:17.689] Info: Returning from 0x a8 to 0x 2e -[19:39:17.689] Info: Pushing 0x 2b to the stack. -[19:39:17.689] Info: Pushing 0x 499 to the stack. -[19:39:17.689] Info: Pushing 0x 333 to the stack. -[19:39:17.689] Info: Pushing 0x 266 to the stack. -[19:39:17.690] Info: Pushing 0x 1cd to the stack. -[19:39:17.690] Info: Returning from 0x a8 to 0x 2b -[19:39:17.690] Info: Pushing 0x 2e to the stack. -[19:39:17.690] Info: Pushing 0x 49a to the stack. -[19:39:17.690] Info: Pushing 0x 335 to the stack. -[19:39:17.690] Info: Pushing 0x 26a to the stack. -[19:39:17.690] Info: Pushing 0x 1d4 to the stack. -[19:39:17.690] Info: Returning from 0x a8 to 0x 2e -[19:39:17.690] Info: Pushing 0x 2b to the stack. -[19:39:17.690] Info: Pushing 0x 4bb to the stack. -[19:39:17.690] Info: Pushing 0x 377 to the stack. -[19:39:17.690] Info: Pushing 0x 2ef to the stack. -[19:39:17.690] Info: Pushing 0x 1df to the stack. -[19:39:17.690] Info: Returning from 0x a8 to 0x 2b -[19:39:17.690] Info: Pushing 0x 2e to the stack. -[19:39:17.690] Info: Pushing 0x 4bf to the stack. -[19:39:17.691] Info: Pushing 0x 37f to the stack. -[19:39:17.691] Info: Pushing 0x 2fe to the stack. -[19:39:17.691] Info: Pushing 0x 1fd to the stack. -[19:39:17.691] Info: Returning from 0x a8 to 0x 2e -[19:39:17.691] Info: Pushing 0x 2b to the stack. -[19:39:17.691] Info: Pushing 0x 4bb to the stack. -[19:39:17.691] Info: Pushing 0x 377 to the stack. -[19:39:17.691] Info: Pushing 0x 2ef to the stack. -[19:39:17.691] Info: Pushing 0x 1df to the stack. -[19:39:17.691] Info: Returning from 0x a8 to 0x 2b -[19:39:17.691] Info: Pushing 0x 2e to the stack. -[19:39:17.691] Info: Pushing 0x 4bf to the stack. -[19:39:17.691] Info: Pushing 0x 37f to the stack. -[19:39:17.691] Info: Pushing 0x 2fe to the stack. -[19:39:17.691] Info: Pushing 0x 1fd to the stack. -[19:39:17.691] Info: Returning from 0x a8 to 0x 2e -[19:39:17.691] Info: Pushing 0x 2b to the stack. -[19:39:17.691] Info: Pushing 0x 467 to the stack. -[19:39:17.692] Info: Pushing 0x 3ce to the stack. -[19:39:17.692] Info: Pushing 0x 29d to the stack. -[19:39:17.694] Info: Pushing 0x 13a to the stack. -[19:39:17.694] Info: Returning from 0x a8 to 0x 2b -[19:39:17.694] Info: Pushing 0x 2e to the stack. -[19:39:17.694] Info: Pushing 0x 475 to the stack. -[19:39:17.694] Info: Pushing 0x 3ea to the stack. -[19:39:17.694] Info: Pushing 0x 2d5 to the stack. -[19:39:17.694] Info: Pushing 0x 1ab to the stack. -[19:39:17.694] Info: Returning from 0x a8 to 0x 2e -[19:39:17.694] Info: Pushing 0x 2b to the stack. -[19:39:17.694] Info: Pushing 0x 463 to the stack. -[19:39:17.694] Info: Pushing 0x 3c6 to the stack. -[19:39:17.694] Info: Pushing 0x 28d to the stack. -[19:39:17.694] Info: Pushing 0x 11a to the stack. -[19:39:17.694] Info: Returning from 0x a8 to 0x 2b -[19:39:17.694] Info: Pushing 0x 2e to the stack. -[19:39:17.694] Info: Pushing 0x 435 to the stack. -[19:39:17.694] Info: Pushing 0x 36a to the stack. -[19:39:17.694] Info: Pushing 0x 2d5 to the stack. -[19:39:17.695] Info: Pushing 0x 1ab to the stack. -[19:39:17.695] Info: Returning from 0x a8 to 0x 2e -[19:39:17.695] Info: Pushing 0x 2b to the stack. -[19:39:17.695] Info: Pushing 0x 46e to the stack. -[19:39:17.695] Info: Pushing 0x 3dc to the stack. -[19:39:17.695] Info: Pushing 0x 2b9 to the stack. -[19:39:17.695] Info: Pushing 0x 173 to the stack. -[19:39:17.695] Info: Returning from 0x a8 to 0x 2b -[19:39:17.695] Info: Pushing 0x 2e to the stack. -[19:39:17.695] Info: Pushing 0x 4e7 to the stack. -[19:39:17.695] Info: Pushing 0x 3ce to the stack. -[19:39:17.695] Info: Pushing 0x 29d to the stack. -[19:39:17.695] Info: Pushing 0x 13b to the stack. -[19:39:17.695] Info: Returning from 0x a8 to 0x 2e -[19:39:17.696] Info: Pushing 0x 2b to the stack. -[19:39:17.696] Info: Pushing 0x 40e to the stack. -[19:39:17.696] Info: Pushing 0x 31c to the stack. -[19:39:17.696] Info: Pushing 0x 238 to the stack. -[19:39:17.696] Info: Pushing 0x 171 to the stack. -[19:39:17.696] Info: Returning from 0x a8 to 0x 2b -[19:39:17.696] Info: Pushing 0x 2e to the stack. -[19:39:17.696] Info: Pushing 0x 4e3 to the stack. -[19:39:17.696] Info: Pushing 0x 3c6 to the stack. -[19:39:17.696] Info: Pushing 0x 28c to the stack. -[19:39:17.696] Info: Pushing 0x 118 to the stack. -[19:39:17.696] Info: Returning from 0x a8 to 0x 2e -[19:39:17.696] Info: Pushing 0x 2b to the stack. -[19:39:17.696] Info: Pushing 0x 4ec to the stack. -[19:39:17.696] Info: Pushing 0x 3d9 to the stack. -[19:39:17.696] Info: Pushing 0x 2b3 to the stack. -[19:39:17.696] Info: Pushing 0x 167 to the stack. -[19:39:17.696] Info: Returning from 0x a8 to 0x 2b -[19:39:17.696] Info: Pushing 0x 2e to the stack. -[19:39:17.696] Info: Pushing 0x 4ce to the stack. -[19:39:17.697] Info: Pushing 0x 39d to the stack. -[19:39:17.697] Info: Pushing 0x 23b to the stack. -[19:39:17.697] Info: Pushing 0x 177 to the stack. -[19:39:17.697] Info: Returning from 0x a8 to 0x 2e -[19:39:17.697] Info: Pushing 0x 2b to the stack. -[19:39:17.698] Info: Pushing 0x 4cc to the stack. -[19:39:17.698] Info: Pushing 0x 399 to the stack. -[19:39:17.698] Info: Pushing 0x 232 to the stack. -[19:39:17.698] Info: Pushing 0x 165 to the stack. -[19:39:17.698] Info: Returning from 0x a8 to 0x 2b -[19:39:17.698] Info: Pushing 0x 2e to the stack. -[19:39:17.698] Info: Pushing 0x 4ca to the stack. -[19:39:17.698] Info: Pushing 0x 395 to the stack. -[19:39:17.698] Info: Pushing 0x 22b to the stack. -[19:39:17.698] Info: Pushing 0x 156 to the stack. -[19:39:17.699] Info: Returning from 0x a8 to 0x 2e -[19:39:17.699] Info: Pushing 0x 2b to the stack. -[19:39:17.699] Info: Pushing 0x 4dd to the stack. -[19:39:17.699] Info: Pushing 0x 3bb to the stack. -[19:39:17.699] Info: Pushing 0x 276 to the stack. -[19:39:17.699] Info: Pushing 0x 1ed to the stack. -[19:39:17.699] Info: Returning from 0x a8 to 0x 2b -[19:39:17.699] Info: Pushing 0x 2e to the stack. -[19:39:17.699] Info: Pushing 0x 4da to the stack. -[19:39:17.699] Info: Pushing 0x 3b5 to the stack. -[19:39:17.699] Info: Pushing 0x 26b to the stack. -[19:39:17.699] Info: Pushing 0x 1d6 to the stack. -[19:39:17.699] Info: Returning from 0x a8 to 0x 2e -[19:39:17.699] Info: Pushing 0x 2b to the stack. -[19:39:17.699] Info: Pushing 0x 4dc to the stack. -[19:39:17.699] Info: Pushing 0x 3b9 to the stack. -[19:39:17.699] Info: Pushing 0x 272 to the stack. -[19:39:17.700] Info: Pushing 0x 1e5 to the stack. -[19:39:17.700] Info: Returning from 0x a8 to 0x 2b -[19:39:17.700] Info: Pushing 0x 2e to the stack. -[19:39:17.700] Info: Pushing 0x 4ca to the stack. -[19:39:17.700] Info: Pushing 0x 395 to the stack. -[19:39:17.700] Info: Pushing 0x 22b to the stack. -[19:39:17.700] Info: Pushing 0x 156 to the stack. -[19:39:17.700] Info: Returning from 0x a8 to 0x 2e -[19:39:17.700] Info: Pushing 0x 2b to the stack. -[19:39:17.700] Info: Pushing 0x 499 to the stack. -[19:39:17.700] Info: Pushing 0x 333 to the stack. -[19:39:17.700] Info: Pushing 0x 266 to the stack. -[19:39:17.700] Info: Pushing 0x 1cd to the stack. -[19:39:17.700] Info: Returning from 0x a8 to 0x 2b -[19:39:17.700] Info: Pushing 0x 2e to the stack. -[19:39:17.700] Info: Pushing 0x 49a to the stack. -[19:39:17.700] Info: Pushing 0x 335 to the stack. -[19:39:17.700] Info: Pushing 0x 26a to the stack. -[19:39:17.701] Info: Pushing 0x 1d4 to the stack. -[19:39:17.701] Info: Returning from 0x a8 to 0x 2e -[19:39:17.702] Info: Pushing 0x 2b to the stack. -[19:39:17.702] Info: Pushing 0x 49f to the stack. -[19:39:17.702] Info: Pushing 0x 33f to the stack. -[19:39:17.702] Info: Pushing 0x 27e to the stack. -[19:39:17.702] Info: Pushing 0x 1fd to the stack. -[19:39:17.702] Info: Returning from 0x a8 to 0x 2b -[19:39:17.702] Info: Pushing 0x 2e to the stack. -[19:39:17.702] Info: Pushing 0x 4fb to the stack. -[19:39:17.702] Info: Pushing 0x 3f7 to the stack. -[19:39:17.702] Info: Pushing 0x 2ee to the stack. -[19:39:17.702] Info: Pushing 0x 1dc to the stack. -[19:39:17.702] Info: Returning from 0x a8 to 0x 2e -[19:39:17.702] Info: Pushing 0x 2b to the stack. -[19:39:17.702] Info: Pushing 0x 4bb to the stack. -[19:39:17.702] Info: Pushing 0x 377 to the stack. -[19:39:17.702] Info: Pushing 0x 2ef to the stack. -[19:39:17.703] Info: Pushing 0x 1df to the stack. -[19:39:17.703] Info: Returning from 0x a8 to 0x 2b -[19:39:17.703] Info: Pushing 0x 2e to the stack. -[19:39:17.703] Info: Pushing 0x 4bf to the stack. -[19:39:17.703] Info: Pushing 0x 37f to the stack. -[19:39:17.703] Info: Pushing 0x 2fe to the stack. -[19:39:17.703] Info: Pushing 0x 1fd to the stack. -[19:39:17.703] Info: Returning from 0x a8 to 0x 2e -[19:39:17.703] Info: Pushing 0x 2b to the stack. -[19:39:17.703] Info: Pushing 0x 4b9 to the stack. -[19:39:17.703] Info: Pushing 0x 373 to the stack. -[19:39:17.703] Info: Pushing 0x 2e7 to the stack. -[19:39:17.703] Info: Pushing 0x 1cf to the stack. -[19:39:17.703] Info: Returning from 0x a8 to 0x 2b -[19:39:17.703] Info: Pushing 0x 2e to the stack. -[19:39:17.703] Info: Pushing 0x 49e to the stack. -[19:39:17.703] Info: Pushing 0x 33d to the stack. -[19:39:17.703] Info: Pushing 0x 27a to the stack. -[19:39:17.705] Info: Pushing 0x 1f5 to the stack. -[19:39:17.705] Info: Returning from 0x a8 to 0x 2e -[19:39:17.705] Info: Pushing 0x 2b to the stack. -[19:39:17.705] Info: Pushing 0x 433 to the stack. -[19:39:17.705] Info: Pushing 0x 366 to the stack. -[19:39:17.705] Info: Pushing 0x 2cd to the stack. -[19:39:17.705] Info: Pushing 0x 19a to the stack. -[19:39:17.705] Info: Returning from 0x a8 to 0x 2b -[19:39:17.705] Info: Pushing 0x 2e to the stack. -[19:39:17.705] Info: Pushing 0x 435 to the stack. -[19:39:17.705] Info: Pushing 0x 36a to the stack. -[19:39:17.705] Info: Pushing 0x 2d4 to the stack. -[19:39:17.705] Info: Pushing 0x 1a9 to the stack. -[19:39:17.705] Info: Returning from 0x a8 to 0x 2e -[19:39:17.705] Info: Pushing 0x 2b to the stack. -[19:39:17.705] Info: Pushing 0x 43e to the stack. -[19:39:17.705] Info: Pushing 0x 37c to the stack. -[19:39:17.705] Info: Pushing 0x 2f9 to the stack. -[19:39:17.705] Info: Pushing 0x 1f3 to the stack. -[19:39:17.705] Info: Returning from 0x a8 to 0x 2b -[19:39:17.705] Info: Pushing 0x 2e to the stack. -[19:39:17.705] Info: Pushing 0x 4e7 to the stack. -[19:39:17.706] Info: Pushing 0x 3ce to the stack. -[19:39:17.706] Info: Pushing 0x 29c to the stack. -[19:39:17.706] Info: Pushing 0x 139 to the stack. -[19:39:17.706] Info: Returning from 0x a8 to 0x 2e -[19:39:22.038] Info: Pushing 0x 153 to the stack. -[19:39:22.042] Info: Returning from 0x2c20 to 0x 153 -[19:39:22.042] Info: Pushing 0x 159 to the stack. -[19:39:22.042] Info: Returning from 0x2b94 to 0x 159 -[19:39:22.042] Info: Pushing 0x 15e to the stack. -[19:39:22.056] Info: Returning from 0x2c47 to 0x 15e -[19:39:22.136] Info: Pushing 0x 19a to the stack. -[19:39:22.136] Info: Returning from 0x71de to 0x 19a -[19:39:22.136] Info: Pushing 0x 1c5 to the stack. -[19:39:22.136] Info: Pushing 0x1f8c to the stack. -[19:39:22.136] Info: Pushing 0x 80 to the stack. -[19:39:22.136] Info: Pushing 0x ff to the stack. -[19:39:22.136] Info: Pushing 0xf810 to the stack. -[19:39:22.136] Info: Pushing 0xc000 to the stack. -[19:39:22.139] Info: Returning from 0x2c38 to 0x1f8c -[19:39:22.139] Info: Returning from 0x1f8d to 0x 1c5 -[19:39:22.139] Info: Pushing 0x 1c8 to the stack. -[19:39:22.139] Info: Pushing 0x 203 to the stack. -[19:39:22.139] Info: Pushing 0x 80 to the stack. -[19:39:22.139] Info: Pushing 0x 168 to the stack. -[19:39:22.139] Info: Pushing 0xf810 to the stack. -[19:39:22.140] Info: Pushing 0xc100 to the stack. -[19:39:22.144] Info: Returning from 0x2c38 to 0x 203 -[19:39:22.144] Info: Pushing 0x 206 to the stack. -[19:39:22.144] Info: Pushing 0x 168 to the stack. -[19:39:22.144] Info: Pushing 0x1b92 to the stack. -[19:39:22.144] Info: Pushing 0x 168 to the stack. -[19:39:22.144] Info: Pushing 0xf810 to the stack. -[19:39:22.144] Info: Pushing 0xc100 to the stack. -[19:39:22.144] Info: Pushing 0x 0 to the stack. -[19:39:22.144] Info: Pushing 0x3eff to the stack. -[19:39:22.144] Info: Returning from 0x27bd to 0x1b92 -[19:39:22.144] Info: Pushing 0xffa0 to the stack. -[19:39:22.144] Info: Pushing 0x1b96 to the stack. -[19:39:22.144] Info: Pushing 0xc100 to the stack. -[19:39:22.144] Info: Pushing 0x 168 to the stack. -[19:39:22.144] Info: Pushing 0x1bae to the stack. -[19:39:22.144] Info: Pushing 0x 168 to the stack. -[19:39:22.144] Info: Pushing 0xf810 to the stack. -[19:39:22.145] Info: Returning from 0x1f4d to 0x1bae -[19:39:22.145] Info: Returning from 0x1bc4 to 0x1b96 -[19:39:22.145] Info: Pushing 0x1b99 to the stack. -[19:39:22.145] Info: Returning from 0x1f7f to 0x1b99 -[19:39:22.145] Warning: Attempting to write to ROM at address: 0x 0. -[19:39:22.145] Info: Pushing 0x 167 to the stack. -[19:39:22.145] Info: Pushing 0x1b92 to the stack. -[19:39:22.145] Info: Pushing 0x 167 to the stack. -[19:39:22.145] Info: Pushing 0x 0 to the stack. -[19:39:22.145] Info: Pushing 0xc101 to the stack. -[19:39:22.145] Info: Pushing 0x f to the stack. -[19:39:22.145] Info: Pushing 0x3eff to the stack. -[19:39:22.145] Info: Returning from 0x27bd to 0x1b92 -[19:39:22.145] Info: Pushing 0xffa0 to the stack. -[19:39:22.145] Info: Pushing 0x1b96 to the stack. -[19:39:22.145] Info: Pushing 0xc101 to the stack. -[19:39:22.145] Info: Pushing 0x 167 to the stack. -[19:39:22.145] Info: Pushing 0x1bae to the stack. -[19:39:22.145] Info: Pushing 0x 167 to the stack. -[19:39:22.145] Info: Pushing 0x 0 to the stack. -[19:39:22.146] Info: Returning from 0x1f4d to 0x1bae -[19:39:22.147] Info: Returning from 0x1bc4 to 0x1b96 -[19:39:22.147] Info: Pushing 0x1b99 to the stack. -[19:39:22.147] Info: Returning from 0x1f7f to 0xffa0 -[19:39:22.147] Info: Pushing 0xfbc3 to the stack. -[19:39:22.148] Info: Returning from 0xff8a to 0x 0 -[19:39:22.148] Info: Pushing 0xfbc3 to the stack. -[19:39:22.152] Info: Returning from 0xff47 to 0x 0 -[19:39:22.152] Info: Pushing 0xfbc3 to the stack. -[19:39:22.152] Error: Unimplemented opcode 0xfd at 0xfbc4! diff --git a/playing-coffee - Copy/pom.xml b/playing-coffee - Copy/pom.xml deleted file mode 100644 index beaa1be..0000000 --- a/playing-coffee - Copy/pom.xml +++ /dev/null @@ -1,15 +0,0 @@ - - 4.0.0 - sixtenhugosson - playing-coffee - 0.0.1-SNAPSHOT - playing-coffee - A GameBoy emulator written in Java. - - - junit - junit - 4.13.1 - - - \ No newline at end of file diff --git a/playing-coffee - Copy/roms/cgb_sound/cgb_sound.gb b/playing-coffee - Copy/roms/cgb_sound/cgb_sound.gb deleted file mode 100644 index dc50471..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/cgb_sound.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/readme.txt b/playing-coffee - Copy/roms/cgb_sound/readme.txt deleted file mode 100644 index 5d8d188..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/readme.txt +++ /dev/null @@ -1,86 +0,0 @@ -Game Boy Sound Hardware Tests ------------------------------ -These tests verify aspects of the sound hardware that the CPU can -observe. The ROMs and GBSs are either for DMG or CGB hardware, as there -are several differences. - - -Multi-ROM ---------- -In the main directory is a single ROM/GBS which runs all the tests. It -prints a test's number, runs the test, then "ok" if it passes, otherwise -a failure code. Once all tests have completed it either reports that all -tests passed, or reports the number of the first failed test as the -result code (1 = first). Finally, it makes several beeps. If a test -fails, it can be run on its own by finding the corresponding ROM/GBS in -the singles directories. - -Ths compact format on screen is to avoid having the results scroll off -the top, so the test can be started and allowed to run without having to -constantly monitor the display. - - -Failure information -------------------- -For more information about a failure code or information printed, see -the test's source code in source/. To find failure code N, search for -"set_test N", which will usually be before the subtest which failed. - - -Flashes, clicks, other glitches -------------------------------- -Some tests might need to turn the screen off and on, or cause slight -audio clicks. This does not indicate failure, and should be ignored. -Only the test result reported at the end is important, unless stated -otherwise. - - -LCD support ------------ -Tests generally print information on screen. The tests will work fine if -run on an emulator with NO LCD support, or as an GBS which has no -inherent screen; in particular, the VBL wait routine has a timeout in -case LY doesn't reflect the current LCD line. The text printing will -also work if the LCD doesn't support scrolling. - - -Output to memory ----------------- -Text output and the final result are also written to memory at $A000, -allowing testing a very minimal emulator that supports little more than -CPU and RAM. To reliably indicate that the data is from a test and not -random data, $A001-$A003 are written with a signature: $DE,$B0,$61. If -this is present, then the text string and final result status are valid. - -$A000 holds the overall status. If the test is still running, it holds -$80, otherwise it holds the final result code. - -All text output is appended to a zero-terminated string at $A004. An -emulator could regularly check this string for any additional -characters, and output them, allowing real-time text output, rather than -just printing the final output at the end. - - -GBS versions ------------- -Many GBS-based tests require that the GBS player either not interrupt -the init routine with the play routine, or if they do, not interrupt the -play routine again if it hasn't returned yet. This is because many tests -need to run for a while without returning. - -In addition to the other text output methods described above, GBS builds -report essential information bytes audibly, including the final result. -A byte is reported as a series of tones. The code is in binary, with a -low tone for 0 and a high tone for 1. The first tone is always a zero. A -final code of 0 means passed, 1 means failure, and 2 or higher indicates -a specific reason as listed in the source code by the corresponding -set_code line. Examples: - -Tones Binary Decimal Meaning -- - - - - - - - - - - - - - - - - - - - -low 0 0 passed -low high 01 1 failed -low high low 010 2 error 2 - --- -Shay Green diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/01-registers.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/01-registers.gb deleted file mode 100644 index be180ba..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/01-registers.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/02-len ctr.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/02-len ctr.gb deleted file mode 100644 index eb5ca82..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/02-len ctr.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/03-trigger.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/03-trigger.gb deleted file mode 100644 index 28b3586..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/03-trigger.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/04-sweep.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/04-sweep.gb deleted file mode 100644 index 75d6366..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/04-sweep.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/05-sweep details.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/05-sweep details.gb deleted file mode 100644 index 383e0c1..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/05-sweep details.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/06-overflow on trigger.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/06-overflow on trigger.gb deleted file mode 100644 index b2d5c75..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/06-overflow on trigger.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/07-len sweep period sync.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/07-len sweep period sync.gb deleted file mode 100644 index 31cce89..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/07-len sweep period sync.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/08-len ctr during power.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/08-len ctr during power.gb deleted file mode 100644 index a3120eb..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/08-len ctr during power.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/09-wave read while on.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/09-wave read while on.gb deleted file mode 100644 index 1e4a78c..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/09-wave read while on.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/10-wave trigger while on.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/10-wave trigger while on.gb deleted file mode 100644 index 56f0e90..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/10-wave trigger while on.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/11-regs after power.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/11-regs after power.gb deleted file mode 100644 index f6c84b4..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/11-regs after power.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/rom_singles/12-wave.gb b/playing-coffee - Copy/roms/cgb_sound/rom_singles/12-wave.gb deleted file mode 100644 index e488e5e..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/rom_singles/12-wave.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/source/01-registers.s b/playing-coffee - Copy/roms/cgb_sound/source/01-registers.s deleted file mode 100644 index ea9f5d5..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/01-registers.s +++ /dev/null @@ -1,117 +0,0 @@ -; - APU registers always have some bits set when read back. -; - Wave memory can be read back freely. -; - When powered off, registers are cleared, except high bit of NR52. -; - While off, register writes are ignored, but not reads. -; - Wave RAM is always readable and writable, and unaffected by power. - -.include "shell.inc" -.include "apu.s" - -main: - set_test 2,"NR10-NR51 and wave RAM write/read" - ld d,0 -- call test_rw - inc d - jr nz,- - - set_test 3,"NR52 write/read" - wreg NR52,$00 - lda NR52 - cp $70 - jp nz,test_failed - wreg NR52,$FF - lda NR52 - cp $F0 - jp nz,test_failed - - set_test 4,"Powering APU shouldn't affect wave" - ld a,$37 - call fill_wave - wreg NR52,$00 - - ; Verify that wave RAM is unchanged - ld hl,WAVE -- ld a,(hl+) - cp $37 - jp nz,test_failed - ld a,l - cp $40 - jr nz,- - wreg NR52,$80 ; on - - set_test 5,"Powering APU off should write 0 to all regs" - ld a,$FF - call fill_apu_regs - wreg NR52,$00 - wreg NR52,$80 - call regs_should_be_clear - - set_test 6,"When off, should ignore writes to registers" - wreg NR52,$00 - ld a,$FF - call fill_apu_regs - wreg NR52,$80 - call regs_should_be_clear - wreg NR52,$80 - - set_test 7,"When off, should allow normal register reads" - wreg NR52,$00 - call regs_should_be_clear - wreg NR52,$80 - - jp tests_passed - -regs_should_be_clear: - ld bc,masks - ld hl,NR10 -- ld a,(bc) - cp (hl) - jp nz,test_failed - inc bc - inc l - ld a,l - cp disabled clocks as well - ld a,1 - call end - - call begin - wchn 4,$40 ; enable length - wchn 1,-2 ; length = 2 - wchn 4,$40 ; enabled -> enabled doesn't clock - wchn 4,$00 ; enabled -> disabled doesn't clock - ld a,2 - call end -.else - set_test 4,"Anything besides enabling shouldnt't clock" - call begin - wchn 4,$40 ; enable length - wchn 1,-2 ; length = 2 - wchn 4,$40 ; enabled -> enabled doesn't clock - wchn 4,$00 ; enabled -> disabled doesn't clock - wchn 4,$00 ; disabled -> disabled doesn't clock - ld a,2 - call end -.endif - - set_test 5,"If clock makes length zero, should disable chan" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - lda chan_mask - ld b,a - lda NR52 ; channel now disabled - and b - jp nz,test_failed - - set_test 6,"If length already reached zero, shouldn't clock" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - wchn 4,0 - wchn 4,$40 ; no clock; length still 0 - wchn 4,0 - wchn 4,$40 ; no clock; length still 0 - lda chan_maxlen; end triggers channel, which loads it with max length - call end - - set_test 7,"Trigger should un-freeze length that reached zero" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - wchn 4,$00 ; disable - wchn 4,$80 ; trigger unfreezes length, so it takes on maximum value - delay_clocks 8192 - wchn 4,$40 ; enable - delay_apu 2 ; clock length by 2 - lda chan_maxlen - sub 2 - call end_nodelay - - set_test 8,"Trigger that un-freezes enabled length should clock it" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - wchn 4,$00 ; disable - wchn 4,$C0 ; trigger unfreezes length, and since enabled, clocks it - lda chan_maxlen - dec a - call end_nodelay - - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - wchn 4,$C0 ; trigger unfreezes length, and since enabled, clocks it - lda chan_maxlen - dec a - call end_nodelay - - set_test 9,"Triggering that clocks length of 1 ","should clock twice and shouldn't freeze" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$C0 ; trigger and enable - ; First length counter is enabled, which clocks it to 0 and freezes it - ; Trigger unfreezes length counter, which clocks it AGAIN - ; The result is the same as the previous test, which enables separately - lda chan_maxlen - dec a - call end_nodelay - - set_test 10,"Trigger shouldn't otherwise affect length" - call begin - wchn 1,0 ; length = max - delay_clocks 8192 - wchn 4,$80 ; trigger - lda chan_maxlen - call end_nodelay - -.ifndef CGB_02 - call begin - wchn 1,0 ; length = max - wchn 4,$80 ; trigger - lda chan_maxlen - call end - - call begin - wchn 1,-2 ; length = 2 - wchn 4,$80 ; trigger - ld a,2 - call end -.endif - - set_test 11,"Disabled DAC shouldn't stop other trigger effects" - call begin - wchn 0,$00 ; disable wave DAC - wchn 2,$07 ; disable square/noise DAC - wchn 1,-1 - wchn 4,$C0 ; clocks length, which becomes max - wchn 0,$80 ; enable wave DAC - wchn 2,$08 ; enable square/noise DAC - wchn 4,$80 ; trigger - lda chan_maxlen - dec a - call end - - set_test 12,"Other trigger effects should still occur when disabled" - call sync_apu - wchn 0,0 - wchn 4,0 - wchn 1,-1 - wchn 4,$40 ; len = 0 - wchn 4,0 - wchn 4,$40 ; len = 0 - wchn 4,$80 ; len = max - wchn 4,$40 ; len = max-1 - wchn 4,0 - wchn 4,$40 ; len = max-2 - wchn 0,$80 ; enable now - wchn 4,$C0 - lda chan_maxlen - sub 3 - call delay_apu_cycles - lda chan_mask - ld b,a - lda NR52 - and b - jp z,test_failed - delay_apu 1 - lda NR52 - and b - jp nz,test_failed - - ret diff --git a/playing-coffee - Copy/roms/cgb_sound/source/04-sweep.s b/playing-coffee - Copy/roms/cgb_sound/source/04-sweep.s deleted file mode 100644 index 17ac4e4..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/04-sweep.s +++ /dev/null @@ -1,120 +0,0 @@ -; Calc = calculation of new frequency and check for > $7FF -; Update = modification of frequency with new calculated value -.include "shell.inc" -.include "apu.s" - -begin: - call sync_sweep - wreg NR14,$40 - wreg NR11,-$21 - wreg NR12,$08 - ret - -should_be_almost_off: - lda NR52 - and $01 - jp z,test_failed - delay_apu 1 -should_be_off: - lda NR52 - and $01 - jp nz,test_failed - ret - -main: - set_test 2,"If shift>0, calculates on trigger" - call begin - wreg NR10,$01 - wreg NR13,$FF - wreg NR14,$C7 - call should_be_off - call begin - wreg NR10,$11 - wreg NR13,$FF - wreg NR14,$C7 - call should_be_off - - set_test 3,"If shift=0, doesn't calculate on trigger" - call begin - wreg NR10,$10 - wreg NR13,$FF - wreg NR14,$C7 - delay_apu 1 - call should_be_almost_off - - set_test 4,"If period=0, doesn't calculate" - call begin - wreg NR10,$00 - wreg NR13,$FF - wreg NR14,$C7 - delay_apu $20 - call should_be_almost_off - - set_test 5,"After updating frequency, calculates a second time" - call begin - wreg NR10,$11 - wreg NR13,$00 - wreg NR14,$C5 - delay_apu 1 - call should_be_almost_off - - set_test 6,"If calculation>$7FF, disables channel" - call begin - wreg NR10,$02 - wreg NR13,$67 - wreg NR14,$C6 - call should_be_off - - set_test 7,"If calculation<=$7FF, doesn't disable channel" - call begin - wreg NR10,$01 - wreg NR13,$55 - wreg NR14,$C5 - delay_apu $20 - call should_be_almost_off - - set_test 8,"If shift=0 and period>0, trigger enables" - call begin - wreg NR10,$10 - wreg NR13,$FF - wreg NR14,$C3 - delay_apu 2 - wreg NR10,$11 - delay_apu 1 - call should_be_almost_off - - set_test 9,"If shift>0 and period=0, trigger enables" - call begin - wreg NR10,$01 - wreg NR13,$FF - wreg NR14,$C3 - delay_apu 15 - wreg NR10,$11 - call should_be_almost_off - - set_test 10,"If shift=0 and period=0, trigger disables" - call begin - wreg NR10,$08 - wreg NR13,$FF - wreg NR14,$C3 - wreg NR10,$11 - delay_apu $20 - call should_be_almost_off - - set_test 11,"If shift=0, doesn't update" - call begin - wreg NR10,$10 - wreg NR13,$FF - wreg NR14,$C3 - delay_apu $20 - call should_be_almost_off - - set_test 12,"If period=0, doesn't update" - call begin - wreg NR10,$01 - wreg NR13,$00 - wreg NR14,$C5 - delay_apu $20 - call should_be_almost_off - - jp tests_passed diff --git a/playing-coffee - Copy/roms/cgb_sound/source/05-sweep details.s b/playing-coffee - Copy/roms/cgb_sound/source/05-sweep details.s deleted file mode 100644 index 1519b68..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/05-sweep details.s +++ /dev/null @@ -1,121 +0,0 @@ -; Calc = calculation of new frequency and check for > $7FF -; Update = modification of frequency with new calculated value -.include "shell.inc" -.include "apu.s" - -begin: - call sync_sweep - wreg NR14,$40 - wreg NR11,-$20 - wreg NR12,$08 - ret - -should_be_almost_off: - lda NR52 - and $01 - jp z,test_failed - delay_apu 1 -should_be_off: - lda NR52 - and $01 - jp nz,test_failed - ret - -main: - set_test 2,"Timer treats period 0 as 8" - call begin - wreg NR10,$11 - wreg NR13,$00 - wreg NR14,$C2 - delay_apu 1 - wreg NR10,$01 ; sweep enabled - delay_apu 3 - wreg NR10,$11 ; non-zero period so calc will occur when timer reloads - delay_apu $11 - call should_be_almost_off - - set_test 3,"Makes private copy of frequency on trigger" - call begin - wreg NR10,$12 - wreg NR13,$04 - wreg NR14,$80 - wreg NR13,$00 - delay_apu $39 - call should_be_almost_off - - set_test 4,"Exiting negate mode after calculation disables channel" - call begin - wreg NR10,$09 ; since shift > 0, calculates sweep value at init - wreg NR13,$00 - wreg NR14,$C0 - delay_apu 2 - wreg NR10,$10 ; neg->pos, so disables channel - call should_be_off - - set_test 5,"Ending negate after it maybe changed freq disables chan" - call begin - wreg NR10,$10 ; enable sweep - wreg NR13,$00 - wreg NR14,$C0 - delay_apu 2 - wreg NR10,$18 ; negate mode - delay_apu 2 - wreg NR10,$10 ; neg->pos, so disables channel - call should_be_off - - set_test 6,"Ending negate mode any other way doesn't disable channel" - call begin - wreg NR10,$1F ; use negate mode once - wreg NR14,$C0 - delay_apu 2 - wreg NR10,$18 ; since period > 0, doesn't calculate at init - wreg NR13,$00 - wreg NR14,$C0 - delay_apu 1 ; no sweep clock here - wreg NR10,$10 ; pos mode before neg mode ever used - delay_apu 1 ; sweep clock occurs here - wreg NR10,$0F ; now let neg mode be seen once, but period = 0 so no calculation is made - delay_apu 2 ; sweep clock occurs here - wreg NR10,$10 ; doesn't affect channel - delay_apu 2 ; sweep clock occurs here - wreg NR10,$1F ; let neg mode get used - delay_apu 18 - wreg NR10,$79 ; period and shift can be changed without channel disabling - delay_apu 5 - call should_be_almost_off - - set_test 7,"Subtract mode uses two's complement" - call begin - delay 2048 ; avoids extra length clocking on CGB-02 - wreg NR10,$1C - wreg NR13,$B0 - wreg NR14,$85 - delay_apu 2 - wreg NR10,$01 - wreg NR14,$C5 - delay_apu $1F - call should_be_almost_off - - set_test 8,"Subtract mode uses two's complement (upper bound)" - call begin - wreg NR10,$1C - wreg NR13,$B1 - wreg NR14,$85 - delay_apu 2 - wreg NR10,$01 - wreg NR14,$C5 - call should_be_off - - set_test 9,"Update channel frequency only when period is reloaded" - call begin - wreg NR10,$74 - wreg NR13,$06 - wreg NR14,$85 - delay_apu 14 ; just reloaded - wreg NR13,$06 - delay_apu 13 ; if 14, fails - wreg NR10,$11 - wreg NR14,$85 ; just before next reload, so freq is still $506 - call should_be_almost_off - - jp tests_passed diff --git a/playing-coffee - Copy/roms/cgb_sound/source/06-overflow on trigger.s b/playing-coffee - Copy/roms/cgb_sound/source/06-overflow on trigger.s deleted file mode 100644 index 2ebc236..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/06-overflow on trigger.s +++ /dev/null @@ -1,64 +0,0 @@ -; Finds highest and lowest frequencies that don't overflow -; immediately on trigger, for NR10 values of $00-$07 - -.include "shell.inc" -.include "apu.s" - -main: - - ; DMG-06: - ; 0555 0666 071C 0787 07C1 07E0 07F0 - - wreg NR12,8 - ld d,$01 -shift_loop: - ld a,d - sta NR10 - ld bc,$87FF -- ld a,c - sta NR13 - ld a,b - sta NR14 - delay_clocks 40 - lda NR52 - and 1 - jr nz,+ - dec bc - bit 6,b - jr z,- -+ res 7,b - call print_bc - inc d - bit 3,d - jr z,shift_loop - call print_newline - check_crc $F604603B - - ; DMG-05, DMG-06, DMG-09, CGB-04, CGB-05: - ; 0556 0667 071D 0788 07C2 07E1 07F1 - - wreg NR12,8 - ld d,$01 -shift_loop2: - ld a,d - sta NR10 - ld bc,$8000 -- ld a,c - sta NR13 - ld a,b - sta NR14 - delay_clocks 40 - lda NR52 - and 1 - jr z,+ - inc bc - bit 6,b - jr z,- -+ res 7,b - call print_bc - inc d - bit 3,d - jr z,shift_loop2 - check_crc $5A1697EE - - jp tests_passed diff --git a/playing-coffee - Copy/roms/cgb_sound/source/07-len sweep period sync.s b/playing-coffee - Copy/roms/cgb_sound/source/07-len sweep period sync.s deleted file mode 100644 index 6b3ed7e..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/07-len sweep period sync.s +++ /dev/null @@ -1,106 +0,0 @@ -; Tests length and sweep periods, and synchronization between the two -.include "shell.inc" -.include "apu.s" - -test_timing: - ; Time how long until next length clock -- inc de - ld a,(NR52) - and $01 - jr nz,- - - ;call print_de - - ; Error if not in 0...4 range - ld a,d - cp 0 - jp nz,test_failed - ld a,e - cp 5 - jp nc,test_failed - ret - -main: - - set_test 2,"Length period is wrong" - call sync_apu - wreg NR14,$40 ; avoids extra length clock - wreg NR11,$3F ; length = $01 - wreg NR12,$08 ; silent without disabling channel - wreg NR14,$C0 ; start length - ld de,-$170 - call test_timing - - set_test 3,"Sweep period is wrong" - call sync_sweep - wreg NR10,$10 ; sweep period = 1 - wreg NR12,$08 ; silent without disabling channel - wreg NR13,$FF ; max freq - wreg NR14,$87 ; start - ld de,-$2E4 - call test_timing - - set_test 4,"Sweep clock is synchronized with length" - call sync_sweep - wreg NR14,$40 ; avoids extra length clock - wreg NR11,$3F ; length = $01 - wreg NR12,$08 ; silent without disabling channel - wreg NR14,$C0 ; start length - ld de,-$170 - call test_timing - - set_test 5,"Powering up APU MODs next frame time with 8192" - call sync_apu - ld de,-$16F - call test_power - - call sync_apu - ld de,-$B5 - call test_power_off - - call sync_apu - delay_clocks 8192 - ld de,-$B5 - call test_power - - call sync_apu - delay_clocks 8192 - ld de,-$B5 - call test_power_off - - call sync_apu - ld de,-$B5 - wreg NR52,$00 ; power off - delay_clocks 8192 - call test_power - - set_test 6,"Powering up APU resets 128 Hz sweep divider" - call sync_sweep - ld de,-$229 - call test_power2 - - call sync_sweep - delay_apu 1 - ld de,-$229 - call test_power2 - - jp tests_passed - -test_power_off: - wreg NR52,$00 ; power off -test_power: - wreg NR52,$80 ; power on - wreg NR14,$40 - wreg NR11,-1 ; length = 1 - wreg NR12,8 - wreg NR14,$C0 - jp test_timing - -test_power2: - wreg NR52,$00 ; power off - wreg NR52,$80 ; power on - wreg NR10,$11 - wreg NR12,8 - wreg NR13,$00 - wreg NR14,$84 - jp test_timing diff --git a/playing-coffee - Copy/roms/cgb_sound/source/08-len ctr during power.s b/playing-coffee - Copy/roms/cgb_sound/source/08-len ctr during power.s deleted file mode 100644 index 1ea218a..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/08-len ctr during power.s +++ /dev/null @@ -1,84 +0,0 @@ -; On CGB, length counters are reset when powered up. -; On DMG, they are unaffected, and not clocked. - -;.define REQUIRE_DMG 1 -;.define REQUIRE_CGB 1 -.include "shell.inc" -.include "apu.s" - -enable_len_ctrs: - wreg NR22,8 - wreg NR24,$C0 - wreg NR12,8 - wreg NR14,$C0 - wreg NR30,$80 - wreg NR34,$C0 - wreg NR42,8 - wreg NR44,$C0 - ret - -main: - call sync_apu - - ld a,0 - call fill_apu_regs - - ; Load length counters - wreg NR41,-$33 - wreg NR31,-$44 - wreg NR11,-$11 - wreg NR21,-$22 - - delay_clocks 8192 - call enable_len_ctrs - - ; Power down. Comment out to see what would - ; happen if length counters did run. - wreg NR52,$00 - - ; Try to enable length counters - call enable_len_ctrs - - ; Give plenty of time for them to be clocked - delay_msec 250 - - ; Power back on and wait a bit longer - wreg NR52,$80 - ;call enable_len_ctrs ; can't do this here - delay_clocks 2048 - - ; Get values from length counters - wreg NR22,8 - wreg NR24,$C0 - ld a,$02 - call get_len_a - push af - - wreg NR12,8 - wreg NR14,$C0 - ld a,$01 - call get_len_a - push af - - wreg NR30,$80 - wreg NR34,$C0 - ld a,$04 - call get_len_a - push af - - wreg NR42,8 - wreg NR44,$C0 - ld a,$08 - call get_len_a - - ; Print them - call print_a - pop af - call print_a - pop af - call print_a - pop af - call print_a - - check_crc_dmg_cgb $32F0CFBB,$3CF589B4 - jp tests_passed diff --git a/playing-coffee - Copy/roms/cgb_sound/source/09-wave read while on.s b/playing-coffee - Copy/roms/cgb_sound/source/09-wave read while on.s deleted file mode 100644 index 2d06a77..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/09-wave read while on.s +++ /dev/null @@ -1,41 +0,0 @@ -; Reads from wave RAM while playing, each time 2 -; clocks later. - -;.define REQUIRE_DMG 1 -;.define REQUIRE_CGB 1 -.include "shell.inc" -.include "apu.s" - -main: - wreg NR51,0 ; mute sound - loop_n_times test,69 - check_crc_dmg_cgb $118A3620,$270DA9A3 - jp tests_passed - -test: - add $99 - ld b,a - - ; Reload wave and have its first - ; sample read occur 2 clocks earlier - ; each loop iteration - ld hl,wave - call load_wave - wreg NR30,$80 ; enable - wreg NR32,$00 ; silent - ld a,b - sta NR33 ; period - wreg NR34,$87 ; start - - ; Read from wave - wreg NR33,-2 ; period = 4 - delay_clocks 176 - lda WAVE - - call print_a - - ret - -wave: - .byte $00,$11,$22,$33,$44,$55,$66,$77 - .byte $88,$99,$AA,$BB,$CC,$DD,$EE,$FF diff --git a/playing-coffee - Copy/roms/cgb_sound/source/10-wave trigger while on.s b/playing-coffee - Copy/roms/cgb_sound/source/10-wave trigger while on.s deleted file mode 100644 index d7ec063..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/10-wave trigger while on.s +++ /dev/null @@ -1,49 +0,0 @@ -; Retriggers wave without stopping first - -;.define REQUIRE_DMG 1 -;.define REQUIRE_CGB 1 -.include "shell.inc" -.include "apu.s" - -main: - wreg NR51,0 ; mute sound - loop_n_times test,69 - check_crc_dmg_cgb $533D6D4D,$8130733A - jp tests_passed - -test: - add $99 - ld b,a - - ; Reload wave and have its first - ; sample read occur 2 clocks earlier - ; each loop iteration - ld hl,wave - call load_wave - wreg NR30,$80 ; enable - wreg NR32,$00 ; silent - ld a,b - sta NR33 ; period - wreg NR34,$87 ; start - - ; Retrigger wave - wreg NR33,-2 ; period = 4 - delay_clocks 168 - wreg NR34,$87 ; restart - delay_clocks 40 - - ; Print wave RAM - wreg NR30,0 - ld c,$30 -- ld a,($FF00+c) - call print_a - inc c - bit 6,c - jr z,- - call print_newline - - ret - -wave: - .byte $00,$11,$22,$33,$44,$55,$66,$77 - .byte $88,$99,$AA,$BB,$CC,$DD,$EE,$FF diff --git a/playing-coffee - Copy/roms/cgb_sound/source/11-regs after power.s b/playing-coffee - Copy/roms/cgb_sound/source/11-regs after power.s deleted file mode 100644 index 6379ad7..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/11-regs after power.s +++ /dev/null @@ -1,51 +0,0 @@ -; After powering sound off then on, NR12, NR14, and NR44 -; are clear. -.define REQUIRE_CGB 1 -.include "shell.inc" -.include "apu.s" - -main: - call sync_apu - - ld a,$FF - call fill_apu_regs - - ; Power down for a moment - wreg NR52,$00 - wreg NR41,-$12 - wreg NR12,$F0 - delay_msec 100 - wreg NR52,$80 - - set_test 2,"Powering off should clear NR12" - call sync_apu - wreg NR14,$80 - lda NR52 - and $01 - jp nz,test_failed - - set_test 3,"Powering off should clear NR13" - call sync_apu - wreg NR10,$11 - wreg NR12,$08 - wreg NR14,$80 - delay_apu 20 - lda NR52 - and $01 - jp z,test_failed - - set_test 4,"Powering off should clear NR41" - call sync_apu - delay_clocks 8192 ; avoids extra length clocking - wreg NR42,$08 - wreg NR44,$C0 - delay_apu 63 - lda NR52 - and $08 - jp z,test_failed - delay_apu 1 - lda NR52 - and $08 - jp nz,test_failed - - jp tests_passed diff --git a/playing-coffee - Copy/roms/cgb_sound/source/12-wave.s b/playing-coffee - Copy/roms/cgb_sound/source/12-wave.s deleted file mode 100644 index ba3185d..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/12-wave.s +++ /dev/null @@ -1,112 +0,0 @@ -; Tests wave channel timer reload and phase rest on trigger, -; and access to wave RAM while playing. -.define REQUIRE_CGB 1 -.include "shell.inc" -.include "apu.s" - -main: - ld hl,wave - call load_wave - wreg NR32,0 - - set_test 2,"Timer period or phase resetting is wrong" - wreg NR30,$80 - wreg NR33,$00 - wreg NR34,$80 - delay_clocks 1024 - wreg NR34,$80 - ld c,$31 - ld de,-$FE - call test_wave - - set_test 3,"Current byte readable at any wave addr" - wreg NR30,$80 - wreg NR33,$00 - wreg NR34,$80 - ld c,$3C - ld de,-$FE - call test_wave - - set_test 5,"Normal access when chan disabled" - wreg NR30,$80 - wreg NR33,$00 - wreg NR34,$80 - wreg NR30,$00 ; disable chan - wreg NR30,$80 ; DAC on - ld c,$31 - ld de,0 - call test_wave - - set_test 6,"Write test" - wreg NR30,$80 - wreg NR33,$F0 - wreg NR34,$87 - delay_clocks 256 - wreg $FF30,$BC - wreg NR30,0 - ld a,($FF34) - cp $BC - jp nz,test_failed - - set_test 7,"Timer period change" - wreg NR30,$80 - wreg NR33,$00 - wreg NR34,$87 - wreg NR33,$F0 - ld c,$30 - ld de,-$E - call test_wave - - set_test 8,"Frequency 0 is valid" - wreg NR30,$80 - wreg NR33,$00 - wreg NR34,$80 - ld c,$30 - ld de,-$FE - call test_wave - - set_test 9,"Maintains phase properly when vol = 0" - wreg NR30,$80 - wreg NR32,0 - wreg NR33,$00 - wreg NR34,$87 - ld c,$30 - ld de,-$1E - call test_wave - - set_test 10,"Maintains phase properly when stereo = 0" - wreg NR51,$00 - wreg NR30,$80 - wreg NR33,$00 - wreg NR34,$87 - ld c,$30 - ld de,-$1E - call test_wave - - jp tests_passed - -test_wave: -- inc de ; 8 - ld a,($FF00+c) ; 8 - or a ; 4 - jr z,- ; 12 - - ;call print_a - ;call print_de - - cp $11 - jp nz,test_failed - - - ; Error if not in 0...4 range - ld a,d - cp 0 - jp nz,test_failed - ld a,e - cp 5 - jp nc,test_failed - ret - -wave: - .byte $00,$11,$22,$33,$44,$55,$66,$77 - .byte $88,$99,$AA,$BB,$CC,$DD,$EE,$FF diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/build_gbs.s b/playing-coffee - Copy/roms/cgb_sound/source/common/build_gbs.s deleted file mode 100644 index 877754f..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/build_gbs.s +++ /dev/null @@ -1,139 +0,0 @@ -; Build as GBS music file - -.memoryMap - defaultSlot 0 - slot 0 $2000 size $2000 - slot 1 $C000 size $2000 -.endMe - -.romBankSize $2000 -.romBanks 2 - -.define RST_OFFSET $70 - -.ifndef GBS_TMA - .define GBS_TMA 0 -.endif - -.ifndef GBS_TAC - .define GBS_TAC 0 -.endif - -;;;; GBS music file header - -.ifndef CUSTOM_HEADER - .byte "GBS" - .byte 1,1,1 ; vers, song count, first song - .word load_addr, reset, gbs_play_, std_stack - .byte GBS_TMA,GBS_TAC ; timer -.endif - .org $10 - .ds $60,0 -load_addr: - .org RST_OFFSET+$70 ; space for RST vectors - .ds $148-RST_OFFSET-$70,0 - .org $150 ; wla insists on generating GB header - -gbs_play_: - jp gbs_play ; GBS spec disallows having gbs_play in RAM - -;;;; Shell - -.include "shell.s" - -.define gbs_idle nv_ram -.redefine nv_ram nv_ram+2 - -init_runtime: - ; Identify as DMG hardware - ld a,$01 - ld (gb_id),a - - ; Save return address - pop hl - ld a,l - ld (gbs_idle),a - ld a,h - ld (gbs_idle+1),a - - ; Delay 1/4 second to give time - ; for GBS player to interrupt with - ; play, if it's going to do so - delay_msec 250 - -.ifndef CUSTOM_PLAY -gbs_play: -.endif - ; Get return address - ld a,(gbs_idle) - ld l,a - ld a,(gbs_idle+1) - ld h,a - - ; If zero, then play interrupted init - ; call, or another play call, and we - ; can't run the program properly. - or l - jp z,internal_error - - setw gbs_idle,0 - jp hl - - -; Reports A in binary as high and low tones, with -; leading low tone for reference. Omits leading -; zeroes. -; Preserved: AF, BC, DE, HL -play_byte: - push af - push hl - - ; HL = (A << 1) | 1 - scf - rla - ld l,a - ld h,0 - rl h - - ; Shift left until next-to-top bit is 1 -- add hl,hl - bit 6,h - jr z,- - - ; Reset sound - delay_msec 400 - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - -- add hl,hl - - ; Low or high pitch based on bit shifted out - ; of HL - ld a,0 - jr nc,+ - ld a,$FF -+ sta NR23 - - ; Play short tone - wreg NR21,$A0 - wreg NR22,$F0 - wreg NR24,$86 - delay_msec 75 - wreg NR22,0 - wreg NR23,$F8 - wreg NR24,$87 - delay_msec 200 - - ; Loop until HL = $8000 - ld a,h - xor $80 - or l - jr nz,- - - pop hl - pop af - ret - -.ends diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/build_rom.s b/playing-coffee - Copy/roms/cgb_sound/source/common/build_rom.s deleted file mode 100644 index f369b92..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/build_rom.s +++ /dev/null @@ -1,70 +0,0 @@ -; Build as GB ROM - -.memoryMap - defaultSlot 0 - slot 0 $0000 size $4000 - slot 1 $C000 size $4000 -.endMe - -.romBankSize $4000 -.romBanks 2 - -.cartridgeType 2 ; MBC1+RAM -.ramsize 02 ; 8K -.computeChecksum -.computeComplementCheck - -;;;; GB ROM header - - ; Reserve space for RST handlers - .org $70 - - ; Keep unused space filled, otherwise - ; wla moves code here - .ds $90,0 - - ; GB header read by bootrom - .org $100 - nop - jp reset - - ; Nintendo logo required for proper boot - .byte $CE,$ED,$66,$66,$CC,$0D,$00,$0B - .byte $03,$73,$00,$83,$00,$0C,$00,$0D - .byte $00,$08,$11,$1F,$88,$89,$00,$0E - .byte $DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 - .byte $BB,$BB,$67,$63,$6E,$0E,$EC,$CC - .byte $DD,$DC,$99,$9F,$BB,$B9,$33,$3E - - ; Internal name - .ifdef ROM_NAME - .byte ROM_NAME - .endif - - ; CGB/DMG requirements - .org $143 - .ifdef REQUIRE_CGB - .byte $C0 - .else - .ifndef REQUIRE_DMG - .byte $80 - .endif - .endif - - ; Keep unused space filled, otherwise - ; wla moves code here - .org $150 - .ds $2150-$150,0 - -;;;; Shell - -.define NEED_CONSOLE 1 -.include "shell.s" - -init_runtime: - ret - -play_byte: - ret - -.ends diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/console.bin b/playing-coffee - Copy/roms/cgb_sound/source/common/console.bin deleted file mode 100644 index b02f2d3..0000000 Binary files a/playing-coffee - Copy/roms/cgb_sound/source/common/console.bin and /dev/null differ diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/console.s b/playing-coffee - Copy/roms/cgb_sound/source/common/console.s deleted file mode 100644 index 403fa5c..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/console.s +++ /dev/null @@ -1,285 +0,0 @@ -; Scrolling text console - -; Console is 20x18 characters. Buffers lines, so -; output doesn't appear until a newline or flush. -; If scrolling isn't supported (i.e. SCY is treated -; as if always zero), the first 18 lines will -; still print properly). Also works properly if -; LY isn't supported (always reads back as the same -; value). - -.define console_width 20 - -.define console_buf bss+0 -.define console_pos bss+console_width -.define console_mode bss+console_width+1 -.define console_scroll bss+console_width+2 -.redefine bss bss+console_width+3 - - -; Waits for start of LCD blanking period -; Preserved: BC, DE, HL -console_wait_vbl: - push bc - - ; Wait for start of vblank, with - ; timeout in case LY doesn't work - ; or LCD is disabled. - ld bc,-1250 -- inc bc - ld a,b - or c - jr z,@timeout - lda LY - cp 144 - jr nz,- -@timeout: - - pop bc - ret - - -; Initializes text console -console_init: - call console_hide - - ; CGB-specific inits - ld a,(gb_id) - and gb_id_cgb - call nz,@init_cgb - - ; Clear nametable - ld a,' ' - call @fill_nametable - - ; Load tiles - ld hl,TILES+$200 - ld c,0 - call @load_tiles - ld hl,TILES+$A00 - ld c,$FF - call @load_tiles - - ; Init state - setb console_pos,console_width - setb console_mode,0 - setb console_scroll,-8 - call console_scroll_up_ - jr console_show - -@fill_nametable: - ld hl,BGMAP0 - ld b,4 -- ld (hl),a - inc l - jr nz,- - inc h - dec b - jr nz,- - ret - -@init_cgb: - ; Clear palette - wreg $FF68,$80 - ld b,16 -- wreg $FF69,$FF - wreg $FF69,$7F - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - dec b - jr nz,- - - ; Clear attributes - wreg VBK,1 - ld a,0 - call @fill_nametable - - wreg VBK,0 - ret - -@load_tiles: - ld de,ASCII - ld b,96 --- push bc - ld b,8 -- ld a,(de) - inc de - xor c - ldi (hl),a - ldi (hl),a - dec b - jr nz,- - pop bc - dec b - jr nz,-- - ret - - -; Shows console display -; Preserved: AF, BC, DE, HL -console_show: - push af - - ; Enable LCD - call console_wait_vbl - wreg LCDC,$91 - wreg SCX,0 - wreg BGP,$E4 - - jp console_apply_scroll_ - - -; Hides console display by turning LCD off -; Preserved: AF, BC, DE, HL -console_hide: - push af - - ; LCD off - call console_wait_vbl - wreg LCDC,$11 - - pop af - ret - - -; Changes to normal text mode -; Preserved: BC, DE, HL -console_normal: - xor a - jr console_set_mode - -; Changes to inverse text mode -; Preserved: BC, DE, HL -console_inverse: - ld a,$80 - -; Changes console mode to A. -; 0: Normal, $80: Inverse -; Preserved: BC, DE, HL -console_set_mode: - and $80 - ld (console_mode),a - ret - - -; Prints char A to console. Will not appear until -; a newline or flush occurs. -; Preserved: AF, BC, DE, HL -console_print: - push af - - cp 10 - jr z,console_newline_ - - push hl - push af - ld hl,console_pos - ldi a,(hl) - cp BGMAP0) >> 2 - add hl,hl - add hl,hl - - ; Copy line - ld de,console_buf + console_width -- dec e - ld a,(de) - ldi (hl),a - ld a,e - cp checksum - ldi (hl),a - ld (hl),d - inc l - ld (hl),c - inc l - ld (hl),b - - pop hl - pop de - pop bc - pop af - ret diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/delay.s b/playing-coffee - Copy/roms/cgb_sound/source/common/delay.s deleted file mode 100644 index cbcdcf3..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/delay.s +++ /dev/null @@ -1,220 +0,0 @@ -; Delays in cycles, milliseconds, etc. - -; All routines are re-entrant (no global data). Routines never -; touch BC, DE, or HL registers. These ASSUME CPU is at normal -; speed. If running at double speed, msec/usec delays are half advertised. - -; Delays n cycles, from 0 to 16777215 -; Preserved: AF, BC, DE, HL -.macro delay ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 16777215 - .printt "Delay must be < 16777216" - .fail - .endif - delay_ n&$FFFF, n>>16 -.endm - -; Delays n clocks, from 0 to 16777216*4. Must be multiple of 4. -; Preserved: AF, BC, DE, HL -.macro delay_clocks ARGS n - .if n # 4 != 0 - .printt "Delay must be a multiple of 4" - .fail - .endif - delay_ (n/4)&$FFFF,(n/4)>>16 -.endm - -; Delays n microseconds (1/1000000 second) -; n can range from 0 to 4000 usec. -; Preserved: AF, BC, DE, HL -.macro delay_usec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 4000 - .printt "Delay must be <= 4000 usec" - .fail - .endif - delay_ ((n * 1048576 + 500000) / 1000000)&$FFFF,((n * 1048576 + 500000) / 1000000)>>16 -.endm - -; Delays n milliseconds (1/1000 second) -; n can range from 0 to 10000 msec. -; Preserved: AF, BC, DE, HL -.macro delay_msec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 10000 - .printt "Delay must be <= 10000 msec" - .fail - .endif - delay_ ((n * 1048576 + 500) / 1000)&$FFFF, ((n * 1048576 + 500) / 1000)>>16 -.endm - - ; All the low/high quantities are to deal wla-dx's asinine - ; restriction full expressions must evaluate to a 16-bit - ; value. If the author ever rectifies this, all "high" - ; arguments can be treated as zero and removed. Better yet, - ; I'll just find an assembler that didn't crawl out of - ; the sewer (this is one of too many bugs I've wasted - ; hours working around). - - .define max_short_delay 28 - - .macro delay_long_ ARGS n, high - ; 0+ to avoid assembler treating as memory read - ld a,0+(((high<<16)+n) - 11) >> 16 - call delay_65536a_9_cycles_ - delay_nosave_ (((high<<16)+n) - 11)&$FFFF, 0 -.endm - - ; Doesn't save AF, allowing minimization of AF save/restore - .macro delay_nosave_ ARGS n, high - ; 65536+11 = maximum delay using delay_256a_9_cycles_ - ; 255+22 = maximum delay using delay_a_20_cycles - ; 22 = minimum delay using delay_a_20_cycles - .if high > 1 - delay_long_ n, high - .else - .if high*n > 11 - delay_long_ n, high - .else - .if (high*(255+22+1))|n > 255+22 - ld a,>(((high<<16)+n) - 11) - call delay_256a_9_cycles_ - delay_nosave_ <(((high<<16)+n) - 11), 0 - .else - .if n >= 22 - ld a,n - 22 - call delay_a_20_cycles - .else - delay_short_ n - .endif - .endif - .endif - .endif -.endm - - .macro delay_ ARGS low, high - .if (high*(max_short_delay+1))|low > max_short_delay - push af - delay_nosave_ ((high<<16)+low - 7)&$FFFF, ((high<<16)+low - 7)>>16 - pop af - .else - delay_short_ low - .endif -.endm - - -; Delays A cycles + overhead -; Preserved: BC, DE, HL -; Time: A+20 cycles (including CALL) -delay_a_20_cycles: -- sub 5 ; 2 - jr nc,- ;3/2 do multiples of 5 - rra ; 1 - jr nc,+ ;3/2 bit 0 -+ adc 1 ; 2 - ret nc ;5/2 -1: 0 cycles - ret z ;5/2 0: 2 cycles - nop ; 1 1: 4 cycles - ret ; 4 (thanks to dclxvi for original algorithm) - -; Delays A*256 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*256+12 cycles (including CALL) -delay_256a_12_cycles: - or a ; 1 - ret z ; 5/2 -delay_256a_9_cycles_: -- delay 256-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays A*65536 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*65536+12 cycles (including CALL) -delay_65536a_12_cycles: - or a ; 1 - ret z ;5/2 -delay_65536a_9_cycles_: -- delay 65536-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays H*256+L cycles + overhead -; Preserved: AF, BC, DE, HL -; Time: H*256+L+51 cycles -delay_hl_51_cycles: - push af - ld a,h - call delay_256a_12_cycles - ld a,l - call delay_a_20_cycles - pop af - ret - - ; delay_short_ macro calls into these - .ds max_short_delay-10,$00 ; NOP repeated several times -delay_unrolled_: - ret - -.macro delay_short_ ARGS n - .if n < 0 - .fail - .endif - .if n > max_short_delay - .fail - .endif - - .if n == 1 - nop - .endif - .if n == 2 - nop - nop - .endif - .if n == 3 - .byte $18,$00 ; JR +0 - .endif - .if n == 4 - .byte $18,$00 ; JR +0 - nop - .endif - .if n == 5 - .byte $18,$00 ; JR +0 - nop - nop - .endif - .if n == 6 - .byte $18,$00 ; JR +0 - .byte $18,$00 ; JR +0 - .endif - .if n == 7 - push af - pop af - .endif - .if n == 8 - push af - pop af - nop - .endif - .if n == 9 - push af - pop af - nop - nop - .endif - .if n >= 10 - call delay_unrolled_ + 10 - n - .endif -.endm diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/gb.inc b/playing-coffee - Copy/roms/cgb_sound/source/common/gb.inc deleted file mode 100644 index 2d0118d..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/gb.inc +++ /dev/null @@ -1,81 +0,0 @@ -; Game Boy hardware addresses - -; $0000-$3FFF Fixed ROM bank -; $4000-$7FFF Switchable bank -; $8000-$9FFF VRAM -; $A000-$BFFF optional cartridge RAM -; $C000-$DFFF RAM -; $E000-$FDFF RAM mirror -; $FE00-$FE9F OAM -; $FEA0-$FEFF unused -; $FF00-$FF7F registers -; $FF80-$FFFE RAM -; $FFFF register - -; Memory -.define VRAM $8000 ; video memory -.define TILES $8000 ; tile images -.define BGMAP0 $9800 ; first 32x32 tilemap -.define BGMAP1 $9C00 ; second 32x32 tilemap -.define BRAM $A000 ; cart memory -.define WRAM $C000 ; internal memory -.define OAM $FE00 ; sprite memory -.define HRAM $FF80 ; fast memory for LDH - -; Registers - -.define RAMEN $0000 ; cartridge WRAM control -.define BANK $2000 ; bank select -.define P1 $FF00 ; controller - -; Game link I/O -.define SB $FF01 ; serial buffer -.define SC $FF02 ; serial control - -; Interrupts -.define DIV $FF04 -.define TIMA $FF05 -.define TMA $FF06 -.define TAC $FF07 -.define IF $FF0F -.define IE $FFFF - -; LCD registers -.define LCDC $FF40 ; control -.define STAT $FF41 ; status -.define SCY $FF42 ; scroll Y -.define SCX $FF43 ; scroll X -.define LY $FF44 ; current Y being rendered -.define BGP $FF47 - -.define KEY1 $FF4D ; for changing CPU speed -.define VBK $FF4F - -; Sound registers -.define NR10 $FF10 -.define NR11 $FF11 -.define NR12 $FF12 -.define NR13 $FF13 -.define NR14 $FF14 - -.define NR21 $FF16 -.define NR22 $FF17 -.define NR23 $FF18 -.define NR24 $FF19 - -.define NR30 $FF1A -.define NR31 $FF1B -.define NR32 $FF1C -.define NR33 $FF1D -.define NR34 $FF1E - -.define NR41 $FF20 -.define NR42 $FF21 -.define NR43 $FF22 -.define NR44 $FF23 - -.define NR50 $FF24 -.define NR51 $FF25 -.define NR52 $FF26 - -.define WAVE $FF30 diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/macros.inc b/playing-coffee - Copy/roms/cgb_sound/source/common/macros.inc deleted file mode 100644 index 9d7cf44..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/macros.inc +++ /dev/null @@ -1,91 +0,0 @@ -; General macros - -; Reads A from addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 3 cycles -.macro lda ; addr - ldh a,(\1 - $FF00) -.endm - -; Writes A to addr, from $FF00 to $FFFF -; Preserved: AF, BC, DE, HL -; Time: 3 cycles -.macro sta ; addr - ldh (\1 - $FF00),a -.endm - -; Writes immediate data to addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 5 cycles -.macro wreg ARGS addr, data - ld a,data - sta addr -.endm - -; Writes byte to addr -; Preserved: F, BC, DE, HL -; Time: 6 cycles -.macro setb ; addr, data - ld a,\2 - ld (\1),a -.endm - -; Writes word to addr -; Preserved: F, BC, DE, HL -; Time: 12 cycles -.macro setw ; addr, data - ld a,<\2 - ld (\1),a - ld a,>\2 - ld (\1+1),a -.endm - -; Calls routine multiple times, with A having the -; value 'start' the first time, 'start+step' the -; second time, up to 'end' for the last time. -; Preserved: BC, DE, HL -.macro for_loop ; routine,start,end,step - ld a,\2 - -for_loop\@: - push af - call \1 - pop af - - add \4 - cp <(\3 + \4) - jr nz,for_loop\@ -.endm - -; Calls routine n times. The value of A in the routine -; counts from 0 to n-1. -; Preserved: BC, DE, HL -.macro loop_n_times ; routine,n - for_loop \1,0,\2 - 1,+1 -.endm - -; Same as for_loop, but counts with 16-bit value in BC. -; Preserved: DE, HL -.macro for_loop16 ; routine,start,end,step - ld bc,\2 - -for_loop16\@: - push bc - call \1 - pop bc - - ld a,c - add <\4 - ld c,a - - ld a,b - adc >\4 - ld b,a - - cp >(\3+\4) - jr nz,for_loop16\@ - - ld a,c - cp <(\3+\4) - jr nz,for_loop16\@ -.endm diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/numbers.s b/playing-coffee - Copy/roms/cgb_sound/source/common/numbers.s deleted file mode 100644 index 6d6faf8..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/numbers.s +++ /dev/null @@ -1,177 +0,0 @@ -; Printing of numeric values - -; Prints value of indicated register/pair -; as 2/4 hex digits, followed by a space. -; Updates checksum with printed values. -; Preserved: AF, BC, DE, HL - -print_regs: - call print_af - call print_bc - call print_de - call print_hl - call print_newline - ret - -print_a: - push af -print_a_: - call print_hex - ld a,' ' - call print_char_nocrc - pop af - ret - -print_af: - push af - call print_hex - pop af -print_f: - push bc - push af - pop bc - call print_c - pop bc - ret - -print_b: - push af - ld a,b - jr print_a_ - -print_c: - push af - ld a,c - jr print_a_ - -print_d: - push af - ld a,d - jr print_a_ - -print_e: - push af - ld a,e - jr print_a_ - -print_h: - push af - ld a,h - jr print_a_ - -print_l: - push af - ld a,l - jr print_a_ - -print_bc: - push af - push bc -print_bc_: - ld a,b - call print_hex - ld a,c - pop bc - jr print_a_ - -print_de: - push af - push bc - ld b,d - ld c,e - jr print_bc_ - -print_hl: - push af - push bc - ld b,h - ld c,l - jr print_bc_ - - -; Prints A as two hex chars and updates checksum -; Preserved: BC, DE, HL -print_hex: - call update_crc -print_hex_nocrc: - push af - swap a - call + - pop af - -+ and $0F - cp 10 - jr c,+ - add 7 -+ add '0' - jp print_char_nocrc - - -; Prints char_nz if Z flag is clear, -; char_z if Z flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nz ARGS char_nz, char_z - push af - ld a,char_nz - jr nz,print_nz\@ - ld a,char_z -print_nz\@: - call print_char - pop af -.endm - - -; Prints char_nc if C flag is clear, -; char_c if C flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nc ARGS char_nc, char_c - push af - ld a,char_nc - jr nz,print_nc\@ - ld a,char_c -print_nc\@: - call print_char - pop af -.endm - - -; Prints A as 2 decimal digits -; Preserved: AF, BC, DE, HL -print_dec2: - push af - push bc - jr + - - -; Prints A as 1-3 digit decimal value -; Preserved: AF, BC, DE, HL -print_dec: - push af - push bc - - cp 10 - jr c,++ - ld c,100 - cp c - call nc,@digit -+ ld c,10 - call @digit -++ add '0' - call print_char - - pop bc - pop af - ret - -@digit: - ld b,'0'-1 -- inc b - sub c - jr nc,- - add c - - ld c,a - ld a,b - call print_char - ld a,c - ret diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/printing.s b/playing-coffee - Copy/roms/cgb_sound/source/common/printing.s deleted file mode 100644 index bb9389b..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/printing.s +++ /dev/null @@ -1,77 +0,0 @@ -; Main printing routine that checksums and -; prints to output device - -; Character that does equivalent of print_newline -.define newline 10 - -; Prints char without updating checksum -; Preserved: BC, DE, HL -;print_char_nocrc (defined by user) - - -; Prints character and updates checksum UNLESS -; it's a newline. -; Preserved: AF, BC, DE, HL -print_char: - push af - cp newline - call nz,update_crc - call print_char_nocrc - pop af - ret - - -; Prints space. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_space: - push af - ld a,' ' - call print_char_nocrc - pop af - ret - - -; Advances to next line. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_newline: - push af - ld a,newline - call print_char_nocrc - pop af - ret - - -; Prints immediate string -; Preserved: AF, BC, DE, HL -.macro print_str ; string,string2 - push hl - call print_str_ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 - pop hl -.endm - -print_str_: - pop hl - call print_str_hl - jp hl - - -; Prints zero-terminated string pointed to by HL. -; On return, HL points to byte AFTER zero terminator. -; Preserved: AF, BC, DE -print_str_hl: - push af - jr + -- call print_char -+ ldi a,(hl) - or a - jr nz,- - pop af - ret diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/shell.s b/playing-coffee - Copy/roms/cgb_sound/source/common/shell.s deleted file mode 100644 index 3e588c7..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/shell.s +++ /dev/null @@ -1,261 +0,0 @@ -; Common routines and runtime - -.define RUNTIME_INCLUDED 1 - -; A few bytes of RAM that aren't cleared -.define nv_ram_base $D800 -.define nv_ram nv_ram_base - -; Address of next normal variable -.define bss_base nv_ram_base+$80 -.define bss bss_base - -; Address of next direct-page ($FFxx) variable -.define dp_base $FF80 -.define dp dp_base - -; Top of stack -.define std_stack $DFFF+1 - -; Final exit result byte is written here -.define final_result $A000 - -; Text output is written here as zero-terminated string -.define text_out_base $A004 - -; DMG/CGB hardware identifier -.define gb_id_cgb $10 ; mask for testing CGB bit -.define gb_id_devcart $04 ; mask for testing "on devcart" bit -.define gb_id nv_ram -.redefine nv_ram nv_ram+1 - -; Copies C*$100 bytes from HL to $C000, then jumps to it. -; A is preserved for jumped-to code. -copy_to_wram_then_run: - ld b,a - - ld de,$C000 -- ld a,(hl+) - ld (de),a - inc e - jr nz,- - inc d - dec c - jr nz,- - - ld a,b - jp $C000 - - -.ifndef RST_OFFSET - .define RST_OFFSET 0 -.endif - -.ifndef CUSTOM_RESET - reset: - di - - ; Run code from $C000, as is done on devcart. This - ; ensures minimal difference in how it behaves. - ld hl,$4000 - ld c,$14 - jp copy_to_wram_then_run - - .bank 1 slot 1 - .org 0 - jp std_reset -.endif - -; returnOrg puts this code AFTER user code. -.section "runtime" returnOrg - - ; Catch user code running off end - jp internal_error - -; Common routines -.include "gb.inc" -.include "macros.inc" -.include "delay.s" -.include "crc.s" -.include "printing.s" -.include "numbers.s" -.include "testing.s" - -; Sets up hardware and runs main -std_reset: - - ; Init hardware - di - ld sp,std_stack - - ; Save DMG/CGB id - ld (gb_id),a - - ; Clear memory except very top of stack - ld bc,std_stack-bss_base - 2 - ld hl,bss_base - call clear_mem - ld bc,$FFFF-dp_base - ld hl,dp_base - call clear_mem - - ; Init hardware - wreg TAC,$00 - wreg IF,$00 - wreg IE,$00 - - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - - call init_runtime - call init_text_out - call console_init - call init_testing - - .ifdef TEST_NAME - print_str TEST_NAME,newline,newline - .endif - - call reset_crc ; in case init_runtime prints anything - - delay_msec 250 - - ; Run user code - call main - - ; Default is to successful exit - ld a,0 - jp exit - - -; Exits code and reports value of A -exit: - ld sp,std_stack - push af - call + - call console_show - pop af - call play_byte - jp post_exit - -+ push af - call print_newline - pop af - - ; Report exit status - cp 1 - - ; 0: "" - ret c - - ; 1: "Failed" - jr nz,+ - print_str "Failed",newline - ret - - ; n: "Failed #n" -+ print_str "Failed #" - call print_dec - call print_newline - ret - - -; Clears BC bytes starting at HL -clear_mem: - ; If C>0, increment B - dec bc - inc c - inc b - - ld a,0 -- ld (hl+),a - dec c - jr nz,- - dec b - jr nz,- - ret - - -; Reports internal error and exits with code 255 -internal_error: - print_str "Internal error" - ld a,255 - jp exit - - -; build_devcart and build_multi customize this -.ifndef CUSTOM_PRINT - .define text_out_addr bss+0 - .redefine bss bss+2 - - ; Initializes text output to cartridge RAM - init_text_out: - ; Enable cartridge RAM and set text output pointer - setb RAMEN,$0A - setw text_out_addr,text_out_base - setb text_out_base-3,$DE - setb text_out_base-2,$B0 - setb text_out_base-1,$61 - setb text_out_base,0 - setb final_result,$80 - ret - - - ; Appends character to text output string - ; Preserved: AF, BC, DE, HL - write_text_out: - push hl - push af - ld a,(text_out_addr) - ld l,a - ld a,(text_out_addr+1) - ld h,a - inc hl - ld (hl),0 - ld a,l - ld (text_out_addr),a - ld a,h - ld (text_out_addr+1),a - dec hl - pop af - ld (hl),a - pop hl - ret - - print_char_nocrc: - call write_text_out - jp console_print -.endif - - -; only build_rom uses console -.ifdef NEED_CONSOLE - .include "console.s" -.else - console_init: - console_print: - console_flush: - console_normal: - console_inverse: - console_show: - console_set_mode: - ret -.endif - - -; build_devcart and build_multi need to customize this -.ifndef CUSTOM_EXIT - post_exit: - ld (final_result),a - forever: - wreg NR52,0 ; sound off -- jr - -.endif - - -.macro def_rst ARGS addr - .bank 0 slot 0 - .org addr+RST_OFFSET -.endm diff --git a/playing-coffee - Copy/roms/cgb_sound/source/common/testing.s b/playing-coffee - Copy/roms/cgb_sound/source/common/testing.s deleted file mode 100644 index 5dd63ce..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/common/testing.s +++ /dev/null @@ -1,195 +0,0 @@ -; Diagnostic and testing utilities - -.define test_code bss+0 -.define test_name bss+1 -.redefine bss bss+3 - - -; Sets test code and optional error text. -; Takes multiple strings due to wla's idiotic -; default limit of 63 chars per string. -; Preserved: AF, BC, DE, HL -.macro set_test ; code[,text[,text2[,text3]]] - push hl - call set_test_ - jr @set_test\@ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .if NARGS > 3 - .byte \4 - .endif - .byte 0 -@set_test\@: - pop hl -.endm - -set_test_: - pop hl - push hl - push af - inc hl - inc hl - ldi a,(hl) - ld (test_code),a - ld a,l - ld (test_name),a - ld a,h - ld (test_name+1),a - pop af - ret - - -; Initializes testing module -init_testing: - set_test $FF - call init_crc - ret - - -; Reports "Passed", then exits with code 0 -tests_passed: - call print_newline - print_str "Passed" - ld a,0 - jp exit - - -; Reports "Done" if set_test has never been used, -; "Passed" if set_test 0 was last used, or -; failure if set_test n was last used. -tests_done: - ld a,(test_code) - inc a - jr z,+ - dec a - jr z,tests_passed - jr test_failed -+ print_str "Done" - ld a,0 - jp exit - - -; Reports current error text and exits with result code -test_failed: - ld a,(test_name) - ld l,a - ld a,(test_name+1) - ld h,a - ld a,(hl) - or a - jr z,+ - call print_newline - call print_str_hl - call print_newline -+ - ld a,(test_code) - cp $FF ; if a = $FF then a = 1 - jr nz,+ - ld a,1 -+ jp exit - - -; Prints checksum as 8-character hex value -; Preserved: AF, BC, DE, HL -print_crc: - push af - - ; Must read checksum entirely before printing, - ; since printing updates it. - lda checksum - cpl - push af - - lda checksum+1 - cpl - push af - - lda checksum+2 - cpl - push af - - lda checksum+3 - cpl - - call print_hex - pop af - call print_hex - pop af - call print_hex - pop af - call print_a - - pop af - ret - - -; If checksum doesn't match expected, reports failed test. -; Passing 0 just prints checksum. Clears checksum afterwards. -.macro check_crc ARGS crc - .if crc == 0 - call print_newline - call print_crc - .else - ld bc,(crc >> 16) ~ $FFFF - ld de,(crc & $FFFF) ~ $FFFF - call check_crc_ - .endif -.endm - -; Checks CRC, differing based on DMG or CGB build -.macro check_crc_dmg_cgb ARGS dmg, cgb - .ifdef REQUIRE_DMG - check_crc dmg - .else - .ifdef REQUIRE_CGB - check_crc cgb - .else - .printt "CGB or DMG must be specified" - .fail - .endif - .endif -.endm - -check_crc_: - lda checksum+0 - cp e - jr nz,+ - - lda checksum+1 - cp d - jr nz,+ - - lda checksum+2 - cp c - jr nz,+ - - lda checksum+3 - cp b - jr nz,+ - - jp reset_crc - -+ call print_crc - jp test_failed - - -; Updates checksum with bytes from addr to addr+size-1 -.macro checksum_mem ARGS addr,size - ld hl,addr - ld bc,size - call checksum_mem_ -.endm - -checksum_mem_: -- ldi a,(hl) - call update_crc - dec bc - ld a,b - or c - jr nz,- - ret diff --git a/playing-coffee - Copy/roms/cgb_sound/source/linkfile b/playing-coffee - Copy/roms/cgb_sound/source/linkfile deleted file mode 100644 index 02a5a2e..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/linkfile +++ /dev/null @@ -1,2 +0,0 @@ -[objects] -test.o diff --git a/playing-coffee - Copy/roms/cgb_sound/source/readme.txt b/playing-coffee - Copy/roms/cgb_sound/source/readme.txt deleted file mode 100644 index a0269c1..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/readme.txt +++ /dev/null @@ -1,82 +0,0 @@ -Game Boy Tests Source Code --------------------------- - -Building with wla-dx --------------------- -To assemble a test ROM with wla-dx, use the following commands: - - wla -o source_filename_here.s test.o - wlalink linkfile test.gb - -To assemble as a GBS music file: - - wla -o source_filename_here.s test.o -DBUILD_GBS - wlalink linkfile test.gbs - -Note that some tests might only work when built as a ROM or GBS file, -but not both. - -Some tests might include a ROM/GBS that has all the tests combined. -Building such a multi-test is complex and the necessary files aren't -included. - - -Framework ---------- -Each test is in a single source file, and makes use of several library -source files from common/. This framework provides common services and -reduces code to only that which performs the actual test. Virtually all -tests include "shell.inc" at the beginning, which sets things up and -includes all the appropriate library files. - -The reset handler does minimal GB hardware initialization, clears RAM, -sets up the text console, then runs main. Main can exit by returning or -jumping to "exit" with an error code in A. Exit reports the code then -goes into an infinite loop. If the code is 0, it doesn't do anything, -otherwise it reports the code. Code 1 is reported as "Failed", and the -rest as "Error ". - -The default is to build a ROM. Defining BUILD_GBS will build as an GBS. -The other build types aren't supported due to their complexity. I load -the code into RAM at $C000 since my devcart requires it, and I don't -want the normal ROM to differ in any way from what I've tested. This -also allows easy self-modifying code. - -Several routines are available to print values and text to the console. -Most update a running CRC-32 checksum which can be checked with -check_crc, allowing ALL the output to be checked very easily. If the -checksum doesn't match, it is printed, so you can run the code on a GB -and paste the correct checksum into your code. - - -Macros ------- -Some macros are used to make common operations more convenient. The left -is equivalent to the right: - - Macro Equivalent - ------------------------------------- - lda addr ldh a,(addr-$FF00) - - sta addr ldh (addr-$FF00),a - - wreg addr,data ld a,data - ldh (addr-$FF00),a - - setb ld a,data - ld (addr),a - - setw setb addr+0,data - - for_loop routine,begin,end,step - calls routine with A set to successive values - - loop_n_times routine,count - calls routine with A from 0 to count-1 - - print_str "str" prints string - - --- -Shay Green diff --git a/playing-coffee - Copy/roms/cgb_sound/source/shell.inc b/playing-coffee - Copy/roms/cgb_sound/source/shell.inc deleted file mode 100644 index 0d43faa..0000000 --- a/playing-coffee - Copy/roms/cgb_sound/source/shell.inc +++ /dev/null @@ -1,27 +0,0 @@ -; Included at beginning of all programs -; that use standard shell - -; Get include files from common/ -.incdir "common" - -; Sub-test in a multi-test ROM -.ifdef BUILD_MULTI - .include "build_multi.s" -.else - -; GBS music file -.ifdef BUILD_GBS - .include "build_gbs.s" -.endif - -; Devcart -.ifdef BUILD_DEVCART - .include "build_devcart.s" -.endif - -; GB ROM (default) -.ifndef RUNTIME_INCLUDED - .include "build_rom.s" -.endif - -.endif ; .ifdef BUILD_MULTI diff --git a/playing-coffee - Copy/roms/cpu_instrs.gb b/playing-coffee - Copy/roms/cpu_instrs.gb deleted file mode 100644 index 7b06221..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/cpu_instrs.gb b/playing-coffee - Copy/roms/cpu_instrs/cpu_instrs.gb deleted file mode 100644 index 7b06221..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/cpu_instrs.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/01-special.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/01-special.gb deleted file mode 100644 index ad3e998..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/01-special.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/02-interrupts.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/02-interrupts.gb deleted file mode 100644 index 2089594..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/02-interrupts.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/03-op sp,hl.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/03-op sp,hl.gb deleted file mode 100644 index 50b3cc7..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/03-op sp,hl.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/04-op r,imm.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/04-op r,imm.gb deleted file mode 100644 index 58ca7b8..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/04-op r,imm.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/05-op rp.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/05-op rp.gb deleted file mode 100644 index 1c19d92..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/05-op rp.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/06-ld r,r.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/06-ld r,r.gb deleted file mode 100644 index d497bfd..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/06-ld r,r.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/07-jr,jp,call,ret,rst.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/07-jr,jp,call,ret,rst.gb deleted file mode 100644 index 5c8d20b..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/07-jr,jp,call,ret,rst.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/08-misc instrs.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/08-misc instrs.gb deleted file mode 100644 index 4da139b..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/08-misc instrs.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/09-op r,r.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/09-op r,r.gb deleted file mode 100644 index e30e6ec..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/09-op r,r.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/10-bit ops.gb b/playing-coffee - Copy/roms/cpu_instrs/individual/10-bit ops.gb deleted file mode 100644 index 8988458..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/10-bit ops.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/individual/11-op a,(hl).gb b/playing-coffee - Copy/roms/cpu_instrs/individual/11-op a,(hl).gb deleted file mode 100644 index 0634b7f..0000000 Binary files a/playing-coffee - Copy/roms/cpu_instrs/individual/11-op a,(hl).gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/cpu_instrs/readme.txt b/playing-coffee - Copy/roms/cpu_instrs/readme.txt deleted file mode 100644 index 6f94955..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/readme.txt +++ /dev/null @@ -1,119 +0,0 @@ -Game Boy CPU Instruction Behavior Test --------------------------------------- -This ROM tests the behavior of all CPU instructions except STOP and the -11 illegal opcodes. The tests are fairly thorough, running instructions -with boundary data and verifying both the result and that other -registers are not modified. Instructions which perform the same -operation on different registers are each tested just as thoroughly, in -case an emulator implements each independently. Some sub-tests take half -minute to complete. - -Failed instructions are listed as - - [CB] opcode - -Some errors cannot of course be diagnosed properly, since the test -framework itself relies on basic instruction behavior being correct. - - -Internal operation ------------------- -The main tests use a framework that runs each instruction in a loop, -varying the register values on input and examining them on output. -Rather than keep a table of correct values, it simply calculates a -CRC-32 checksum of all the output, then compares this with the correct -value. Instructions are divided into several groups, each with a -different set of input values suited for their behavior; for example, -the bit test instructions are fed $01, $02, $04 ... $40, $80, to ensure -each bit is handled properly, while the arithmetic instructions are fed -$01, $0F, $10, $7F, $FF, to exercise carry and half-carry. A few -instructions require a custom test due to their uniqueness. - - -Multi-ROM ---------- -In the main directory is a single ROM which runs all the tests. It -prints a test's number, runs the test, then "ok" if it passes, otherwise -a failure code. Once all tests have completed it either reports that all -tests passed, or prints the number of failed tests. Finally, it makes -several beeps. If a test fails, it can be run on its own by finding the -corresponding ROM in individual/. - -Ths compact format on screen is to avoid having the results scroll off -the top, so the test can be started and allowed to run without having to -constantly monitor the display. - -Currently there is no well-defined way for an emulator test rig to -programatically find the result of the test; contact me if you're trying -to do completely automated testing of your emulator. One simple approach -is to take a screenshot after all tests have run, or even just a -checksum of one, and compare this with a previous run. - - -Failure codes -------------- -Failed tests may print a failure code, and also short description of the -problem. For more information about a failure code, look in the -corresponding source file in source/; the point in the code where -"set_test n" occurs is where that failure code will be generated. -Failure code 1 is a general failure of the test; any further information -will be printed. - -Note that once a sub-test fails, no further tests for that file are run. - - -Console output --------------- -Information is printed on screen in a way that needs only minimum LCD -support, and won't hang if LCD output isn't supported at all. -Specifically, while polling LY to wait for vblank, it will time out if -it takes too long, so LY always reading back as the same value won't -hang the test. It's also OK if scrolling isn't supported; in this case, -text will appear starting at the top of the screen. - -Everything printed on screen is also sent to the game link port by -writing the character to SB, then writing $81 to SC. This is useful for -tests which print lots of information that scrolls off screen. - - -Source code ------------ -Source code is included for all tests, in source/. It can be used to -build the individual test ROMs. Code for the multi test isn't included -due to the complexity of putting everything together. - -Code is written for the wla-dx assembler. To assemble a particular test, -execute - - wla -o "source_filename.s" test.o - wlalink linkfile test.gb - -Test code uses a common shell framework contained in common/. - - -Internal framework operation ----------------------------- -Tests use a common framework for setting things up, reporting results, -and ending. All files first include "shell.inc", which sets up the ROM -header and shell code, and includes other commonly-used modules. - -One oddity is that test code is first copied to internal RAM at $D000, -then executed there. This allows self-modification, and ensures the code -is executed the same way it is on my devcart, which doesn't have a -rewritable ROM as most do. - -Some macros are used to simplify common tasks: - - Macro Behavior - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wreg addr,data Writes data to addr using LDH - lda addr Loads byte from addr into A using LDH - sta addr Stores A at addr using LDH - delay n Delays n cycles, where NOP = 1 cycle - delay_msec n Delays n milliseconds - set_test n,"Cause" Sets failure code and optional string - -Routines and macros are documented where they are defined. - --- -Shay Green diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/01-special.s b/playing-coffee - Copy/roms/cpu_instrs/source/01-special.s deleted file mode 100644 index 776d685..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/01-special.s +++ /dev/null @@ -1,78 +0,0 @@ -; Tests instructions that don't fit template - -.include "shell.inc" - -main: - set_test 2,"JR negative" - ld a,0 - jp jr_neg - inc a -- inc a - inc a - cp 2 - jp nz,test_failed - jp + -jr_neg: - jr - -+ - - set_test 3,"JR positive" - ld a,0 - jr + - inc a -+ inc a - inc a - cp 2 - jp nz,test_failed - - - set_test 4,"LD PC,HL" - ld hl,+ - ld a,0 - ld pc,hl - inc a -+ inc a - inc a - cp 2 - jp nz,test_failed - - - set_test 5,"POP AF" - ld bc,$1200 -- push bc - pop af - push af - pop de - ld a,c - and $F0 - cp e - jp nz,test_failed - inc b - inc c - jr nz,- - - - set_test 6,"DAA" - ; Test all combinations of A and flags (256*16 total) - ld de,0 -- push de - pop af - daa - - push af - call update_crc - pop hl - ld a,l - call update_crc - - inc d - jr nz,- - - ld a,e - add $10 - ld e,a - jr nz,- - - check_crc $6A9F8D8A - - jp tests_passed diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/02-interrupts.s b/playing-coffee - Copy/roms/cpu_instrs/source/02-interrupts.s deleted file mode 100644 index de18b34..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/02-interrupts.s +++ /dev/null @@ -1,73 +0,0 @@ -; Tests DI, EI, and HALT (STOP proved untestable) - -.include "shell.inc" - -main: - wreg IE,$04 - - set_test 2,"EI" - ei - ld bc,0 - push bc - pop bc - inc b - wreg IF,$04 -interrupt_addr: - dec b - jp nz,test_failed - ld hl,sp-2 - ldi a,(hl) - cp interrupt_addr - jp nz,test_failed - lda IF - and $04 - jp nz,test_failed - - set_test 3,"DI" - di - ld bc,0 - push bc - pop bc - wreg IF,$04 - ld hl,sp-2 - ldi a,(hl) - or (hl) - jp nz,test_failed - lda IF - and $04 - jp z,test_failed - - set_test 4,"Timer doesn't work" - wreg TAC,$05 - wreg TIMA,0 - wreg IF,0 - delay 500 - lda IF - delay 500 - and $04 - jp nz,test_failed - delay 500 - lda IF - and $04 - jp z,test_failed - pop af - - set_test 5,"HALT" - wreg TAC,$05 - wreg TIMA,0 - wreg IF,0 - halt ; timer interrupt will exit halt - nop ; avoids DMG bug - lda IF - and $04 - jp z,test_failed - - jp tests_passed - -.bank 0 slot 0 -.org $50 - inc a - ret diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/03-op sp,hl.s b/playing-coffee - Copy/roms/cpu_instrs/source/03-op sp,hl.s deleted file mode 100644 index 9531d51..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/03-op sp,hl.s +++ /dev/null @@ -1,102 +0,0 @@ -; Tests SP/HL instructions - -;.define PRINT_CHECKSUMS 1 -.include "shell.inc" -.include "instr_test.s" - -instrs: - .byte $33,0,0 ; INC SP - .byte $3B,0,0 ; DEC SP - .byte $39,0,0 ; ADD HL,SP - .byte $F9,0,0 ; LD SP,HL - .byte $E8,$01,0 ; ADD SP,1 - .byte $E8,$FF,0 ; ADD SP,-1 - .byte $F8,$01,0 ; LD HL,SP+1 - .byte $F8,$FF,0 ; LD HL,SP-1 -instrs_end: - -test_instr: - ; C = flags register - ld c,$00 - call test - ld c,$F0 - call test - ret - -test: - ; Go through each value for HL - ld hl,values -hl_loop: - ld e,(hl) - inc hl - ld d,(hl) - inc hl - push hl - - ; Go through each value for SP - ld hl,values -values_loop: - push bc - push de - push hl - - push bc - pop af - - ; Switch stack - ld (temp),sp - ld a,(hl+) - ld h,(hl) - ld l,a -; call print_regs - ld sp,hl - - ; Set registers - ld h,d - ld l,e - ld a,$12 - ld bc,$5691 - ld de,$9ABC - - jp instr -instr_done: - ; Save new SP and switch to yet another stack - ld (temp+2),sp - ld sp,$DF70 - - call checksum_af_bc_de_hl - - ; Checksum SP - ld a,(temp+2) - call update_crc_fast - ld a,(temp+3) - call update_crc_fast - - ldsp temp - - pop hl - pop de - pop bc - inc hl - inc hl - ld a,l - cp taken ; JP NZ,taken - .byte $C3,taken ; JP taken - .byte $CA,taken ; JP Z,taken - .byte $D2,taken ; JP NC,taken - .byte $DA,taken ; JP C,taken - - .byte $C4,taken ; CALL NZ,taken - .byte $CC,taken ; CALL Z,taken - .byte $CD,taken ; CALL taken - .byte $D4,taken ; CALL NC,taken - .byte $DC,taken ; CALL C,taken - - ; RET cond - ; INC A - .byte $C0,$3C,0 ; RET NZ - .byte $C8,$3C,0 ; RET Z - .byte $C9,$3C,0 ; RET - .byte $D0,$3C,0 ; RET NC - .byte $D8,$3C,0 ; RET C - .byte $D9,$3C,0 ; RETI - - ; RST - ; can only easily test this one on devcart - .byte $C7,0,0 ; RST $00 -.ifndef BUILD_DEVCART - .byte $CF,0,0 ; RST $08 - .byte $D7,0,0 ; RST $10 - .byte $DF,0,0 ; RST $18 - .byte $E7,0,0 ; RST $20 - .byte $EF,0,0 ; RST $28 - .byte $F7,0,0 ; RST $30 - .byte $FF,0,0 ; RST $38 -.endif - -instrs_end: - -test_instr: - wreg IE,0 ; disable interrupts, since RETI does EI - - ; Go through all 16 combinations of flags - ld bc,$1200 -- - ; Fill 4 bytes of new stack - ld a,$12 - ld ($DF80-2),a - ld a,$34 - ld ($DF80-3),a - ld a,$56 - ld ($DF80-4),a - ld a,$78 - ld ($DF80-5),a - - ; Set AF - push bc - pop af - - ; Switch to new stack - ld (temp),sp - ld sp,$DF80 - - ; Set return address - ld de,instr+3 - push de - - jp instr -instr_done: - inc a -taken: - di ; RETI enables interrupts - - ; Save new SP and switch to yet another stack - ld (temp+2),sp - ld sp,$DF70 - - ; Checksum A and SP - call update_crc_fast - ld a,(temp+2) - call update_crc_fast - ld a,(temp+3) - call update_crc_fast - - ; Checksum 4 bytes of stack - ld a,($DF80-2) - call update_crc_fast - ld a,($DF80-3) - call update_crc_fast - ld a,($DF80-4) - call update_crc_fast - ld a,($DF80-5) - call update_crc_fast - - ldsp temp - - ld a,c - add $10 - ld c,a - jr nz,- - - ret - -checksums: - .byte $EC,$A4,$94,$79,$C4,$00,$96,$2C,$C4,$64,$90,$33,$77,$C7,$0A,$D4 - .byte $77,$A3,$0C,$CB,$79,$E7,$7E,$AE,$DA,$DC,$03,$F7,$4F,$9F,$E9,$20 - .byte $72,$12,$DA,$01,$44,$6A,$4D,$8F,$D1,$79,$30,$4C,$AA,$37,$F2,$6A - .byte $97,$EA,$56,$5F,$32,$28,$C7,$D1,$49,$66,$05,$F7,$80,$0F,$BA,$8E - .byte $41,$E2,$A4,$9A,$2D,$2D,$8C,$72,$A5,$13,$76,$A8,$64,$FE,$68,$BC - .byte $2D,$2D,$8C,$72,$50,$96,$24,$27,$50,$96,$24,$27,$50,$96,$24,$27 - .byte $50,$96,$24,$27,$50,$96,$24,$27,$50,$96,$24,$27,$50,$96,$24,$27 - .byte $50,$96,$24,$27 - -.include "multi_custom.s" diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/08-misc instrs.s b/playing-coffee - Copy/roms/cpu_instrs/source/08-misc instrs.s deleted file mode 100644 index 5c11c8e..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/08-misc instrs.s +++ /dev/null @@ -1,110 +0,0 @@ -; Tests miscellaneous instructions - -;.define PRINT_CHECKSUMS 1 -.include "shell.inc" -.include "instr_test.s" - -instrs: - .byte $F0,$91,0 ; LDH A,($91) - .byte $E0,$91,0 ; LDH ($91),A - .byte $F2,$00,0 ; LDH A,(C) - .byte $E2,$00,0 ; LDH (C),A - .byte $FA,$91,$FF ; LD A,($FF91) - .byte $EA,$91,$FF ; LD ($FF91),A - .byte $08,$91,$FF ; LD ($FF91),SP - .byte $01,$23,$01 ; LD BC,$0123 - .byte $11,$23,$01 ; LD DE,$0123 - .byte $21,$23,$01 ; LD HL,$0123 - .byte $31,$23,$01 ; LD SP,$0123 - .byte $F5,0,0 ; PUSH AF - .byte $C5,0,0 ; PUSH BC - .byte $D5,0,0 ; PUSH DE - .byte $E5,0,0 ; PUSH HL - .byte $F1,0,0 ; POP AF - .byte $C1,0,0 ; POP BC - .byte $D1,0,0 ; POP DE - .byte $E1,0,0 ; POP HL -instrs_end: - -test_instr: - ; C = flags register - ld c,$00 - call test - ld c,$10 - call test - ld c,$E0 - call test - ld c,$F0 - call test - ret - -test: - ; Fill RAM - ld a,$FE - ld ($FF90),a - ld a,$DC - ld ($FF91),a - ld a,$BA - ld ($FF92),a - - ; Fill stack - ld a,$13 - ld ($DF80),a - ld a,$57 - ld ($DF80-1),a - ld a,$9B - ld ($DF80-2),a - ld a,$DF - ld ($DF80-3),a - - ; Set registers - ld b,$12 - push bc - ld bc,$5691 - ld de,$9ABC - ld hl,$DEF0 - pop af - - ; Switch stack - ld (temp),sp - ld sp,$DF80-2 - - jp instr -instr_done: - ; Save new SP and switch to another stack - ld (temp+2),sp - ld sp,$DF70 - - call checksum_af_bc_de_hl - - ; Checksum SP - ld a,(temp+2) - call update_crc_fast - ld a,(temp+3) - call update_crc_fast - - ; Checksum RAM - ld a,($FF90) - call update_crc_fast - ld a,($FF91) - call update_crc_fast - ld a,($FF92) - call update_crc_fast - - ; Checksum stack - ld a,($DF80) - call update_crc_fast - ld a,($DF80-1) - call update_crc_fast - ld a,($DF80-2) - call update_crc_fast - ld a,($DF80-3) - call update_crc_fast - - ; Restore SP - ldsp temp - - ret - -checksums: - .byte $4D,$FF,$15,$97,$6D,$A7,$35,$65,$4D,$FF,$15,$97,$6D,$A7,$35,$65,$4D,$FF,$15,$97,$6D,$A7,$35,$65,$AD,$FA,$5E,$41,$D0,$78,$79,$C1,$AF,$66,$99,$34,$0D,$E1,$97,$99,$6F,$D0,$6F,$5D,$C3,$1F,$A3,$8A,$C2,$F1,$9C,$F3,$C1,$C3,$DC,$78,$C0,$2D,$E3,$01,$8F,$C4,$0F,$44,$95,$22,$6A,$39,$61,$C5,$AB,$55,$FB,$DF,$2C,$52, diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/09-op r,r.s b/playing-coffee - Copy/roms/cpu_instrs/source/09-op r,r.s deleted file mode 100644 index 432c4e7..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/09-op r,r.s +++ /dev/null @@ -1,269 +0,0 @@ -; Tests most register instructions. -; Takes 10 seconds. - -;.define PRINT_CHECKSUMS 1 -.include "shell.inc" -.include "instr_test.s" - -instrs: - .byte $00,0,0 ; NOP - .byte $2F,0,0 ; CPL - .byte $37,0,0 ; SCF - .byte $3F,0,0 ; CCF - - .byte $B0,0,0 ; OR B - .byte $B1,0,0 ; OR C - .byte $B2,0,0 ; OR D - .byte $B3,0,0 ; OR E - .byte $B4,0,0 ; OR H - .byte $B5,0,0 ; OR L - .byte $B7,0,0 ; OR A - - .byte $B8,0,0 ; CP B - .byte $B9,0,0 ; CP C - .byte $BA,0,0 ; CP D - .byte $BB,0,0 ; CP E - .byte $BC,0,0 ; CP H - .byte $BD,0,0 ; CP L - .byte $BF,0,0 ; CP A - - .byte $80,0,0 ; ADD B - .byte $81,0,0 ; ADD C - .byte $82,0,0 ; ADD D - .byte $83,0,0 ; ADD E - .byte $84,0,0 ; ADD H - .byte $85,0,0 ; ADD L - .byte $87,0,0 ; ADD A - - .byte $88,0,0 ; ADC B - .byte $89,0,0 ; ADC C - .byte $8A,0,0 ; ADC D - .byte $8B,0,0 ; ADC E - .byte $8C,0,0 ; ADC H - .byte $8D,0,0 ; ADC L - .byte $8F,0,0 ; ADC A - - .byte $90,0,0 ; SUB B - .byte $91,0,0 ; SUB C - .byte $92,0,0 ; SUB D - .byte $93,0,0 ; SUB E - .byte $94,0,0 ; SUB H - .byte $95,0,0 ; SUB L - .byte $97,0,0 ; SUB A - - .byte $98,0,0 ; SBC B - .byte $99,0,0 ; SBC C - .byte $9A,0,0 ; SBC D - .byte $9B,0,0 ; SBC E - .byte $9C,0,0 ; SBC H - .byte $9D,0,0 ; SBC L - .byte $9F,0,0 ; SBC A - - .byte $A0,0,0 ; AND B - .byte $A1,0,0 ; AND C - .byte $A2,0,0 ; AND D - .byte $A3,0,0 ; AND E - .byte $A4,0,0 ; AND H - .byte $A5,0,0 ; AND L - .byte $A7,0,0 ; AND A - - .byte $A8,0,0 ; XOR B - .byte $A9,0,0 ; XOR C - .byte $AA,0,0 ; XOR D - .byte $AB,0,0 ; XOR E - .byte $AC,0,0 ; XOR H - .byte $AD,0,0 ; XOR L - .byte $AF,0,0 ; XOR A - - .byte $05,0,0 ; DEC B - .byte $0D,0,0 ; DEC C - .byte $15,0,0 ; DEC D - .byte $1D,0,0 ; DEC E - .byte $25,0,0 ; DEC H - .byte $2D,0,0 ; DEC L - .byte $3D,0,0 ; DEC A - - .byte $04,0,0 ; INC B - .byte $0C,0,0 ; INC C - .byte $14,0,0 ; INC D - .byte $1C,0,0 ; INC E - .byte $24,0,0 ; INC H - .byte $2C,0,0 ; INC L - .byte $3C,0,0 ; INC A - - .byte $07,0,0 ; RLCA - .byte $17,0,0 ; RLA - .byte $0F,0,0 ; RRCA - .byte $1F,0,0 ; RRA - - .byte $CB,$00,0 ; RLC B - .byte $CB,$01,0 ; RLC C - .byte $CB,$02,0 ; RLC D - .byte $CB,$03,0 ; RLC E - .byte $CB,$04,0 ; RLC H - .byte $CB,$05,0 ; RLC L - .byte $CB,$07,0 ; RLC A - - .byte $CB,$08,0 ; RRC B - .byte $CB,$09,0 ; RRC C - .byte $CB,$0A,0 ; RRC D - .byte $CB,$0B,0 ; RRC E - .byte $CB,$0C,0 ; RRC H - .byte $CB,$0D,0 ; RRC L - .byte $CB,$0F,0 ; RRC A - - .byte $CB,$10,0 ; RL B - .byte $CB,$11,0 ; RL C - .byte $CB,$12,0 ; RL D - .byte $CB,$13,0 ; RL E - .byte $CB,$14,0 ; RL H - .byte $CB,$15,0 ; RL L - .byte $CB,$17,0 ; RL A - - .byte $CB,$18,0 ; RR B - .byte $CB,$19,0 ; RR C - .byte $CB,$1A,0 ; RR D - .byte $CB,$1B,0 ; RR E - .byte $CB,$1C,0 ; RR H - .byte $CB,$1D,0 ; RR L - .byte $CB,$1F,0 ; RR A - - .byte $CB,$20,0 ; SLA B - .byte $CB,$21,0 ; SLA C - .byte $CB,$22,0 ; SLA D - .byte $CB,$23,0 ; SLA E - .byte $CB,$24,0 ; SLA H - .byte $CB,$25,0 ; SLA L - .byte $CB,$27,0 ; SLA A - - .byte $CB,$28,0 ; SRA B - .byte $CB,$29,0 ; SRA C - .byte $CB,$2A,0 ; SRA D - .byte $CB,$2B,0 ; SRA E - .byte $CB,$2C,0 ; SRA H - .byte $CB,$2D,0 ; SRA L - .byte $CB,$2F,0 ; SRA A - - .byte $CB,$30,0 ; SWAP B - .byte $CB,$31,0 ; SWAP C - .byte $CB,$32,0 ; SWAP D - .byte $CB,$33,0 ; SWAP E - .byte $CB,$34,0 ; SWAP H - .byte $CB,$35,0 ; SWAP L - .byte $CB,$37,0 ; SWAP A - - .byte $CB,$38,0 ; SRL B - .byte $CB,$39,0 ; SRL C - .byte $CB,$3A,0 ; SRL D - .byte $CB,$3B,0 ; SRL E - .byte $CB,$3C,0 ; SRL H - .byte $CB,$3D,0 ; SRL L - .byte $CB,$3F,0 ; SRL A -instrs_end: - -test_instr: - ld c,$00 - call test - ld c,$F0 - call test - ret - -test: - ; Go through each value for A - ld hl,values -a_loop: - ld b,(hl) - push hl - - ; Go through each value for other registers - ld hl,values -values_loop: - push bc - push hl - - push bc - - ; BC - ld a,(hl+) - ld b,a - ld a,(hl+) - ld c,a - - ; HL - ld a,(hl+) - ld d,a - ld a,(hl+) - ld e,a - push de - - ; DE - ld a,(hl+) - ld d,a - ld a,(hl+) - ld e,a - - pop hl - pop af - -; call print_regs - jp instr -instr_done: - - ; Checksum registers - call checksum_af_bc_de_hl - - pop hl - pop bc - inc hl - ld a,l - cp checksums - ld (next_checksum+1),a - ret - -; Compares current checksum with next checksum in -; list. Z if they match, NZ if not. -; Preserved: BC, DE, HL -checksums_compare: -.ifdef PRINT_CHECKSUMS - lda checksum+3 - push af - lda checksum+2 - push af - lda checksum+1 - push af - lda checksum+0 - push af - - ld a,(next_checksum) - inc a - ld (next_checksum),a - sub BGMAP0) >> 2 - add hl,hl - add hl,hl - - ; Copy line - ld de,console_buf + console_width -- dec e - ld a,(de) - ldi (hl),a - ld a,e - cp checksum - ldi (hl),a - ld (hl),d - inc l - ld (hl),c - inc l - ld (hl),b - - pop hl - pop de - pop bc - pop af - ret diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/crc_fast.s b/playing-coffee - Copy/roms/cpu_instrs/source/common/crc_fast.s deleted file mode 100644 index d1088b0..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/crc_fast.s +++ /dev/null @@ -1,88 +0,0 @@ -; Fast table-based CRC-32 - -.define crc_tables (bss+$FF)&$FF00 ; 256-byte aligned -.redefine bss crc_tables+$400 - - -; Initializes fast CRC tables and resets checksum. -; Time: 47 msec -init_crc_fast: - ld l,0 -@next: - xor a - ld c,a - ld d,a - ld e,l - - ld h,8 -- rra - rr c - rr d - rr e - jr nc,+ - xor $ED - ld b,a - ld a,c - xor $B8 - ld c,a - ld a,d - xor $83 - ld d,a - ld a,e - xor $20 - ld e,a - ld a,b - -+ dec h - jr nz,- - - ld h,>crc_tables - ld (hl),e - inc h - ld (hl),d - inc h - ld (hl),c - inc h - ld (hl),a - - inc l - jr nz,@next - - jp init_crc - - -; Faster version of update_crc -; Preserved: BC, DE -; Time: 50 cycles (including CALL) -update_crc_fast: - -; Fastest inline macro version of update_crc_fast -; Time: 40 cycles -; Size: 28 bytes -.macro update_crc_fast - ld l,a ; 1 - lda checksum ; 3 - xor l ; 1 - ld l,a ; 1 - ld h,>crc_tables ; 2 - - lda checksum+1 ; 3 - xor (hl) ; 2 - inc h ; 1 - sta checksum ; 3 - - lda checksum+2 ; 3 - xor (hl) ; 2 - inc h ; 1 - sta checksum+1 ; 3 - - lda checksum+3 ; 3 - xor (hl) ; 2 - inc h ; 1 - sta checksum+2 ; 3 - - ld a,(hl) ; 2 - sta checksum+3 ; 3 -.endm - update_crc_fast - ret diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/delay.s b/playing-coffee - Copy/roms/cpu_instrs/source/common/delay.s deleted file mode 100644 index 65eb9c0..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/delay.s +++ /dev/null @@ -1,220 +0,0 @@ -; Delays in cycles, milliseconds, etc. - -; All routines are re-entrant (no global data). Routines never -; touch BC, DE, or HL registers. These ASSUME CPU is at normal -; speed. If running at double speed, msec/usec delays are half advertised. - -; Delays n cycles, from 0 to 16777215 -; Preserved: AF, BC, DE, HL -.macro delay ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 16777215 - .printt "Delay must be < 16777216" - .fail - .endif - delay_ n&$FFFF, n>>16 -.endm - -; Delays n clocks, from 0 to 16777216*4. Must be multiple of 4. -; Preserved: AF, BC, DE, HL -.macro delay_clocks ARGS n - .if n # 4 != 0 - .printt "Delay must be a multiple of 4" - .fail - .endif - delay_ (n/4)&$FFFF,(n/4)>>16 -.endm - -; Delays n microseconds (1/1000000 second) -; n can range from 0 to 4000 usec. -; Preserved: AF, BC, DE, HL -.macro delay_usec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 4000 - .printt "Delay must be <= 4000 usec" - .fail - .endif - delay_ ((n * 1048576 + 500000) / 1000000)&$FFFF,((n * 1048576 + 500000) / 1000000)>>16 -.endm - -; Delays n milliseconds (1/1000 second) -; n can range from 0 to 10000 msec. -; Preserved: AF, BC, DE, HL -.macro delay_msec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 10000 - .printt "Delay must be <= 10000 msec" - .fail - .endif - delay_ ((n * 1048576 + 500) / 1000)&$FFFF, ((n * 1048576 + 500) / 1000)>>16 -.endm - - ; All the low/high quantities are to deal wla-dx's asinine - ; restriction full expressions must evaluate to a 16-bit - ; value. If the author ever rectifies this, all "high" - ; arguments can be treated as zero and removed. Better yet, - ; I'll just find an assembler that didn't crawl out of - ; the sewer (this is one of too many bugs I've wasted - ; hours working around). - - .define max_short_delay 28 - - .macro delay_long_ ARGS n, high - ; 0+ to avoid assembler treating as memory read - ld a,0+(((high<<16)+n) - 11) >> 16 - call delay_65536a_9_cycles_ - delay_nosave_ (((high<<16)+n) - 11)&$FFFF, 0 - .endm - - ; Doesn't save AF, allowing minimization of AF save/restore - .macro delay_nosave_ ARGS n, high - ; 65536+11 = maximum delay using delay_256a_9_cycles_ - ; 255+22 = maximum delay using delay_a_20_cycles - ; 22 = minimum delay using delay_a_20_cycles - .if high > 1 - delay_long_ n, high - .else - .if high*n > 11 - delay_long_ n, high - .else - .if (high*(255+22+1))|n > 255+22 - ld a,>(((high<<16)+n) - 11) - call delay_256a_9_cycles_ - delay_nosave_ <(((high<<16)+n) - 11), 0 - .else - .if n >= 22 - ld a,n - 22 - call delay_a_20_cycles - .else - delay_short_ n - .endif - .endif - .endif - .endif - .endm - - .macro delay_ ARGS low, high - .if (high*(max_short_delay+1))|low > max_short_delay - push af - delay_nosave_ ((high<<16)+low - 7)&$FFFF, ((high<<16)+low - 7)>>16 - pop af - .else - delay_short_ low - .endif - .endm - - -; Delays A cycles + overhead -; Preserved: BC, DE, HL -; Time: A+20 cycles (including CALL) -delay_a_20_cycles: -- sub 5 ; 2 - jr nc,- ;3/2 do multiples of 5 - rra ; 1 - jr nc,+ ;3/2 bit 0 -+ adc 1 ; 2 - ret nc ;5/2 -1: 0 cycles - ret z ;5/2 0: 2 cycles - nop ; 1 1: 4 cycles - ret ; 4 (thanks to dclxvi for original algorithm) - -; Delays A*256 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*256+12 cycles (including CALL) -delay_256a_12_cycles: - or a ; 1 - ret z ; 5/2 -delay_256a_9_cycles_: -- delay 256-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays A*65536 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*65536+12 cycles (including CALL) -delay_65536a_12_cycles: - or a ; 1 - ret z ;5/2 -delay_65536a_9_cycles_: -- delay 65536-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays H*256+L cycles + overhead -; Preserved: AF, BC, DE, HL -; Time: H*256+L+51 cycles -delay_hl_51_cycles: - push af - ld a,h - call delay_256a_12_cycles - ld a,l - call delay_a_20_cycles - pop af - ret - - ; delay_short_ macro calls into these - .ds max_short_delay-10,$00 ; NOP repeated several times -delay_unrolled_: - ret - -.macro delay_short_ ARGS n - .if n < 0 - .fail - .endif - .if n > max_short_delay - .fail - .endif - - .if n == 1 - nop - .endif - .if n == 2 - nop - nop - .endif - .if n == 3 - .byte $18,$00 ; JR +0 - .endif - .if n == 4 - .byte $18,$00 ; JR +0 - nop - .endif - .if n == 5 - .byte $18,$00 ; JR +0 - nop - nop - .endif - .if n == 6 - .byte $18,$00 ; JR +0 - .byte $18,$00 ; JR +0 - .endif - .if n == 7 - push af - pop af - .endif - .if n == 8 - push af - pop af - nop - .endif - .if n == 9 - push af - pop af - nop - nop - .endif - .if n >= 10 - call delay_unrolled_ + 10 - n - .endif -.endm diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/gb.inc b/playing-coffee - Copy/roms/cpu_instrs/source/common/gb.inc deleted file mode 100644 index 31bbf14..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/gb.inc +++ /dev/null @@ -1,64 +0,0 @@ -; Game Boy hardware addresses - -; Memory -.define VRAM $8000 ; video memory -.define TILES $8000 ; tile images -.define BGMAP0 $9800 ; first 32x32 tilemap -.define BGMAP1 $9C00 ; second 32x32 tilemap -.define WRAM $C000 ; internal memory -.define OAM $FE00 ; sprite memory -.define HRAM $FF80 ; fast memory for LDH - -.define P1 $FF00 - -; Game link I/O -.define SB $FF01 -.define SC $FF02 - -; Interrupts -.define DIV $FF04 -.define TIMA $FF05 -.define TMA $FF06 -.define TAC $FF07 -.define IF $FF0F -.define IE $FFFF - -; LCD registers -.define LCDC $FF40 ; control -.define STAT $FF41 ; status -.define SCY $FF42 ; scroll Y -.define SCX $FF43 ; scroll X -.define LY $FF44 ; current Y being rendered -.define BGP $FF47 - -.define KEY1 $FF4D ; for changing CPU speed -.define VBK $FF4F - -; Sound registers -.define NR10 $FF10 -.define NR11 $FF11 -.define NR12 $FF12 -.define NR13 $FF13 -.define NR14 $FF14 - -.define NR21 $FF16 -.define NR22 $FF17 -.define NR23 $FF18 -.define NR24 $FF19 - -.define NR30 $FF1A -.define NR31 $FF1B -.define NR32 $FF1C -.define NR33 $FF1D -.define NR34 $FF1E - -.define NR41 $FF20 -.define NR42 $FF21 -.define NR43 $FF22 -.define NR44 $FF23 - -.define NR50 $FF24 -.define NR51 $FF25 -.define NR52 $FF26 - -.define WAVE $FF30 diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/instr_test.s b/playing-coffee - Copy/roms/cpu_instrs/source/common/instr_test.s deleted file mode 100644 index 5ed6e2c..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/instr_test.s +++ /dev/null @@ -1,105 +0,0 @@ -; Framework for CPU instruction tests - -; Calls test_instr with each instruction copied -; to instr, with a JP instr_done after it. -; Verifies checksum after testing instruction and -; prints opcode if it's wrong. - -.include "checksums.s" -.include "cpu_speed.s" -.include "apu.s" -.include "crc_fast.s" - -.define instr $DEF8 -.define rp_temp (instr-4) - -.define temp bss - -; Sets SP to word at addr -; Preserved: BC, DE -.macro ldsp ; addr - ld a,(\1) - ld l,a - ld a,((\1)+1) - ld h,a - ld sp,hl -.endm - -main: - call cpu_fast - call init_crc_fast - call checksums_init - set_test 0 - - ld hl,instrs -- ; Copy instruction - ld a,(hl+) - ld (instr),a - ld a,(hl+) - ld (instr+1),a - ld a,(hl+) - ld (instr+2),a - push hl - - ; Put JP instr_done after it - ld a,$C3 - ld (instr+3),a - ld a,instr_done - ld (instr+5),a - - call reset_crc - call test_instr - - call checksums_compare - jr z,passed - - set_test 1 - ld a,(instr) - call print_a - cp $CB - jr nz,+ - ld a,(instr+1) - call print_a -+ - -passed: - ; Next instruction - pop hl - ld a,l - cp instrs_end - jr nz,- - - jp tests_done - - -; Updates checksum with AF, BC, DE, and HL -checksum_af_bc_de_hl: - push hl - - push af - update_crc_fast - pop hl - ld a,l - update_crc_fast - - ld a,b - update_crc_fast - ld a,c - update_crc_fast - - ld a,d - update_crc_fast - ld a,e - update_crc_fast - - pop de - ld a,d - update_crc_fast - ld a,e - update_crc_fast - ret diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/macros.inc b/playing-coffee - Copy/roms/cpu_instrs/source/common/macros.inc deleted file mode 100644 index c413bd5..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/macros.inc +++ /dev/null @@ -1,73 +0,0 @@ -; General macros - -; Reads A from addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 3 cycles -.macro lda ARGS addr - ldh a,(addr - $FF00) -.endm - -; Writes A to addr, from $FF00 to $FFFF -; Preserved: AF, BC, DE, HL -; Time: 3 cycles -.macro sta ARGS addr - ldh (addr - $FF00),a -.endm - -; Writes immediate data to addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 5 cycles -.macro wreg ARGS addr, data - ld a,data - sta addr -.endm - -; Calls routine multiple times, with A having the -; value 'start' the first time, 'start+step' the -; second time, up to 'end' for the last time. -; Preserved: BC, DE, HL -.macro for_loop ; routine,start,end,step - ld a,\2 - -for_loop\@: - push af - call \1 - pop af - - add \4 - cp <(\3 + \4) - jr nz,for_loop\@ -.endm - -; Calls routine n times. The value of A in the routine -; counts from 0 to n-1. -; Preserved: BC, DE, HL -.macro loop_n_times ; routine,n - for_loop \1,0,\2 - 1,+1 -.endm - -; Same as for_loop, but counts with 16-bit value in BC. -; Preserved: DE, HL -.macro for_loop16 ; routine,start,end,step - ld bc,\2 - -for_loop16\@: - push bc - call \1 - pop bc - - ld a,c - add <\4 - ld c,a - - ld a,b - adc >\4 - ld b,a - - cp >(\3+\4) - jr nz,for_loop16\@ - - ld a,c - cp <(\3+\4) - jr nz,for_loop16\@ -.endm diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/multi_custom.s b/playing-coffee - Copy/roms/cpu_instrs/source/common/multi_custom.s deleted file mode 100644 index 4dbae9d..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/multi_custom.s +++ /dev/null @@ -1,38 +0,0 @@ -; RST handlers -.bank 0 slot 0 -.org 0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret - .ds 6,0 - inc a - ret diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/numbers.s b/playing-coffee - Copy/roms/cpu_instrs/source/common/numbers.s deleted file mode 100644 index 6d6faf8..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/numbers.s +++ /dev/null @@ -1,177 +0,0 @@ -; Printing of numeric values - -; Prints value of indicated register/pair -; as 2/4 hex digits, followed by a space. -; Updates checksum with printed values. -; Preserved: AF, BC, DE, HL - -print_regs: - call print_af - call print_bc - call print_de - call print_hl - call print_newline - ret - -print_a: - push af -print_a_: - call print_hex - ld a,' ' - call print_char_nocrc - pop af - ret - -print_af: - push af - call print_hex - pop af -print_f: - push bc - push af - pop bc - call print_c - pop bc - ret - -print_b: - push af - ld a,b - jr print_a_ - -print_c: - push af - ld a,c - jr print_a_ - -print_d: - push af - ld a,d - jr print_a_ - -print_e: - push af - ld a,e - jr print_a_ - -print_h: - push af - ld a,h - jr print_a_ - -print_l: - push af - ld a,l - jr print_a_ - -print_bc: - push af - push bc -print_bc_: - ld a,b - call print_hex - ld a,c - pop bc - jr print_a_ - -print_de: - push af - push bc - ld b,d - ld c,e - jr print_bc_ - -print_hl: - push af - push bc - ld b,h - ld c,l - jr print_bc_ - - -; Prints A as two hex chars and updates checksum -; Preserved: BC, DE, HL -print_hex: - call update_crc -print_hex_nocrc: - push af - swap a - call + - pop af - -+ and $0F - cp 10 - jr c,+ - add 7 -+ add '0' - jp print_char_nocrc - - -; Prints char_nz if Z flag is clear, -; char_z if Z flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nz ARGS char_nz, char_z - push af - ld a,char_nz - jr nz,print_nz\@ - ld a,char_z -print_nz\@: - call print_char - pop af -.endm - - -; Prints char_nc if C flag is clear, -; char_c if C flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nc ARGS char_nc, char_c - push af - ld a,char_nc - jr nz,print_nc\@ - ld a,char_c -print_nc\@: - call print_char - pop af -.endm - - -; Prints A as 2 decimal digits -; Preserved: AF, BC, DE, HL -print_dec2: - push af - push bc - jr + - - -; Prints A as 1-3 digit decimal value -; Preserved: AF, BC, DE, HL -print_dec: - push af - push bc - - cp 10 - jr c,++ - ld c,100 - cp c - call nc,@digit -+ ld c,10 - call @digit -++ add '0' - call print_char - - pop bc - pop af - ret - -@digit: - ld b,'0'-1 -- inc b - sub c - jr nc,- - add c - - ld c,a - ld a,b - call print_char - ld a,c - ret diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/printing.s b/playing-coffee - Copy/roms/cpu_instrs/source/common/printing.s deleted file mode 100644 index ad9d811..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/printing.s +++ /dev/null @@ -1,98 +0,0 @@ -; Main printing routine that checksums and -; prints to output device - -; Character that does equivalent of print_newline -.define newline 10 - -; Prints char without updating checksum -; Preserved: BC, DE, HL -.define print_char_nocrc bss -.redefine bss bss+3 - - -; Initializes printing. HL = print routine -init_printing: - ld a,l - ld (print_char_nocrc+1),a - ld a,h - ld (print_char_nocrc+2),a - jr show_printing - - -; Hides/shows further printing -; Preserved: BC, DE, HL -hide_printing: - ld a,$C9 ; RET - jr + -show_printing: - ld a,$C3 ; JP (nn) -+ ld (print_char_nocrc),a - ret - - -; Prints character and updates checksum UNLESS -; it's a newline. -; Preserved: AF, BC, DE, HL -print_char: - push af - cp newline - call nz,update_crc - call print_char_nocrc - pop af - ret - - -; Prints space. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_space: - push af - ld a,' ' - call print_char_nocrc - pop af - ret - - -; Advances to next line. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_newline: - push af - ld a,newline - call print_char_nocrc - pop af - ret - - -; Prints immediate string -; Preserved: AF, BC, DE, HL -.macro print_str ; string,string2 - push hl - call print_str_ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 - pop hl -.endm - -print_str_: - pop hl - call print_str_hl - jp hl - - -; Prints zero-terminated string pointed to by HL. -; On return, HL points to byte AFTER zero terminator. -; Preserved: AF, BC, DE -print_str_hl: - push af - jr + -- call print_char -+ ldi a,(hl) - or a - jr nz,- - pop af - ret diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/runtime.s b/playing-coffee - Copy/roms/cpu_instrs/source/common/runtime.s deleted file mode 100644 index 90cd24f..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/runtime.s +++ /dev/null @@ -1,142 +0,0 @@ -; Common routines and runtime - -; Must be defined by target-specific runtime: -; -; init_runtime: ; target-specific inits -; std_print: ; default routine to print char A -; post_exit: ; called at end of std_exit -; report_byte: ; report A to user - -.define RUNTIME_INCLUDED 1 - -.ifndef bss - ; address of next normal variable - .define bss $D800 -.endif - -.ifndef dp - ; address of next direct-page ($FFxx) variable - .define dp $FF80 -.endif - -; DMG/CGB hardware identifier -.define gb_id_cgb $10 ; mask for testing CGB bit -.define gb_id_devcart $04 ; mask for testing "on devcart" bit - -.define gb_id bss -.redefine bss bss+1 - -; Stack is normally here -.define std_stack $DFFF - -; Copies $1000 bytes from HL to $C000, then jumps to it. -; A is preserved for jumped-to code. -copy_to_wram_then_run: - ld b,a - - ld de,$C000 - ld c,$10 -- ldi a,(hl) - ld (de),a - inc e - jr nz,- - inc d - dec c - jr nz,- - - ld a,b - jp $C000 - -.ifndef CUSTOM_RESET - reset: - ; Run code from $C000, as is done on devcart. This - ; ensures minimal difference in how it behaves. - ld hl,$4000 - jp copy_to_wram_then_run - - .bank 1 slot 1 - .org $0 ; otherwise wla pads with lots of zeroes - jp std_reset -.endif - -; Common routines -.include "gb.inc" -.include "macros.inc" -.include "delay.s" -.include "crc.s" -.include "printing.s" -.include "numbers.s" -.include "testing.s" - -; Sets up hardware and runs main -std_reset: - - ; Init hardware - di - ld sp,std_stack - - ; Save DMG/CGB id - ld (gb_id),a - - ; Init hardware - .ifndef BUILD_GBS - wreg TAC,$00 - wreg IF,$00 - wreg IE,$00 - .endif - - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - - ; TODO: clear all memory? - - ld hl,std_print - call init_printing - call init_testing - call init_runtime - call reset_crc ; in case init_runtime prints anything - - delay_msec 250 - - ; Run user code - call main - - ; Default is to successful exit - ld a,0 - jp exit - - -; Exits code and reports value of A -exit: - ld sp,std_stack - push af - call + - pop af - jp post_exit - -+ push af - call print_newline - call show_printing - pop af - - ; Report exit status - cp 1 - - ; 0: "" - ret c - - ; 1: "Failed" - jr nz,+ - print_str "Failed",newline - ret - - ; n: "Failed #n" -+ print_str "Failed #" - call print_dec - call print_newline - ret - -; returnOrg puts this code AFTER user code. -.section "runtime" returnOrg diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/common/testing.s b/playing-coffee - Copy/roms/cpu_instrs/source/common/testing.s deleted file mode 100644 index c102f78..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/common/testing.s +++ /dev/null @@ -1,176 +0,0 @@ -; Diagnostic and testing utilities - -.define result bss+0 -.define test_name bss+1 -.redefine bss bss+3 - - -; Sets test code and optional error text -; Preserved: AF, BC, DE, HL -.macro set_test ; code[,text[,text2]] - push hl - call set_test_ - jr @set_test\@ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 -@set_test\@: - pop hl -.endm - -set_test_: - pop hl - push hl - push af - inc hl - inc hl - ldi a,(hl) - ld (result),a - ld a,l - ld (test_name),a - ld a,h - ld (test_name+1),a - pop af - ret - - -; Initializes testing module -init_testing: - set_test $FF - call init_crc - ret - - -; Reports "Passed", then exits with code 0 -tests_passed: - call print_newline - print_str "Passed" - ld a,0 - jp exit - - -; Reports "Done" if set_test has never been used, -; "Passed" if set_test 0 was last used, or -; failure if set_test n was last used. -tests_done: - ld a,(result) - inc a - jr z,+ - dec a - jr z,tests_passed - jr test_failed -+ print_str "Done" - ld a,0 - jp exit - - -; Reports current error text and exits with result code -test_failed: - ld a,(test_name) - ld l,a - ld a,(test_name+1) - ld h,a - ld a,(hl) - or a - jr z,+ - call print_newline - call print_str_hl - call print_newline -+ - ld a,(result) - cp 1 ; if a = 0 then a = 1 - adc 0 - jp exit - - -; Prints checksum as 8-character hex value -; Preserved: AF, BC, DE, HL -print_crc: - push af - - ; Must read checksum entirely before printing, - ; since printing updates it. - lda checksum - cpl - push af - - lda checksum+1 - cpl - push af - - lda checksum+2 - cpl - push af - - lda checksum+3 - cpl - - call print_hex - pop af - call print_hex - pop af - call print_hex - pop af - call print_a - - pop af - ret - - -; If checksum doesn't match expected, reports failed test. -; Passing 0 just prints checksum. Clears checksum afterwards. -.macro check_crc ARGS crc - .if crc == 0 - call show_printing - call print_newline - call print_crc - .else - ld bc,(crc >> 16) ~ $FFFF - ld de,(crc & $FFFF) ~ $FFFF - call check_crc_ - .endif -.endm - -check_crc_: - lda checksum+0 - cp e - jr nz,+ - - lda checksum+1 - cp d - jr nz,+ - - lda checksum+2 - cp c - jr nz,+ - - lda checksum+3 - cp b - jr nz,+ - - jp reset_crc - -+ call print_crc - jp test_failed - - -; Updates checksum with bytes from addr to addr+size-1 -.macro checksum_mem ARGS addr,size - ld hl,addr - ld bc,size - call checksum_mem_ -.endm - -checksum_mem_: -- ldi a,(hl) - call update_crc - dec bc - ld a,b - or c - jr nz,- - ret diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/linkfile b/playing-coffee - Copy/roms/cpu_instrs/source/linkfile deleted file mode 100644 index 02a5a2e..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/linkfile +++ /dev/null @@ -1,2 +0,0 @@ -[objects] -test.o diff --git a/playing-coffee - Copy/roms/cpu_instrs/source/shell.inc b/playing-coffee - Copy/roms/cpu_instrs/source/shell.inc deleted file mode 100644 index 277a9b7..0000000 --- a/playing-coffee - Copy/roms/cpu_instrs/source/shell.inc +++ /dev/null @@ -1,21 +0,0 @@ -.incdir "common" - -; GBS music file -.ifdef BUILD_GBS - .include "build_gbs.s" -.endif - -; Devcart -.ifdef BUILD_DEVCART - .include "build_devcart.s" -.endif - -; Sub-test in a multi-test ROM -.ifdef BUILD_MULTI - .include "build_multi.s" -.endif - -; GB ROM (default) -.ifndef RUNTIME_INCLUDED - .include "build_rom.s" -.endif diff --git a/playing-coffee - Copy/roms/dmg_sound/dmg_sound.gb b/playing-coffee - Copy/roms/dmg_sound/dmg_sound.gb deleted file mode 100644 index fe91310..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/dmg_sound.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/readme.txt b/playing-coffee - Copy/roms/dmg_sound/readme.txt deleted file mode 100644 index 5d8d188..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/readme.txt +++ /dev/null @@ -1,86 +0,0 @@ -Game Boy Sound Hardware Tests ------------------------------ -These tests verify aspects of the sound hardware that the CPU can -observe. The ROMs and GBSs are either for DMG or CGB hardware, as there -are several differences. - - -Multi-ROM ---------- -In the main directory is a single ROM/GBS which runs all the tests. It -prints a test's number, runs the test, then "ok" if it passes, otherwise -a failure code. Once all tests have completed it either reports that all -tests passed, or reports the number of the first failed test as the -result code (1 = first). Finally, it makes several beeps. If a test -fails, it can be run on its own by finding the corresponding ROM/GBS in -the singles directories. - -Ths compact format on screen is to avoid having the results scroll off -the top, so the test can be started and allowed to run without having to -constantly monitor the display. - - -Failure information -------------------- -For more information about a failure code or information printed, see -the test's source code in source/. To find failure code N, search for -"set_test N", which will usually be before the subtest which failed. - - -Flashes, clicks, other glitches -------------------------------- -Some tests might need to turn the screen off and on, or cause slight -audio clicks. This does not indicate failure, and should be ignored. -Only the test result reported at the end is important, unless stated -otherwise. - - -LCD support ------------ -Tests generally print information on screen. The tests will work fine if -run on an emulator with NO LCD support, or as an GBS which has no -inherent screen; in particular, the VBL wait routine has a timeout in -case LY doesn't reflect the current LCD line. The text printing will -also work if the LCD doesn't support scrolling. - - -Output to memory ----------------- -Text output and the final result are also written to memory at $A000, -allowing testing a very minimal emulator that supports little more than -CPU and RAM. To reliably indicate that the data is from a test and not -random data, $A001-$A003 are written with a signature: $DE,$B0,$61. If -this is present, then the text string and final result status are valid. - -$A000 holds the overall status. If the test is still running, it holds -$80, otherwise it holds the final result code. - -All text output is appended to a zero-terminated string at $A004. An -emulator could regularly check this string for any additional -characters, and output them, allowing real-time text output, rather than -just printing the final output at the end. - - -GBS versions ------------- -Many GBS-based tests require that the GBS player either not interrupt -the init routine with the play routine, or if they do, not interrupt the -play routine again if it hasn't returned yet. This is because many tests -need to run for a while without returning. - -In addition to the other text output methods described above, GBS builds -report essential information bytes audibly, including the final result. -A byte is reported as a series of tones. The code is in binary, with a -low tone for 0 and a high tone for 1. The first tone is always a zero. A -final code of 0 means passed, 1 means failure, and 2 or higher indicates -a specific reason as listed in the source code by the corresponding -set_code line. Examples: - -Tones Binary Decimal Meaning -- - - - - - - - - - - - - - - - - - - - -low 0 0 passed -low high 01 1 failed -low high low 010 2 error 2 - --- -Shay Green diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/01-registers.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/01-registers.gb deleted file mode 100644 index c1fa6c5..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/01-registers.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/02-len ctr.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/02-len ctr.gb deleted file mode 100644 index d940c7a..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/02-len ctr.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/03-trigger.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/03-trigger.gb deleted file mode 100644 index 1b0f032..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/03-trigger.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/04-sweep.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/04-sweep.gb deleted file mode 100644 index 746b78a..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/04-sweep.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/05-sweep details.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/05-sweep details.gb deleted file mode 100644 index 55351a3..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/05-sweep details.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/06-overflow on trigger.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/06-overflow on trigger.gb deleted file mode 100644 index d3fbe3b..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/06-overflow on trigger.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/07-len sweep period sync.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/07-len sweep period sync.gb deleted file mode 100644 index 3da3bd7..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/07-len sweep period sync.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/08-len ctr during power.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/08-len ctr during power.gb deleted file mode 100644 index c72bbf2..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/08-len ctr during power.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/09-wave read while on.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/09-wave read while on.gb deleted file mode 100644 index b4a79ad..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/09-wave read while on.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/10-wave trigger while on.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/10-wave trigger while on.gb deleted file mode 100644 index a7c7ddc..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/10-wave trigger while on.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/11-regs after power.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/11-regs after power.gb deleted file mode 100644 index 773e01e..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/11-regs after power.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/rom_singles/12-wave write while on.gb b/playing-coffee - Copy/roms/dmg_sound/rom_singles/12-wave write while on.gb deleted file mode 100644 index e0119b9..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/rom_singles/12-wave write while on.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/source/01-registers.s b/playing-coffee - Copy/roms/dmg_sound/source/01-registers.s deleted file mode 100644 index ea9f5d5..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/01-registers.s +++ /dev/null @@ -1,117 +0,0 @@ -; - APU registers always have some bits set when read back. -; - Wave memory can be read back freely. -; - When powered off, registers are cleared, except high bit of NR52. -; - While off, register writes are ignored, but not reads. -; - Wave RAM is always readable and writable, and unaffected by power. - -.include "shell.inc" -.include "apu.s" - -main: - set_test 2,"NR10-NR51 and wave RAM write/read" - ld d,0 -- call test_rw - inc d - jr nz,- - - set_test 3,"NR52 write/read" - wreg NR52,$00 - lda NR52 - cp $70 - jp nz,test_failed - wreg NR52,$FF - lda NR52 - cp $F0 - jp nz,test_failed - - set_test 4,"Powering APU shouldn't affect wave" - ld a,$37 - call fill_wave - wreg NR52,$00 - - ; Verify that wave RAM is unchanged - ld hl,WAVE -- ld a,(hl+) - cp $37 - jp nz,test_failed - ld a,l - cp $40 - jr nz,- - wreg NR52,$80 ; on - - set_test 5,"Powering APU off should write 0 to all regs" - ld a,$FF - call fill_apu_regs - wreg NR52,$00 - wreg NR52,$80 - call regs_should_be_clear - - set_test 6,"When off, should ignore writes to registers" - wreg NR52,$00 - ld a,$FF - call fill_apu_regs - wreg NR52,$80 - call regs_should_be_clear - wreg NR52,$80 - - set_test 7,"When off, should allow normal register reads" - wreg NR52,$00 - call regs_should_be_clear - wreg NR52,$80 - - jp tests_passed - -regs_should_be_clear: - ld bc,masks - ld hl,NR10 -- ld a,(bc) - cp (hl) - jp nz,test_failed - inc bc - inc l - ld a,l - cp disabled clocks as well - ld a,1 - call end - - call begin - wchn 4,$40 ; enable length - wchn 1,-2 ; length = 2 - wchn 4,$40 ; enabled -> enabled doesn't clock - wchn 4,$00 ; enabled -> disabled doesn't clock - ld a,2 - call end -.else - set_test 4,"Anything besides enabling shouldnt't clock" - call begin - wchn 4,$40 ; enable length - wchn 1,-2 ; length = 2 - wchn 4,$40 ; enabled -> enabled doesn't clock - wchn 4,$00 ; enabled -> disabled doesn't clock - wchn 4,$00 ; disabled -> disabled doesn't clock - ld a,2 - call end -.endif - - set_test 5,"If clock makes length zero, should disable chan" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - lda chan_mask - ld b,a - lda NR52 ; channel now disabled - and b - jp nz,test_failed - - set_test 6,"If length already reached zero, shouldn't clock" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - wchn 4,0 - wchn 4,$40 ; no clock; length still 0 - wchn 4,0 - wchn 4,$40 ; no clock; length still 0 - lda chan_maxlen; end triggers channel, which loads it with max length - call end - - set_test 7,"Trigger should un-freeze length that reached zero" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - wchn 4,$00 ; disable - wchn 4,$80 ; trigger unfreezes length, so it takes on maximum value - delay_clocks 8192 - wchn 4,$40 ; enable - delay_apu 2 ; clock length by 2 - lda chan_maxlen - sub 2 - call end_nodelay - - set_test 8,"Trigger that un-freezes enabled length should clock it" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - wchn 4,$00 ; disable - wchn 4,$C0 ; trigger unfreezes length, and since enabled, clocks it - lda chan_maxlen - dec a - call end_nodelay - - call begin - wchn 1,-1 ; length = 1 - wchn 4,$40 ; enable, causing clock to zero - wchn 4,$C0 ; trigger unfreezes length, and since enabled, clocks it - lda chan_maxlen - dec a - call end_nodelay - - set_test 9,"Triggering that clocks length of 1 ","should clock twice and shouldn't freeze" - call begin - wchn 1,-1 ; length = 1 - wchn 4,$C0 ; trigger and enable - ; First length counter is enabled, which clocks it to 0 and freezes it - ; Trigger unfreezes length counter, which clocks it AGAIN - ; The result is the same as the previous test, which enables separately - lda chan_maxlen - dec a - call end_nodelay - - set_test 10,"Trigger shouldn't otherwise affect length" - call begin - wchn 1,0 ; length = max - delay_clocks 8192 - wchn 4,$80 ; trigger - lda chan_maxlen - call end_nodelay - -.ifndef CGB_02 - call begin - wchn 1,0 ; length = max - wchn 4,$80 ; trigger - lda chan_maxlen - call end - - call begin - wchn 1,-2 ; length = 2 - wchn 4,$80 ; trigger - ld a,2 - call end -.endif - - set_test 11,"Disabled DAC shouldn't stop other trigger effects" - call begin - wchn 0,$00 ; disable wave DAC - wchn 2,$07 ; disable square/noise DAC - wchn 1,-1 - wchn 4,$C0 ; clocks length, which becomes max - wchn 0,$80 ; enable wave DAC - wchn 2,$08 ; enable square/noise DAC - wchn 4,$80 ; trigger - lda chan_maxlen - dec a - call end - - set_test 12,"Other trigger effects should still occur when disabled" - call sync_apu - wchn 0,0 - wchn 4,0 - wchn 1,-1 - wchn 4,$40 ; len = 0 - wchn 4,0 - wchn 4,$40 ; len = 0 - wchn 4,$80 ; len = max - wchn 4,$40 ; len = max-1 - wchn 4,0 - wchn 4,$40 ; len = max-2 - wchn 0,$80 ; enable now - wchn 4,$C0 - lda chan_maxlen - sub 3 - call delay_apu_cycles - lda chan_mask - ld b,a - lda NR52 - and b - jp z,test_failed - delay_apu 1 - lda NR52 - and b - jp nz,test_failed - - ret diff --git a/playing-coffee - Copy/roms/dmg_sound/source/04-sweep.s b/playing-coffee - Copy/roms/dmg_sound/source/04-sweep.s deleted file mode 100644 index 17ac4e4..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/04-sweep.s +++ /dev/null @@ -1,120 +0,0 @@ -; Calc = calculation of new frequency and check for > $7FF -; Update = modification of frequency with new calculated value -.include "shell.inc" -.include "apu.s" - -begin: - call sync_sweep - wreg NR14,$40 - wreg NR11,-$21 - wreg NR12,$08 - ret - -should_be_almost_off: - lda NR52 - and $01 - jp z,test_failed - delay_apu 1 -should_be_off: - lda NR52 - and $01 - jp nz,test_failed - ret - -main: - set_test 2,"If shift>0, calculates on trigger" - call begin - wreg NR10,$01 - wreg NR13,$FF - wreg NR14,$C7 - call should_be_off - call begin - wreg NR10,$11 - wreg NR13,$FF - wreg NR14,$C7 - call should_be_off - - set_test 3,"If shift=0, doesn't calculate on trigger" - call begin - wreg NR10,$10 - wreg NR13,$FF - wreg NR14,$C7 - delay_apu 1 - call should_be_almost_off - - set_test 4,"If period=0, doesn't calculate" - call begin - wreg NR10,$00 - wreg NR13,$FF - wreg NR14,$C7 - delay_apu $20 - call should_be_almost_off - - set_test 5,"After updating frequency, calculates a second time" - call begin - wreg NR10,$11 - wreg NR13,$00 - wreg NR14,$C5 - delay_apu 1 - call should_be_almost_off - - set_test 6,"If calculation>$7FF, disables channel" - call begin - wreg NR10,$02 - wreg NR13,$67 - wreg NR14,$C6 - call should_be_off - - set_test 7,"If calculation<=$7FF, doesn't disable channel" - call begin - wreg NR10,$01 - wreg NR13,$55 - wreg NR14,$C5 - delay_apu $20 - call should_be_almost_off - - set_test 8,"If shift=0 and period>0, trigger enables" - call begin - wreg NR10,$10 - wreg NR13,$FF - wreg NR14,$C3 - delay_apu 2 - wreg NR10,$11 - delay_apu 1 - call should_be_almost_off - - set_test 9,"If shift>0 and period=0, trigger enables" - call begin - wreg NR10,$01 - wreg NR13,$FF - wreg NR14,$C3 - delay_apu 15 - wreg NR10,$11 - call should_be_almost_off - - set_test 10,"If shift=0 and period=0, trigger disables" - call begin - wreg NR10,$08 - wreg NR13,$FF - wreg NR14,$C3 - wreg NR10,$11 - delay_apu $20 - call should_be_almost_off - - set_test 11,"If shift=0, doesn't update" - call begin - wreg NR10,$10 - wreg NR13,$FF - wreg NR14,$C3 - delay_apu $20 - call should_be_almost_off - - set_test 12,"If period=0, doesn't update" - call begin - wreg NR10,$01 - wreg NR13,$00 - wreg NR14,$C5 - delay_apu $20 - call should_be_almost_off - - jp tests_passed diff --git a/playing-coffee - Copy/roms/dmg_sound/source/05-sweep details.s b/playing-coffee - Copy/roms/dmg_sound/source/05-sweep details.s deleted file mode 100644 index 1519b68..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/05-sweep details.s +++ /dev/null @@ -1,121 +0,0 @@ -; Calc = calculation of new frequency and check for > $7FF -; Update = modification of frequency with new calculated value -.include "shell.inc" -.include "apu.s" - -begin: - call sync_sweep - wreg NR14,$40 - wreg NR11,-$20 - wreg NR12,$08 - ret - -should_be_almost_off: - lda NR52 - and $01 - jp z,test_failed - delay_apu 1 -should_be_off: - lda NR52 - and $01 - jp nz,test_failed - ret - -main: - set_test 2,"Timer treats period 0 as 8" - call begin - wreg NR10,$11 - wreg NR13,$00 - wreg NR14,$C2 - delay_apu 1 - wreg NR10,$01 ; sweep enabled - delay_apu 3 - wreg NR10,$11 ; non-zero period so calc will occur when timer reloads - delay_apu $11 - call should_be_almost_off - - set_test 3,"Makes private copy of frequency on trigger" - call begin - wreg NR10,$12 - wreg NR13,$04 - wreg NR14,$80 - wreg NR13,$00 - delay_apu $39 - call should_be_almost_off - - set_test 4,"Exiting negate mode after calculation disables channel" - call begin - wreg NR10,$09 ; since shift > 0, calculates sweep value at init - wreg NR13,$00 - wreg NR14,$C0 - delay_apu 2 - wreg NR10,$10 ; neg->pos, so disables channel - call should_be_off - - set_test 5,"Ending negate after it maybe changed freq disables chan" - call begin - wreg NR10,$10 ; enable sweep - wreg NR13,$00 - wreg NR14,$C0 - delay_apu 2 - wreg NR10,$18 ; negate mode - delay_apu 2 - wreg NR10,$10 ; neg->pos, so disables channel - call should_be_off - - set_test 6,"Ending negate mode any other way doesn't disable channel" - call begin - wreg NR10,$1F ; use negate mode once - wreg NR14,$C0 - delay_apu 2 - wreg NR10,$18 ; since period > 0, doesn't calculate at init - wreg NR13,$00 - wreg NR14,$C0 - delay_apu 1 ; no sweep clock here - wreg NR10,$10 ; pos mode before neg mode ever used - delay_apu 1 ; sweep clock occurs here - wreg NR10,$0F ; now let neg mode be seen once, but period = 0 so no calculation is made - delay_apu 2 ; sweep clock occurs here - wreg NR10,$10 ; doesn't affect channel - delay_apu 2 ; sweep clock occurs here - wreg NR10,$1F ; let neg mode get used - delay_apu 18 - wreg NR10,$79 ; period and shift can be changed without channel disabling - delay_apu 5 - call should_be_almost_off - - set_test 7,"Subtract mode uses two's complement" - call begin - delay 2048 ; avoids extra length clocking on CGB-02 - wreg NR10,$1C - wreg NR13,$B0 - wreg NR14,$85 - delay_apu 2 - wreg NR10,$01 - wreg NR14,$C5 - delay_apu $1F - call should_be_almost_off - - set_test 8,"Subtract mode uses two's complement (upper bound)" - call begin - wreg NR10,$1C - wreg NR13,$B1 - wreg NR14,$85 - delay_apu 2 - wreg NR10,$01 - wreg NR14,$C5 - call should_be_off - - set_test 9,"Update channel frequency only when period is reloaded" - call begin - wreg NR10,$74 - wreg NR13,$06 - wreg NR14,$85 - delay_apu 14 ; just reloaded - wreg NR13,$06 - delay_apu 13 ; if 14, fails - wreg NR10,$11 - wreg NR14,$85 ; just before next reload, so freq is still $506 - call should_be_almost_off - - jp tests_passed diff --git a/playing-coffee - Copy/roms/dmg_sound/source/06-overflow on trigger.s b/playing-coffee - Copy/roms/dmg_sound/source/06-overflow on trigger.s deleted file mode 100644 index 2ebc236..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/06-overflow on trigger.s +++ /dev/null @@ -1,64 +0,0 @@ -; Finds highest and lowest frequencies that don't overflow -; immediately on trigger, for NR10 values of $00-$07 - -.include "shell.inc" -.include "apu.s" - -main: - - ; DMG-06: - ; 0555 0666 071C 0787 07C1 07E0 07F0 - - wreg NR12,8 - ld d,$01 -shift_loop: - ld a,d - sta NR10 - ld bc,$87FF -- ld a,c - sta NR13 - ld a,b - sta NR14 - delay_clocks 40 - lda NR52 - and 1 - jr nz,+ - dec bc - bit 6,b - jr z,- -+ res 7,b - call print_bc - inc d - bit 3,d - jr z,shift_loop - call print_newline - check_crc $F604603B - - ; DMG-05, DMG-06, DMG-09, CGB-04, CGB-05: - ; 0556 0667 071D 0788 07C2 07E1 07F1 - - wreg NR12,8 - ld d,$01 -shift_loop2: - ld a,d - sta NR10 - ld bc,$8000 -- ld a,c - sta NR13 - ld a,b - sta NR14 - delay_clocks 40 - lda NR52 - and 1 - jr z,+ - inc bc - bit 6,b - jr z,- -+ res 7,b - call print_bc - inc d - bit 3,d - jr z,shift_loop2 - check_crc $5A1697EE - - jp tests_passed diff --git a/playing-coffee - Copy/roms/dmg_sound/source/07-len sweep period sync.s b/playing-coffee - Copy/roms/dmg_sound/source/07-len sweep period sync.s deleted file mode 100644 index 6b3ed7e..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/07-len sweep period sync.s +++ /dev/null @@ -1,106 +0,0 @@ -; Tests length and sweep periods, and synchronization between the two -.include "shell.inc" -.include "apu.s" - -test_timing: - ; Time how long until next length clock -- inc de - ld a,(NR52) - and $01 - jr nz,- - - ;call print_de - - ; Error if not in 0...4 range - ld a,d - cp 0 - jp nz,test_failed - ld a,e - cp 5 - jp nc,test_failed - ret - -main: - - set_test 2,"Length period is wrong" - call sync_apu - wreg NR14,$40 ; avoids extra length clock - wreg NR11,$3F ; length = $01 - wreg NR12,$08 ; silent without disabling channel - wreg NR14,$C0 ; start length - ld de,-$170 - call test_timing - - set_test 3,"Sweep period is wrong" - call sync_sweep - wreg NR10,$10 ; sweep period = 1 - wreg NR12,$08 ; silent without disabling channel - wreg NR13,$FF ; max freq - wreg NR14,$87 ; start - ld de,-$2E4 - call test_timing - - set_test 4,"Sweep clock is synchronized with length" - call sync_sweep - wreg NR14,$40 ; avoids extra length clock - wreg NR11,$3F ; length = $01 - wreg NR12,$08 ; silent without disabling channel - wreg NR14,$C0 ; start length - ld de,-$170 - call test_timing - - set_test 5,"Powering up APU MODs next frame time with 8192" - call sync_apu - ld de,-$16F - call test_power - - call sync_apu - ld de,-$B5 - call test_power_off - - call sync_apu - delay_clocks 8192 - ld de,-$B5 - call test_power - - call sync_apu - delay_clocks 8192 - ld de,-$B5 - call test_power_off - - call sync_apu - ld de,-$B5 - wreg NR52,$00 ; power off - delay_clocks 8192 - call test_power - - set_test 6,"Powering up APU resets 128 Hz sweep divider" - call sync_sweep - ld de,-$229 - call test_power2 - - call sync_sweep - delay_apu 1 - ld de,-$229 - call test_power2 - - jp tests_passed - -test_power_off: - wreg NR52,$00 ; power off -test_power: - wreg NR52,$80 ; power on - wreg NR14,$40 - wreg NR11,-1 ; length = 1 - wreg NR12,8 - wreg NR14,$C0 - jp test_timing - -test_power2: - wreg NR52,$00 ; power off - wreg NR52,$80 ; power on - wreg NR10,$11 - wreg NR12,8 - wreg NR13,$00 - wreg NR14,$84 - jp test_timing diff --git a/playing-coffee - Copy/roms/dmg_sound/source/08-len ctr during power.s b/playing-coffee - Copy/roms/dmg_sound/source/08-len ctr during power.s deleted file mode 100644 index 1ea218a..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/08-len ctr during power.s +++ /dev/null @@ -1,84 +0,0 @@ -; On CGB, length counters are reset when powered up. -; On DMG, they are unaffected, and not clocked. - -;.define REQUIRE_DMG 1 -;.define REQUIRE_CGB 1 -.include "shell.inc" -.include "apu.s" - -enable_len_ctrs: - wreg NR22,8 - wreg NR24,$C0 - wreg NR12,8 - wreg NR14,$C0 - wreg NR30,$80 - wreg NR34,$C0 - wreg NR42,8 - wreg NR44,$C0 - ret - -main: - call sync_apu - - ld a,0 - call fill_apu_regs - - ; Load length counters - wreg NR41,-$33 - wreg NR31,-$44 - wreg NR11,-$11 - wreg NR21,-$22 - - delay_clocks 8192 - call enable_len_ctrs - - ; Power down. Comment out to see what would - ; happen if length counters did run. - wreg NR52,$00 - - ; Try to enable length counters - call enable_len_ctrs - - ; Give plenty of time for them to be clocked - delay_msec 250 - - ; Power back on and wait a bit longer - wreg NR52,$80 - ;call enable_len_ctrs ; can't do this here - delay_clocks 2048 - - ; Get values from length counters - wreg NR22,8 - wreg NR24,$C0 - ld a,$02 - call get_len_a - push af - - wreg NR12,8 - wreg NR14,$C0 - ld a,$01 - call get_len_a - push af - - wreg NR30,$80 - wreg NR34,$C0 - ld a,$04 - call get_len_a - push af - - wreg NR42,8 - wreg NR44,$C0 - ld a,$08 - call get_len_a - - ; Print them - call print_a - pop af - call print_a - pop af - call print_a - pop af - call print_a - - check_crc_dmg_cgb $32F0CFBB,$3CF589B4 - jp tests_passed diff --git a/playing-coffee - Copy/roms/dmg_sound/source/09-wave read while on.s b/playing-coffee - Copy/roms/dmg_sound/source/09-wave read while on.s deleted file mode 100644 index 2d06a77..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/09-wave read while on.s +++ /dev/null @@ -1,41 +0,0 @@ -; Reads from wave RAM while playing, each time 2 -; clocks later. - -;.define REQUIRE_DMG 1 -;.define REQUIRE_CGB 1 -.include "shell.inc" -.include "apu.s" - -main: - wreg NR51,0 ; mute sound - loop_n_times test,69 - check_crc_dmg_cgb $118A3620,$270DA9A3 - jp tests_passed - -test: - add $99 - ld b,a - - ; Reload wave and have its first - ; sample read occur 2 clocks earlier - ; each loop iteration - ld hl,wave - call load_wave - wreg NR30,$80 ; enable - wreg NR32,$00 ; silent - ld a,b - sta NR33 ; period - wreg NR34,$87 ; start - - ; Read from wave - wreg NR33,-2 ; period = 4 - delay_clocks 176 - lda WAVE - - call print_a - - ret - -wave: - .byte $00,$11,$22,$33,$44,$55,$66,$77 - .byte $88,$99,$AA,$BB,$CC,$DD,$EE,$FF diff --git a/playing-coffee - Copy/roms/dmg_sound/source/10-wave trigger while on.s b/playing-coffee - Copy/roms/dmg_sound/source/10-wave trigger while on.s deleted file mode 100644 index d7ec063..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/10-wave trigger while on.s +++ /dev/null @@ -1,49 +0,0 @@ -; Retriggers wave without stopping first - -;.define REQUIRE_DMG 1 -;.define REQUIRE_CGB 1 -.include "shell.inc" -.include "apu.s" - -main: - wreg NR51,0 ; mute sound - loop_n_times test,69 - check_crc_dmg_cgb $533D6D4D,$8130733A - jp tests_passed - -test: - add $99 - ld b,a - - ; Reload wave and have its first - ; sample read occur 2 clocks earlier - ; each loop iteration - ld hl,wave - call load_wave - wreg NR30,$80 ; enable - wreg NR32,$00 ; silent - ld a,b - sta NR33 ; period - wreg NR34,$87 ; start - - ; Retrigger wave - wreg NR33,-2 ; period = 4 - delay_clocks 168 - wreg NR34,$87 ; restart - delay_clocks 40 - - ; Print wave RAM - wreg NR30,0 - ld c,$30 -- ld a,($FF00+c) - call print_a - inc c - bit 6,c - jr z,- - call print_newline - - ret - -wave: - .byte $00,$11,$22,$33,$44,$55,$66,$77 - .byte $88,$99,$AA,$BB,$CC,$DD,$EE,$FF diff --git a/playing-coffee - Copy/roms/dmg_sound/source/11-regs after power.s b/playing-coffee - Copy/roms/dmg_sound/source/11-regs after power.s deleted file mode 100644 index 56506bb..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/11-regs after power.s +++ /dev/null @@ -1,52 +0,0 @@ -; After powering sound off then on, NR12 and NR14 are 0 -; and NR44 is unchanged. While powered off, writes to -; NR41 are NOT ignored. - -.define REQUIRE_DMG 1 -.include "shell.inc" -.include "apu.s" - -main: - call sync_apu - ld a,$FF - call fill_apu_regs - - ; Power down for a moment - wreg NR52,$00 - wreg NR41,-$12 - wreg NR12,$F0 - delay_msec 100 - wreg NR52,$80 - - set_test 2,"Powering off should clear NR12" - call sync_apu - wreg NR14,$80 - lda NR52 - and $01 - jp nz,test_failed - - set_test 3,"Powering off should clear NR13" - call sync_apu - wreg NR10,$11 - wreg NR12,$08 - wreg NR14,$80 - delay_apu 20 - lda NR52 - and $01 - jp z,test_failed - - set_test 4,"Powering off shouldn't affect NR41" - call sync_apu - delay_clocks 8192 ; avoids extra length clocking - wreg NR42,$08 - wreg NR44,$C0 - delay_apu $11 - lda NR52 - and $08 - jp z,test_failed - delay_apu 1 - lda NR52 - and $08 - jp nz,test_failed - - jp tests_passed diff --git a/playing-coffee - Copy/roms/dmg_sound/source/12-wave write while on.s b/playing-coffee - Copy/roms/dmg_sound/source/12-wave write while on.s deleted file mode 100644 index de4df7e..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/12-wave write while on.s +++ /dev/null @@ -1,49 +0,0 @@ -; Writes to wave RAM while playing - -.define REQUIRE_DMG 1 -;.define REQUIRE_CGB 1 -.include "shell.inc" -.include "apu.s" - -main: - loop_n_times test,69 - - ; CGB behaves erratically, so DMG-only for now - check_crc_dmg_cgb $3B4538A9,$2B27544E - jp tests_passed - -test: - add $99 - ld b,a - - ; Reload wave and have its first - ; sample read occur 2 clocks earlier - ; each loop iteration - ld hl,wave - call load_wave - wreg NR30,$80 ; enable - wreg NR32,$00 ; silent - ld a,b - sta NR33 ; period - wreg NR34,$87 ; start - - ; Write to wave - wreg NR33,-2 ; period = 4 - delay_clocks 168 - wreg WAVE,$F7 - - ; Print wave RAM - wreg NR30,0 - delay 1000 - ld hl,WAVE -- ld a,(hl+) - call print_a - bit 6,l - jr z,- - call print_newline - - ret - -wave: - .byte $00,$11,$22,$33,$44,$55,$66,$77 - .byte $88,$99,$AA,$BB,$CC,$DD,$EE,$FF diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/build_gbs.s b/playing-coffee - Copy/roms/dmg_sound/source/common/build_gbs.s deleted file mode 100644 index 877754f..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/build_gbs.s +++ /dev/null @@ -1,139 +0,0 @@ -; Build as GBS music file - -.memoryMap - defaultSlot 0 - slot 0 $2000 size $2000 - slot 1 $C000 size $2000 -.endMe - -.romBankSize $2000 -.romBanks 2 - -.define RST_OFFSET $70 - -.ifndef GBS_TMA - .define GBS_TMA 0 -.endif - -.ifndef GBS_TAC - .define GBS_TAC 0 -.endif - -;;;; GBS music file header - -.ifndef CUSTOM_HEADER - .byte "GBS" - .byte 1,1,1 ; vers, song count, first song - .word load_addr, reset, gbs_play_, std_stack - .byte GBS_TMA,GBS_TAC ; timer -.endif - .org $10 - .ds $60,0 -load_addr: - .org RST_OFFSET+$70 ; space for RST vectors - .ds $148-RST_OFFSET-$70,0 - .org $150 ; wla insists on generating GB header - -gbs_play_: - jp gbs_play ; GBS spec disallows having gbs_play in RAM - -;;;; Shell - -.include "shell.s" - -.define gbs_idle nv_ram -.redefine nv_ram nv_ram+2 - -init_runtime: - ; Identify as DMG hardware - ld a,$01 - ld (gb_id),a - - ; Save return address - pop hl - ld a,l - ld (gbs_idle),a - ld a,h - ld (gbs_idle+1),a - - ; Delay 1/4 second to give time - ; for GBS player to interrupt with - ; play, if it's going to do so - delay_msec 250 - -.ifndef CUSTOM_PLAY -gbs_play: -.endif - ; Get return address - ld a,(gbs_idle) - ld l,a - ld a,(gbs_idle+1) - ld h,a - - ; If zero, then play interrupted init - ; call, or another play call, and we - ; can't run the program properly. - or l - jp z,internal_error - - setw gbs_idle,0 - jp hl - - -; Reports A in binary as high and low tones, with -; leading low tone for reference. Omits leading -; zeroes. -; Preserved: AF, BC, DE, HL -play_byte: - push af - push hl - - ; HL = (A << 1) | 1 - scf - rla - ld l,a - ld h,0 - rl h - - ; Shift left until next-to-top bit is 1 -- add hl,hl - bit 6,h - jr z,- - - ; Reset sound - delay_msec 400 - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - -- add hl,hl - - ; Low or high pitch based on bit shifted out - ; of HL - ld a,0 - jr nc,+ - ld a,$FF -+ sta NR23 - - ; Play short tone - wreg NR21,$A0 - wreg NR22,$F0 - wreg NR24,$86 - delay_msec 75 - wreg NR22,0 - wreg NR23,$F8 - wreg NR24,$87 - delay_msec 200 - - ; Loop until HL = $8000 - ld a,h - xor $80 - or l - jr nz,- - - pop hl - pop af - ret - -.ends diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/build_rom.s b/playing-coffee - Copy/roms/dmg_sound/source/common/build_rom.s deleted file mode 100644 index c1595b7..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/build_rom.s +++ /dev/null @@ -1,70 +0,0 @@ -; Build as GB ROM - -.memoryMap - defaultSlot 0 - slot 0 $0000 size $4000 - slot 1 $C000 size $4000 -.endMe - -.romBankSize $4000 -.romBanks 2 - -.cartridgeType 3 ; MBC1+RAM+battery -.ramsize 02 ; 8K -.computeChecksum -.computeComplementCheck - -;;;; GB ROM header - - ; Reserve space for RST handlers - .org $70 - - ; Keep unused space filled, otherwise - ; wla moves code here - .ds $90,0 - - ; GB header read by bootrom - .org $100 - nop - jp reset - - ; Nintendo logo required for proper boot - .byte $CE,$ED,$66,$66,$CC,$0D,$00,$0B - .byte $03,$73,$00,$83,$00,$0C,$00,$0D - .byte $00,$08,$11,$1F,$88,$89,$00,$0E - .byte $DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 - .byte $BB,$BB,$67,$63,$6E,$0E,$EC,$CC - .byte $DD,$DC,$99,$9F,$BB,$B9,$33,$3E - - ; Internal name - .ifdef ROM_NAME - .byte ROM_NAME - .endif - - ; CGB/DMG requirements - .org $143 - .ifdef REQUIRE_CGB - .byte $C0 - .else - .ifndef REQUIRE_DMG - .byte $80 - .endif - .endif - - ; Keep unused space filled, otherwise - ; wla moves code here - .org $150 - .ds $2150-$150,0 - -;;;; Shell - -.define NEED_CONSOLE 1 -.include "shell.s" - -init_runtime: - ret - -play_byte: - ret - -.ends diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/console.bin b/playing-coffee - Copy/roms/dmg_sound/source/common/console.bin deleted file mode 100644 index b02f2d3..0000000 Binary files a/playing-coffee - Copy/roms/dmg_sound/source/common/console.bin and /dev/null differ diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/console.s b/playing-coffee - Copy/roms/dmg_sound/source/common/console.s deleted file mode 100644 index 403fa5c..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/console.s +++ /dev/null @@ -1,285 +0,0 @@ -; Scrolling text console - -; Console is 20x18 characters. Buffers lines, so -; output doesn't appear until a newline or flush. -; If scrolling isn't supported (i.e. SCY is treated -; as if always zero), the first 18 lines will -; still print properly). Also works properly if -; LY isn't supported (always reads back as the same -; value). - -.define console_width 20 - -.define console_buf bss+0 -.define console_pos bss+console_width -.define console_mode bss+console_width+1 -.define console_scroll bss+console_width+2 -.redefine bss bss+console_width+3 - - -; Waits for start of LCD blanking period -; Preserved: BC, DE, HL -console_wait_vbl: - push bc - - ; Wait for start of vblank, with - ; timeout in case LY doesn't work - ; or LCD is disabled. - ld bc,-1250 -- inc bc - ld a,b - or c - jr z,@timeout - lda LY - cp 144 - jr nz,- -@timeout: - - pop bc - ret - - -; Initializes text console -console_init: - call console_hide - - ; CGB-specific inits - ld a,(gb_id) - and gb_id_cgb - call nz,@init_cgb - - ; Clear nametable - ld a,' ' - call @fill_nametable - - ; Load tiles - ld hl,TILES+$200 - ld c,0 - call @load_tiles - ld hl,TILES+$A00 - ld c,$FF - call @load_tiles - - ; Init state - setb console_pos,console_width - setb console_mode,0 - setb console_scroll,-8 - call console_scroll_up_ - jr console_show - -@fill_nametable: - ld hl,BGMAP0 - ld b,4 -- ld (hl),a - inc l - jr nz,- - inc h - dec b - jr nz,- - ret - -@init_cgb: - ; Clear palette - wreg $FF68,$80 - ld b,16 -- wreg $FF69,$FF - wreg $FF69,$7F - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - dec b - jr nz,- - - ; Clear attributes - wreg VBK,1 - ld a,0 - call @fill_nametable - - wreg VBK,0 - ret - -@load_tiles: - ld de,ASCII - ld b,96 --- push bc - ld b,8 -- ld a,(de) - inc de - xor c - ldi (hl),a - ldi (hl),a - dec b - jr nz,- - pop bc - dec b - jr nz,-- - ret - - -; Shows console display -; Preserved: AF, BC, DE, HL -console_show: - push af - - ; Enable LCD - call console_wait_vbl - wreg LCDC,$91 - wreg SCX,0 - wreg BGP,$E4 - - jp console_apply_scroll_ - - -; Hides console display by turning LCD off -; Preserved: AF, BC, DE, HL -console_hide: - push af - - ; LCD off - call console_wait_vbl - wreg LCDC,$11 - - pop af - ret - - -; Changes to normal text mode -; Preserved: BC, DE, HL -console_normal: - xor a - jr console_set_mode - -; Changes to inverse text mode -; Preserved: BC, DE, HL -console_inverse: - ld a,$80 - -; Changes console mode to A. -; 0: Normal, $80: Inverse -; Preserved: BC, DE, HL -console_set_mode: - and $80 - ld (console_mode),a - ret - - -; Prints char A to console. Will not appear until -; a newline or flush occurs. -; Preserved: AF, BC, DE, HL -console_print: - push af - - cp 10 - jr z,console_newline_ - - push hl - push af - ld hl,console_pos - ldi a,(hl) - cp BGMAP0) >> 2 - add hl,hl - add hl,hl - - ; Copy line - ld de,console_buf + console_width -- dec e - ld a,(de) - ldi (hl),a - ld a,e - cp checksum - ldi (hl),a - ld (hl),d - inc l - ld (hl),c - inc l - ld (hl),b - - pop hl - pop de - pop bc - pop af - ret diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/delay.s b/playing-coffee - Copy/roms/dmg_sound/source/common/delay.s deleted file mode 100644 index cbcdcf3..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/delay.s +++ /dev/null @@ -1,220 +0,0 @@ -; Delays in cycles, milliseconds, etc. - -; All routines are re-entrant (no global data). Routines never -; touch BC, DE, or HL registers. These ASSUME CPU is at normal -; speed. If running at double speed, msec/usec delays are half advertised. - -; Delays n cycles, from 0 to 16777215 -; Preserved: AF, BC, DE, HL -.macro delay ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 16777215 - .printt "Delay must be < 16777216" - .fail - .endif - delay_ n&$FFFF, n>>16 -.endm - -; Delays n clocks, from 0 to 16777216*4. Must be multiple of 4. -; Preserved: AF, BC, DE, HL -.macro delay_clocks ARGS n - .if n # 4 != 0 - .printt "Delay must be a multiple of 4" - .fail - .endif - delay_ (n/4)&$FFFF,(n/4)>>16 -.endm - -; Delays n microseconds (1/1000000 second) -; n can range from 0 to 4000 usec. -; Preserved: AF, BC, DE, HL -.macro delay_usec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 4000 - .printt "Delay must be <= 4000 usec" - .fail - .endif - delay_ ((n * 1048576 + 500000) / 1000000)&$FFFF,((n * 1048576 + 500000) / 1000000)>>16 -.endm - -; Delays n milliseconds (1/1000 second) -; n can range from 0 to 10000 msec. -; Preserved: AF, BC, DE, HL -.macro delay_msec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 10000 - .printt "Delay must be <= 10000 msec" - .fail - .endif - delay_ ((n * 1048576 + 500) / 1000)&$FFFF, ((n * 1048576 + 500) / 1000)>>16 -.endm - - ; All the low/high quantities are to deal wla-dx's asinine - ; restriction full expressions must evaluate to a 16-bit - ; value. If the author ever rectifies this, all "high" - ; arguments can be treated as zero and removed. Better yet, - ; I'll just find an assembler that didn't crawl out of - ; the sewer (this is one of too many bugs I've wasted - ; hours working around). - - .define max_short_delay 28 - - .macro delay_long_ ARGS n, high - ; 0+ to avoid assembler treating as memory read - ld a,0+(((high<<16)+n) - 11) >> 16 - call delay_65536a_9_cycles_ - delay_nosave_ (((high<<16)+n) - 11)&$FFFF, 0 -.endm - - ; Doesn't save AF, allowing minimization of AF save/restore - .macro delay_nosave_ ARGS n, high - ; 65536+11 = maximum delay using delay_256a_9_cycles_ - ; 255+22 = maximum delay using delay_a_20_cycles - ; 22 = minimum delay using delay_a_20_cycles - .if high > 1 - delay_long_ n, high - .else - .if high*n > 11 - delay_long_ n, high - .else - .if (high*(255+22+1))|n > 255+22 - ld a,>(((high<<16)+n) - 11) - call delay_256a_9_cycles_ - delay_nosave_ <(((high<<16)+n) - 11), 0 - .else - .if n >= 22 - ld a,n - 22 - call delay_a_20_cycles - .else - delay_short_ n - .endif - .endif - .endif - .endif -.endm - - .macro delay_ ARGS low, high - .if (high*(max_short_delay+1))|low > max_short_delay - push af - delay_nosave_ ((high<<16)+low - 7)&$FFFF, ((high<<16)+low - 7)>>16 - pop af - .else - delay_short_ low - .endif -.endm - - -; Delays A cycles + overhead -; Preserved: BC, DE, HL -; Time: A+20 cycles (including CALL) -delay_a_20_cycles: -- sub 5 ; 2 - jr nc,- ;3/2 do multiples of 5 - rra ; 1 - jr nc,+ ;3/2 bit 0 -+ adc 1 ; 2 - ret nc ;5/2 -1: 0 cycles - ret z ;5/2 0: 2 cycles - nop ; 1 1: 4 cycles - ret ; 4 (thanks to dclxvi for original algorithm) - -; Delays A*256 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*256+12 cycles (including CALL) -delay_256a_12_cycles: - or a ; 1 - ret z ; 5/2 -delay_256a_9_cycles_: -- delay 256-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays A*65536 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*65536+12 cycles (including CALL) -delay_65536a_12_cycles: - or a ; 1 - ret z ;5/2 -delay_65536a_9_cycles_: -- delay 65536-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays H*256+L cycles + overhead -; Preserved: AF, BC, DE, HL -; Time: H*256+L+51 cycles -delay_hl_51_cycles: - push af - ld a,h - call delay_256a_12_cycles - ld a,l - call delay_a_20_cycles - pop af - ret - - ; delay_short_ macro calls into these - .ds max_short_delay-10,$00 ; NOP repeated several times -delay_unrolled_: - ret - -.macro delay_short_ ARGS n - .if n < 0 - .fail - .endif - .if n > max_short_delay - .fail - .endif - - .if n == 1 - nop - .endif - .if n == 2 - nop - nop - .endif - .if n == 3 - .byte $18,$00 ; JR +0 - .endif - .if n == 4 - .byte $18,$00 ; JR +0 - nop - .endif - .if n == 5 - .byte $18,$00 ; JR +0 - nop - nop - .endif - .if n == 6 - .byte $18,$00 ; JR +0 - .byte $18,$00 ; JR +0 - .endif - .if n == 7 - push af - pop af - .endif - .if n == 8 - push af - pop af - nop - .endif - .if n == 9 - push af - pop af - nop - nop - .endif - .if n >= 10 - call delay_unrolled_ + 10 - n - .endif -.endm diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/gb.inc b/playing-coffee - Copy/roms/dmg_sound/source/common/gb.inc deleted file mode 100644 index 2d0118d..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/gb.inc +++ /dev/null @@ -1,81 +0,0 @@ -; Game Boy hardware addresses - -; $0000-$3FFF Fixed ROM bank -; $4000-$7FFF Switchable bank -; $8000-$9FFF VRAM -; $A000-$BFFF optional cartridge RAM -; $C000-$DFFF RAM -; $E000-$FDFF RAM mirror -; $FE00-$FE9F OAM -; $FEA0-$FEFF unused -; $FF00-$FF7F registers -; $FF80-$FFFE RAM -; $FFFF register - -; Memory -.define VRAM $8000 ; video memory -.define TILES $8000 ; tile images -.define BGMAP0 $9800 ; first 32x32 tilemap -.define BGMAP1 $9C00 ; second 32x32 tilemap -.define BRAM $A000 ; cart memory -.define WRAM $C000 ; internal memory -.define OAM $FE00 ; sprite memory -.define HRAM $FF80 ; fast memory for LDH - -; Registers - -.define RAMEN $0000 ; cartridge WRAM control -.define BANK $2000 ; bank select -.define P1 $FF00 ; controller - -; Game link I/O -.define SB $FF01 ; serial buffer -.define SC $FF02 ; serial control - -; Interrupts -.define DIV $FF04 -.define TIMA $FF05 -.define TMA $FF06 -.define TAC $FF07 -.define IF $FF0F -.define IE $FFFF - -; LCD registers -.define LCDC $FF40 ; control -.define STAT $FF41 ; status -.define SCY $FF42 ; scroll Y -.define SCX $FF43 ; scroll X -.define LY $FF44 ; current Y being rendered -.define BGP $FF47 - -.define KEY1 $FF4D ; for changing CPU speed -.define VBK $FF4F - -; Sound registers -.define NR10 $FF10 -.define NR11 $FF11 -.define NR12 $FF12 -.define NR13 $FF13 -.define NR14 $FF14 - -.define NR21 $FF16 -.define NR22 $FF17 -.define NR23 $FF18 -.define NR24 $FF19 - -.define NR30 $FF1A -.define NR31 $FF1B -.define NR32 $FF1C -.define NR33 $FF1D -.define NR34 $FF1E - -.define NR41 $FF20 -.define NR42 $FF21 -.define NR43 $FF22 -.define NR44 $FF23 - -.define NR50 $FF24 -.define NR51 $FF25 -.define NR52 $FF26 - -.define WAVE $FF30 diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/macros.inc b/playing-coffee - Copy/roms/dmg_sound/source/common/macros.inc deleted file mode 100644 index 9d7cf44..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/macros.inc +++ /dev/null @@ -1,91 +0,0 @@ -; General macros - -; Reads A from addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 3 cycles -.macro lda ; addr - ldh a,(\1 - $FF00) -.endm - -; Writes A to addr, from $FF00 to $FFFF -; Preserved: AF, BC, DE, HL -; Time: 3 cycles -.macro sta ; addr - ldh (\1 - $FF00),a -.endm - -; Writes immediate data to addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 5 cycles -.macro wreg ARGS addr, data - ld a,data - sta addr -.endm - -; Writes byte to addr -; Preserved: F, BC, DE, HL -; Time: 6 cycles -.macro setb ; addr, data - ld a,\2 - ld (\1),a -.endm - -; Writes word to addr -; Preserved: F, BC, DE, HL -; Time: 12 cycles -.macro setw ; addr, data - ld a,<\2 - ld (\1),a - ld a,>\2 - ld (\1+1),a -.endm - -; Calls routine multiple times, with A having the -; value 'start' the first time, 'start+step' the -; second time, up to 'end' for the last time. -; Preserved: BC, DE, HL -.macro for_loop ; routine,start,end,step - ld a,\2 - -for_loop\@: - push af - call \1 - pop af - - add \4 - cp <(\3 + \4) - jr nz,for_loop\@ -.endm - -; Calls routine n times. The value of A in the routine -; counts from 0 to n-1. -; Preserved: BC, DE, HL -.macro loop_n_times ; routine,n - for_loop \1,0,\2 - 1,+1 -.endm - -; Same as for_loop, but counts with 16-bit value in BC. -; Preserved: DE, HL -.macro for_loop16 ; routine,start,end,step - ld bc,\2 - -for_loop16\@: - push bc - call \1 - pop bc - - ld a,c - add <\4 - ld c,a - - ld a,b - adc >\4 - ld b,a - - cp >(\3+\4) - jr nz,for_loop16\@ - - ld a,c - cp <(\3+\4) - jr nz,for_loop16\@ -.endm diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/numbers.s b/playing-coffee - Copy/roms/dmg_sound/source/common/numbers.s deleted file mode 100644 index 6d6faf8..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/numbers.s +++ /dev/null @@ -1,177 +0,0 @@ -; Printing of numeric values - -; Prints value of indicated register/pair -; as 2/4 hex digits, followed by a space. -; Updates checksum with printed values. -; Preserved: AF, BC, DE, HL - -print_regs: - call print_af - call print_bc - call print_de - call print_hl - call print_newline - ret - -print_a: - push af -print_a_: - call print_hex - ld a,' ' - call print_char_nocrc - pop af - ret - -print_af: - push af - call print_hex - pop af -print_f: - push bc - push af - pop bc - call print_c - pop bc - ret - -print_b: - push af - ld a,b - jr print_a_ - -print_c: - push af - ld a,c - jr print_a_ - -print_d: - push af - ld a,d - jr print_a_ - -print_e: - push af - ld a,e - jr print_a_ - -print_h: - push af - ld a,h - jr print_a_ - -print_l: - push af - ld a,l - jr print_a_ - -print_bc: - push af - push bc -print_bc_: - ld a,b - call print_hex - ld a,c - pop bc - jr print_a_ - -print_de: - push af - push bc - ld b,d - ld c,e - jr print_bc_ - -print_hl: - push af - push bc - ld b,h - ld c,l - jr print_bc_ - - -; Prints A as two hex chars and updates checksum -; Preserved: BC, DE, HL -print_hex: - call update_crc -print_hex_nocrc: - push af - swap a - call + - pop af - -+ and $0F - cp 10 - jr c,+ - add 7 -+ add '0' - jp print_char_nocrc - - -; Prints char_nz if Z flag is clear, -; char_z if Z flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nz ARGS char_nz, char_z - push af - ld a,char_nz - jr nz,print_nz\@ - ld a,char_z -print_nz\@: - call print_char - pop af -.endm - - -; Prints char_nc if C flag is clear, -; char_c if C flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nc ARGS char_nc, char_c - push af - ld a,char_nc - jr nz,print_nc\@ - ld a,char_c -print_nc\@: - call print_char - pop af -.endm - - -; Prints A as 2 decimal digits -; Preserved: AF, BC, DE, HL -print_dec2: - push af - push bc - jr + - - -; Prints A as 1-3 digit decimal value -; Preserved: AF, BC, DE, HL -print_dec: - push af - push bc - - cp 10 - jr c,++ - ld c,100 - cp c - call nc,@digit -+ ld c,10 - call @digit -++ add '0' - call print_char - - pop bc - pop af - ret - -@digit: - ld b,'0'-1 -- inc b - sub c - jr nc,- - add c - - ld c,a - ld a,b - call print_char - ld a,c - ret diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/printing.s b/playing-coffee - Copy/roms/dmg_sound/source/common/printing.s deleted file mode 100644 index bb9389b..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/printing.s +++ /dev/null @@ -1,77 +0,0 @@ -; Main printing routine that checksums and -; prints to output device - -; Character that does equivalent of print_newline -.define newline 10 - -; Prints char without updating checksum -; Preserved: BC, DE, HL -;print_char_nocrc (defined by user) - - -; Prints character and updates checksum UNLESS -; it's a newline. -; Preserved: AF, BC, DE, HL -print_char: - push af - cp newline - call nz,update_crc - call print_char_nocrc - pop af - ret - - -; Prints space. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_space: - push af - ld a,' ' - call print_char_nocrc - pop af - ret - - -; Advances to next line. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_newline: - push af - ld a,newline - call print_char_nocrc - pop af - ret - - -; Prints immediate string -; Preserved: AF, BC, DE, HL -.macro print_str ; string,string2 - push hl - call print_str_ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 - pop hl -.endm - -print_str_: - pop hl - call print_str_hl - jp hl - - -; Prints zero-terminated string pointed to by HL. -; On return, HL points to byte AFTER zero terminator. -; Preserved: AF, BC, DE -print_str_hl: - push af - jr + -- call print_char -+ ldi a,(hl) - or a - jr nz,- - pop af - ret diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/shell.s b/playing-coffee - Copy/roms/dmg_sound/source/common/shell.s deleted file mode 100644 index 3e588c7..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/shell.s +++ /dev/null @@ -1,261 +0,0 @@ -; Common routines and runtime - -.define RUNTIME_INCLUDED 1 - -; A few bytes of RAM that aren't cleared -.define nv_ram_base $D800 -.define nv_ram nv_ram_base - -; Address of next normal variable -.define bss_base nv_ram_base+$80 -.define bss bss_base - -; Address of next direct-page ($FFxx) variable -.define dp_base $FF80 -.define dp dp_base - -; Top of stack -.define std_stack $DFFF+1 - -; Final exit result byte is written here -.define final_result $A000 - -; Text output is written here as zero-terminated string -.define text_out_base $A004 - -; DMG/CGB hardware identifier -.define gb_id_cgb $10 ; mask for testing CGB bit -.define gb_id_devcart $04 ; mask for testing "on devcart" bit -.define gb_id nv_ram -.redefine nv_ram nv_ram+1 - -; Copies C*$100 bytes from HL to $C000, then jumps to it. -; A is preserved for jumped-to code. -copy_to_wram_then_run: - ld b,a - - ld de,$C000 -- ld a,(hl+) - ld (de),a - inc e - jr nz,- - inc d - dec c - jr nz,- - - ld a,b - jp $C000 - - -.ifndef RST_OFFSET - .define RST_OFFSET 0 -.endif - -.ifndef CUSTOM_RESET - reset: - di - - ; Run code from $C000, as is done on devcart. This - ; ensures minimal difference in how it behaves. - ld hl,$4000 - ld c,$14 - jp copy_to_wram_then_run - - .bank 1 slot 1 - .org 0 - jp std_reset -.endif - -; returnOrg puts this code AFTER user code. -.section "runtime" returnOrg - - ; Catch user code running off end - jp internal_error - -; Common routines -.include "gb.inc" -.include "macros.inc" -.include "delay.s" -.include "crc.s" -.include "printing.s" -.include "numbers.s" -.include "testing.s" - -; Sets up hardware and runs main -std_reset: - - ; Init hardware - di - ld sp,std_stack - - ; Save DMG/CGB id - ld (gb_id),a - - ; Clear memory except very top of stack - ld bc,std_stack-bss_base - 2 - ld hl,bss_base - call clear_mem - ld bc,$FFFF-dp_base - ld hl,dp_base - call clear_mem - - ; Init hardware - wreg TAC,$00 - wreg IF,$00 - wreg IE,$00 - - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - - call init_runtime - call init_text_out - call console_init - call init_testing - - .ifdef TEST_NAME - print_str TEST_NAME,newline,newline - .endif - - call reset_crc ; in case init_runtime prints anything - - delay_msec 250 - - ; Run user code - call main - - ; Default is to successful exit - ld a,0 - jp exit - - -; Exits code and reports value of A -exit: - ld sp,std_stack - push af - call + - call console_show - pop af - call play_byte - jp post_exit - -+ push af - call print_newline - pop af - - ; Report exit status - cp 1 - - ; 0: "" - ret c - - ; 1: "Failed" - jr nz,+ - print_str "Failed",newline - ret - - ; n: "Failed #n" -+ print_str "Failed #" - call print_dec - call print_newline - ret - - -; Clears BC bytes starting at HL -clear_mem: - ; If C>0, increment B - dec bc - inc c - inc b - - ld a,0 -- ld (hl+),a - dec c - jr nz,- - dec b - jr nz,- - ret - - -; Reports internal error and exits with code 255 -internal_error: - print_str "Internal error" - ld a,255 - jp exit - - -; build_devcart and build_multi customize this -.ifndef CUSTOM_PRINT - .define text_out_addr bss+0 - .redefine bss bss+2 - - ; Initializes text output to cartridge RAM - init_text_out: - ; Enable cartridge RAM and set text output pointer - setb RAMEN,$0A - setw text_out_addr,text_out_base - setb text_out_base-3,$DE - setb text_out_base-2,$B0 - setb text_out_base-1,$61 - setb text_out_base,0 - setb final_result,$80 - ret - - - ; Appends character to text output string - ; Preserved: AF, BC, DE, HL - write_text_out: - push hl - push af - ld a,(text_out_addr) - ld l,a - ld a,(text_out_addr+1) - ld h,a - inc hl - ld (hl),0 - ld a,l - ld (text_out_addr),a - ld a,h - ld (text_out_addr+1),a - dec hl - pop af - ld (hl),a - pop hl - ret - - print_char_nocrc: - call write_text_out - jp console_print -.endif - - -; only build_rom uses console -.ifdef NEED_CONSOLE - .include "console.s" -.else - console_init: - console_print: - console_flush: - console_normal: - console_inverse: - console_show: - console_set_mode: - ret -.endif - - -; build_devcart and build_multi need to customize this -.ifndef CUSTOM_EXIT - post_exit: - ld (final_result),a - forever: - wreg NR52,0 ; sound off -- jr - -.endif - - -.macro def_rst ARGS addr - .bank 0 slot 0 - .org addr+RST_OFFSET -.endm diff --git a/playing-coffee - Copy/roms/dmg_sound/source/common/testing.s b/playing-coffee - Copy/roms/dmg_sound/source/common/testing.s deleted file mode 100644 index 5dd63ce..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/common/testing.s +++ /dev/null @@ -1,195 +0,0 @@ -; Diagnostic and testing utilities - -.define test_code bss+0 -.define test_name bss+1 -.redefine bss bss+3 - - -; Sets test code and optional error text. -; Takes multiple strings due to wla's idiotic -; default limit of 63 chars per string. -; Preserved: AF, BC, DE, HL -.macro set_test ; code[,text[,text2[,text3]]] - push hl - call set_test_ - jr @set_test\@ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .if NARGS > 3 - .byte \4 - .endif - .byte 0 -@set_test\@: - pop hl -.endm - -set_test_: - pop hl - push hl - push af - inc hl - inc hl - ldi a,(hl) - ld (test_code),a - ld a,l - ld (test_name),a - ld a,h - ld (test_name+1),a - pop af - ret - - -; Initializes testing module -init_testing: - set_test $FF - call init_crc - ret - - -; Reports "Passed", then exits with code 0 -tests_passed: - call print_newline - print_str "Passed" - ld a,0 - jp exit - - -; Reports "Done" if set_test has never been used, -; "Passed" if set_test 0 was last used, or -; failure if set_test n was last used. -tests_done: - ld a,(test_code) - inc a - jr z,+ - dec a - jr z,tests_passed - jr test_failed -+ print_str "Done" - ld a,0 - jp exit - - -; Reports current error text and exits with result code -test_failed: - ld a,(test_name) - ld l,a - ld a,(test_name+1) - ld h,a - ld a,(hl) - or a - jr z,+ - call print_newline - call print_str_hl - call print_newline -+ - ld a,(test_code) - cp $FF ; if a = $FF then a = 1 - jr nz,+ - ld a,1 -+ jp exit - - -; Prints checksum as 8-character hex value -; Preserved: AF, BC, DE, HL -print_crc: - push af - - ; Must read checksum entirely before printing, - ; since printing updates it. - lda checksum - cpl - push af - - lda checksum+1 - cpl - push af - - lda checksum+2 - cpl - push af - - lda checksum+3 - cpl - - call print_hex - pop af - call print_hex - pop af - call print_hex - pop af - call print_a - - pop af - ret - - -; If checksum doesn't match expected, reports failed test. -; Passing 0 just prints checksum. Clears checksum afterwards. -.macro check_crc ARGS crc - .if crc == 0 - call print_newline - call print_crc - .else - ld bc,(crc >> 16) ~ $FFFF - ld de,(crc & $FFFF) ~ $FFFF - call check_crc_ - .endif -.endm - -; Checks CRC, differing based on DMG or CGB build -.macro check_crc_dmg_cgb ARGS dmg, cgb - .ifdef REQUIRE_DMG - check_crc dmg - .else - .ifdef REQUIRE_CGB - check_crc cgb - .else - .printt "CGB or DMG must be specified" - .fail - .endif - .endif -.endm - -check_crc_: - lda checksum+0 - cp e - jr nz,+ - - lda checksum+1 - cp d - jr nz,+ - - lda checksum+2 - cp c - jr nz,+ - - lda checksum+3 - cp b - jr nz,+ - - jp reset_crc - -+ call print_crc - jp test_failed - - -; Updates checksum with bytes from addr to addr+size-1 -.macro checksum_mem ARGS addr,size - ld hl,addr - ld bc,size - call checksum_mem_ -.endm - -checksum_mem_: -- ldi a,(hl) - call update_crc - dec bc - ld a,b - or c - jr nz,- - ret diff --git a/playing-coffee - Copy/roms/dmg_sound/source/linkfile b/playing-coffee - Copy/roms/dmg_sound/source/linkfile deleted file mode 100644 index 02a5a2e..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/linkfile +++ /dev/null @@ -1,2 +0,0 @@ -[objects] -test.o diff --git a/playing-coffee - Copy/roms/dmg_sound/source/readme.txt b/playing-coffee - Copy/roms/dmg_sound/source/readme.txt deleted file mode 100644 index a0269c1..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/readme.txt +++ /dev/null @@ -1,82 +0,0 @@ -Game Boy Tests Source Code --------------------------- - -Building with wla-dx --------------------- -To assemble a test ROM with wla-dx, use the following commands: - - wla -o source_filename_here.s test.o - wlalink linkfile test.gb - -To assemble as a GBS music file: - - wla -o source_filename_here.s test.o -DBUILD_GBS - wlalink linkfile test.gbs - -Note that some tests might only work when built as a ROM or GBS file, -but not both. - -Some tests might include a ROM/GBS that has all the tests combined. -Building such a multi-test is complex and the necessary files aren't -included. - - -Framework ---------- -Each test is in a single source file, and makes use of several library -source files from common/. This framework provides common services and -reduces code to only that which performs the actual test. Virtually all -tests include "shell.inc" at the beginning, which sets things up and -includes all the appropriate library files. - -The reset handler does minimal GB hardware initialization, clears RAM, -sets up the text console, then runs main. Main can exit by returning or -jumping to "exit" with an error code in A. Exit reports the code then -goes into an infinite loop. If the code is 0, it doesn't do anything, -otherwise it reports the code. Code 1 is reported as "Failed", and the -rest as "Error ". - -The default is to build a ROM. Defining BUILD_GBS will build as an GBS. -The other build types aren't supported due to their complexity. I load -the code into RAM at $C000 since my devcart requires it, and I don't -want the normal ROM to differ in any way from what I've tested. This -also allows easy self-modifying code. - -Several routines are available to print values and text to the console. -Most update a running CRC-32 checksum which can be checked with -check_crc, allowing ALL the output to be checked very easily. If the -checksum doesn't match, it is printed, so you can run the code on a GB -and paste the correct checksum into your code. - - -Macros ------- -Some macros are used to make common operations more convenient. The left -is equivalent to the right: - - Macro Equivalent - ------------------------------------- - lda addr ldh a,(addr-$FF00) - - sta addr ldh (addr-$FF00),a - - wreg addr,data ld a,data - ldh (addr-$FF00),a - - setb ld a,data - ld (addr),a - - setw setb addr+0,data - - for_loop routine,begin,end,step - calls routine with A set to successive values - - loop_n_times routine,count - calls routine with A from 0 to count-1 - - print_str "str" prints string - - --- -Shay Green diff --git a/playing-coffee - Copy/roms/dmg_sound/source/shell.inc b/playing-coffee - Copy/roms/dmg_sound/source/shell.inc deleted file mode 100644 index 0d43faa..0000000 --- a/playing-coffee - Copy/roms/dmg_sound/source/shell.inc +++ /dev/null @@ -1,27 +0,0 @@ -; Included at beginning of all programs -; that use standard shell - -; Get include files from common/ -.incdir "common" - -; Sub-test in a multi-test ROM -.ifdef BUILD_MULTI - .include "build_multi.s" -.else - -; GBS music file -.ifdef BUILD_GBS - .include "build_gbs.s" -.endif - -; Devcart -.ifdef BUILD_DEVCART - .include "build_devcart.s" -.endif - -; GB ROM (default) -.ifndef RUNTIME_INCLUDED - .include "build_rom.s" -.endif - -.endif ; .ifdef BUILD_MULTI diff --git a/playing-coffee - Copy/roms/drmario.gb b/playing-coffee - Copy/roms/drmario.gb deleted file mode 100644 index 2f3dc69..0000000 Binary files a/playing-coffee - Copy/roms/drmario.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/halt_bug.gb b/playing-coffee - Copy/roms/halt_bug.gb deleted file mode 100644 index 38e3662..0000000 Binary files a/playing-coffee - Copy/roms/halt_bug.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/instr_timing/instr_timing.gb b/playing-coffee - Copy/roms/instr_timing/instr_timing.gb deleted file mode 100644 index 61d2b20..0000000 Binary files a/playing-coffee - Copy/roms/instr_timing/instr_timing.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/instr_timing/readme.txt b/playing-coffee - Copy/roms/instr_timing/readme.txt deleted file mode 100644 index b64024f..0000000 --- a/playing-coffee - Copy/roms/instr_timing/readme.txt +++ /dev/null @@ -1,139 +0,0 @@ -Game Boy CPU Instruction Timing Test ------------------------------------- -This ROM tests the timings of all CPU instructions except HALT, STOP, -and the 11 illegal opcodes. For conditional instructions, it tests taken -and not taken timings. This test requires proper timer operation (TAC, -TIMA, TMA). - -Failed instructions are listed as - - [CB] opcode:measured time-correct time - -Times are in terms of instruction cycles, where NOP takes one cycle. - - -Verified cycle timing tables ----------------------------- -The test internally uses a table of proper cycle times, which can be -used in an emulator to ensure proper timing. The only changes below are -removal of the .byte prefixes, and addition of commas at the ends, so -that they can be used without changes in most programming languages. For -added correctness assurance, the original tables can be found at the end -of the source code. - -Normal instructions: - - 1,3,2,2,1,1,2,1,5,2,2,2,1,1,2,1, - 0,3,2,2,1,1,2,1,3,2,2,2,1,1,2,1, - 2,3,2,2,1,1,2,1,2,2,2,2,1,1,2,1, - 2,3,2,2,3,3,3,1,2,2,2,2,1,1,2,1, - 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1, - 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1, - 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1, - 2,2,2,2,2,2,0,2,1,1,1,1,1,1,2,1, - 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1, - 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1, - 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1, - 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1, - 2,3,3,4,3,4,2,4,2,4,3,0,3,6,2,4, - 2,3,3,0,3,4,2,4,2,4,3,0,3,0,2,4, - 3,3,2,0,0,4,2,4,4,1,4,0,0,0,2,4, - 3,3,2,1,0,4,2,4,3,2,4,1,0,0,2,4 - -CB-prefixed instructions: - - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2, - 2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2, - 2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2, - 2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2, - 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - - -Internal operation ------------------- -Before each instruction is executed, the test sets up registers and -memory in such a way that the instruction will cleanly execute and then -end up at a common destination, without trashing anything important. The -timing itself is done by first synchronizing to the timer via a loop, -executing the instruction, then using a similar loop to determine how -many clocks elapsed. - - -Failure codes -------------- -Failed tests may print a failure code, and also short description of the -problem. For more information about a failure code, look in the -corresponding source file in source/; the point in the code where -"set_test n" occurs is where that failure code will be generated. -Failure code 1 is a general failure of the test; any further information -will be printed. - -Note that once a sub-test fails, no further tests for that file are run. - - -Console output --------------- -Information is printed on screen in a way that needs only minimum LCD -support, and won't hang if LCD output isn't supported at all. -Specifically, while polling LY to wait for vblank, it will time out if -it takes too long, so LY always reading back as the same value won't -hang the test. It's also OK if scrolling isn't supported; in this case, -text will appear starting at the top of the screen. - -Everything printed on screen is also sent to the game link port by -writing the character to SB, then writing $81 to SC. This is useful for -tests which print lots of information that scrolls off screen. - - -Source code ------------ -Source code is included for all tests, in source/. It can be used to -build the individual test ROMs. Code for the multi test isn't included -due to the complexity of putting everything together. - -Code is written for the wla-dx assembler. To assemble a particular test, -execute - - wla -o "source_filename.s" test.o - wlalink linkfile test.gb - -Test code uses a common shell framework contained in common/. - - -Internal framework operation ----------------------------- -Tests use a common framework for setting things up, reporting results, -and ending. All files first include "shell.inc", which sets up the ROM -header and shell code, and includes other commonly-used modules. - -One oddity is that test code is first copied to internal RAM at $D000, -then executed there. This allows self-modification, and ensures the code -is executed the same way it is on my devcart, which doesn't have a -rewritable ROM as most do. - -Some macros are used to simplify common tasks: - - Macro Behavior - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wreg addr,data Writes data to addr using LDH - lda addr Loads byte from addr into A using LDH - sta addr Stores A at addr using LDH - delay n Delays n cycles, where NOP = 1 cycle - delay_msec n Delays n milliseconds - set_test n,"Cause" Sets failure code and optional string - -Routines and macros are documented where they are defined. - --- -Shay Green diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/build_gbs.s b/playing-coffee - Copy/roms/instr_timing/source/common/build_gbs.s deleted file mode 100644 index 7ac8d3c..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/build_gbs.s +++ /dev/null @@ -1,121 +0,0 @@ -; Build as GBS music file - -.memoryMap - defaultSlot 0 - slot 0 $3000 size $1000 - slot 1 $C000 size $1000 -.endMe - -.romBankSize $1000 -.romBanks 2 - - -;;;; GBS music file header - -.byte "GBS" -.byte 1 ; vers -.byte 1 ; songs -.byte 1 ; first song -.word load_addr -.word reset -.word gbs_play -.word std_stack -.byte 0,0 ; timer -.ds $60,0 -load_addr: - -; WLA assumes we're building ROM and messes -; with bytes at the beginning, so skip them. -.ds $100,0 - - -;;;; Shell - -.include "runtime.s" - -init_runtime: - ld a,$01 ; Identify as DMG hardware - ld (gb_id),a - .ifdef TEST_NAME - print_str TEST_NAME,newline,newline - .endif - ret - -std_print: - sta SB - wreg SC,$81 - delay 2304 - ret - -post_exit: - call play_byte -forever: - wreg NR52,0 ; sound off -- jp - - -.ifndef CUSTOM_RESET - gbs_play: -.endif -console_flush: -console_normal: -console_inverse: -console_set_mode: - ret - -; Reports A in binary as high and low tones, with -; leading low tone for reference. Omits leading -; zeroes. -; Preserved: AF, BC, DE, HL -play_byte: - push af - push hl - - ; HL = (A << 1) | 1 - scf - rla - ld l,a - ld h,0 - rl h - - ; Shift left until next-to-top bit is 1 -- add hl,hl - bit 6,h - jr z,- - - ; Reset sound - delay_msec 400 - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - -- add hl,hl - - ; Low or high pitch based on bit shifted out - ; of HL - ld a,0 - jr nc,+ - ld a,$FF -+ sta NR23 - - ; Play short tone - wreg NR21,$A0 - wreg NR22,$F0 - wreg NR24,$86 - delay_msec 75 - wreg NR22,0 - wreg NR23,$F8 - wreg NR24,$87 - delay_msec 200 - - ; Loop until HL = $8000 - ld a,h - xor $80 - or l - jr nz,- - - pop hl - pop af - ret - -.ends diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/build_rom.s b/playing-coffee - Copy/roms/instr_timing/source/common/build_rom.s deleted file mode 100644 index e1e220f..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/build_rom.s +++ /dev/null @@ -1,80 +0,0 @@ -; Build as GB ROM - -.memoryMap - defaultSlot 0 - slot 0 $0000 size $4000 - slot 1 $C000 size $4000 -.endMe - -.romBankSize $4000 ; generates $8000 byte ROM -.romBanks 2 - -.cartridgeType 1 ; MBC1 -.computeChecksum -.computeComplementCheck - - -;;;; GB ROM header - -; GB header read by bootrom -.org $100 - nop - jp reset - -; Nintendo logo required for proper boot -.byte $CE,$ED,$66,$66,$CC,$0D,$00,$0B -.byte $03,$73,$00,$83,$00,$0C,$00,$0D -.byte $00,$08,$11,$1F,$88,$89,$00,$0E -.byte $DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 -.byte $BB,$BB,$67,$63,$6E,$0E,$EC,$CC -.byte $DD,$DC,$99,$9F,$BB,$B9,$33,$3E - -; Internal name -.ifdef ROM_NAME - .byte ROM_NAME -.endif - -; CGB/DMG requirements -.org $143 - .ifdef REQUIRE_CGB - .byte $C0 - .else - .ifndef REQUIRE_DMG - .byte $80 - .endif - .endif - -.org $200 - - -;;;; Shell - -.include "runtime.s" -.include "console.s" - -init_runtime: - call console_init - .ifdef TEST_NAME - print_str TEST_NAME,newline,newline - .endif - ret - -std_print: - push af - sta SB - wreg SC,$81 - delay 2304 - pop af - jp console_print - -post_exit: - call console_show - call play_byte -forever: - wreg NR52,0 ; sound off -- jr - - -play_byte: - ret - -.ends diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/console.bin b/playing-coffee - Copy/roms/instr_timing/source/common/console.bin deleted file mode 100644 index b02f2d3..0000000 Binary files a/playing-coffee - Copy/roms/instr_timing/source/common/console.bin and /dev/null differ diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/console.s b/playing-coffee - Copy/roms/instr_timing/source/common/console.s deleted file mode 100644 index 5307f6b..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/console.s +++ /dev/null @@ -1,291 +0,0 @@ -; Scrolling text console - -; Console is 20x18 characters. Buffers lines, so -; output doesn't appear until a newline or flush. -; If scrolling isn't supported (i.e. SCY is treated -; as if always zero), the first 18 lines will -; still print properly). Also works properly if -; LY isn't supported (always reads back as the same -; value). - -.define console_width 20 - -.define console_buf bss+0 -.define console_pos bss+console_width -.define console_mode bss+console_width+1 -.define console_scroll bss+console_width+2 -.redefine bss bss+console_width+3 - - -; Waits for start of LCD blanking period -; Preserved: BC, DE, HL -console_wait_vbl: - push bc - - ; Wait for start of vblank, with - ; timeout in case LY doesn't work - ; or LCD is disabled. - ld bc,-1250 -- inc bc - ld a,b - or c - jr z,@timeout - lda LY - cp 144 - jr nz,- -@timeout: - - pop bc - ret - - -; Initializes text console -console_init: - call console_hide - - ; CGB-specific inits - ld a,(gb_id) - and gb_id_cgb - call nz,@init_cgb - - ; Clear nametable - ld a,' ' - call @fill_nametable - - ; Load tiles - ld hl,TILES+$200 - ld c,0 - call @load_tiles - ld hl,TILES+$A00 - ld c,$FF - call @load_tiles - - ; Init state - ld a,console_width - ld (console_pos),a - ld a,0 - ld (console_mode),a - ld a,-8 - ld (console_scroll),a - call console_scroll_up_ - jr console_show - -@fill_nametable: - ld hl,BGMAP0 - ld b,4 -- ld (hl),a - inc l - jr nz,- - inc h - dec b - jr nz,- - ret - -@init_cgb: - ; Clear palette - wreg $FF68,$80 - ld b,16 -- wreg $FF69,$FF - wreg $FF69,$7F - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - dec b - jr nz,- - - ; Clear attributes - ld a,1 - ld (VBK),a - ld a,0 - call @fill_nametable - - ld a,0 - ld (VBK),a - ret - -@load_tiles: - ld de,ASCII - ld b,96 --- push bc - ld b,8 -- ld a,(de) - inc de - xor c - ldi (hl),a - ldi (hl),a - dec b - jr nz,- - pop bc - dec b - jr nz,-- - ret - - -; Shows console display -; Preserved: AF, BC, DE, HL -console_show: - push af - - ; Enable LCD - call console_wait_vbl - wreg LCDC,$91 - wreg SCX,0 - wreg BGP,$E4 - - jp console_apply_scroll_ - - -; Hides console display by turning LCD off -; Preserved: AF, BC, DE, HL -console_hide: - push af - - ; LCD off - call console_wait_vbl - wreg LCDC,$11 - - pop af - ret - - -; Changes to normal text mode -; Preserved: BC, DE, HL -console_normal: - xor a - jr console_set_mode - -; Changes to inverse text mode -; Preserved: BC, DE, HL -console_inverse: - ld a,$80 - -; Changes console mode to A. -; 0: Normal, $80: Inverse -; Preserved: BC, DE, HL -console_set_mode: - and $80 - ld (console_mode),a - ret - - -; Prints char A to console. Will not appear until -; a newline or flush occurs. -; Preserved: AF, BC, DE, HL -console_print: - push af - - cp 10 - jr z,console_newline_ - - push hl - push af - ld hl,console_pos - ldi a,(hl) - cp BGMAP0) >> 2 - add hl,hl - add hl,hl - - ; Copy line - ld de,console_buf + console_width -- dec e - ld a,(de) - ldi (hl),a - ld a,e - cp checksum - ldi (hl),a - ld (hl),d - inc l - ld (hl),c - inc l - ld (hl),b - - pop hl - pop de - pop bc - pop af - ret diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/delay.s b/playing-coffee - Copy/roms/instr_timing/source/common/delay.s deleted file mode 100644 index 65eb9c0..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/delay.s +++ /dev/null @@ -1,220 +0,0 @@ -; Delays in cycles, milliseconds, etc. - -; All routines are re-entrant (no global data). Routines never -; touch BC, DE, or HL registers. These ASSUME CPU is at normal -; speed. If running at double speed, msec/usec delays are half advertised. - -; Delays n cycles, from 0 to 16777215 -; Preserved: AF, BC, DE, HL -.macro delay ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 16777215 - .printt "Delay must be < 16777216" - .fail - .endif - delay_ n&$FFFF, n>>16 -.endm - -; Delays n clocks, from 0 to 16777216*4. Must be multiple of 4. -; Preserved: AF, BC, DE, HL -.macro delay_clocks ARGS n - .if n # 4 != 0 - .printt "Delay must be a multiple of 4" - .fail - .endif - delay_ (n/4)&$FFFF,(n/4)>>16 -.endm - -; Delays n microseconds (1/1000000 second) -; n can range from 0 to 4000 usec. -; Preserved: AF, BC, DE, HL -.macro delay_usec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 4000 - .printt "Delay must be <= 4000 usec" - .fail - .endif - delay_ ((n * 1048576 + 500000) / 1000000)&$FFFF,((n * 1048576 + 500000) / 1000000)>>16 -.endm - -; Delays n milliseconds (1/1000 second) -; n can range from 0 to 10000 msec. -; Preserved: AF, BC, DE, HL -.macro delay_msec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 10000 - .printt "Delay must be <= 10000 msec" - .fail - .endif - delay_ ((n * 1048576 + 500) / 1000)&$FFFF, ((n * 1048576 + 500) / 1000)>>16 -.endm - - ; All the low/high quantities are to deal wla-dx's asinine - ; restriction full expressions must evaluate to a 16-bit - ; value. If the author ever rectifies this, all "high" - ; arguments can be treated as zero and removed. Better yet, - ; I'll just find an assembler that didn't crawl out of - ; the sewer (this is one of too many bugs I've wasted - ; hours working around). - - .define max_short_delay 28 - - .macro delay_long_ ARGS n, high - ; 0+ to avoid assembler treating as memory read - ld a,0+(((high<<16)+n) - 11) >> 16 - call delay_65536a_9_cycles_ - delay_nosave_ (((high<<16)+n) - 11)&$FFFF, 0 - .endm - - ; Doesn't save AF, allowing minimization of AF save/restore - .macro delay_nosave_ ARGS n, high - ; 65536+11 = maximum delay using delay_256a_9_cycles_ - ; 255+22 = maximum delay using delay_a_20_cycles - ; 22 = minimum delay using delay_a_20_cycles - .if high > 1 - delay_long_ n, high - .else - .if high*n > 11 - delay_long_ n, high - .else - .if (high*(255+22+1))|n > 255+22 - ld a,>(((high<<16)+n) - 11) - call delay_256a_9_cycles_ - delay_nosave_ <(((high<<16)+n) - 11), 0 - .else - .if n >= 22 - ld a,n - 22 - call delay_a_20_cycles - .else - delay_short_ n - .endif - .endif - .endif - .endif - .endm - - .macro delay_ ARGS low, high - .if (high*(max_short_delay+1))|low > max_short_delay - push af - delay_nosave_ ((high<<16)+low - 7)&$FFFF, ((high<<16)+low - 7)>>16 - pop af - .else - delay_short_ low - .endif - .endm - - -; Delays A cycles + overhead -; Preserved: BC, DE, HL -; Time: A+20 cycles (including CALL) -delay_a_20_cycles: -- sub 5 ; 2 - jr nc,- ;3/2 do multiples of 5 - rra ; 1 - jr nc,+ ;3/2 bit 0 -+ adc 1 ; 2 - ret nc ;5/2 -1: 0 cycles - ret z ;5/2 0: 2 cycles - nop ; 1 1: 4 cycles - ret ; 4 (thanks to dclxvi for original algorithm) - -; Delays A*256 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*256+12 cycles (including CALL) -delay_256a_12_cycles: - or a ; 1 - ret z ; 5/2 -delay_256a_9_cycles_: -- delay 256-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays A*65536 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*65536+12 cycles (including CALL) -delay_65536a_12_cycles: - or a ; 1 - ret z ;5/2 -delay_65536a_9_cycles_: -- delay 65536-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays H*256+L cycles + overhead -; Preserved: AF, BC, DE, HL -; Time: H*256+L+51 cycles -delay_hl_51_cycles: - push af - ld a,h - call delay_256a_12_cycles - ld a,l - call delay_a_20_cycles - pop af - ret - - ; delay_short_ macro calls into these - .ds max_short_delay-10,$00 ; NOP repeated several times -delay_unrolled_: - ret - -.macro delay_short_ ARGS n - .if n < 0 - .fail - .endif - .if n > max_short_delay - .fail - .endif - - .if n == 1 - nop - .endif - .if n == 2 - nop - nop - .endif - .if n == 3 - .byte $18,$00 ; JR +0 - .endif - .if n == 4 - .byte $18,$00 ; JR +0 - nop - .endif - .if n == 5 - .byte $18,$00 ; JR +0 - nop - nop - .endif - .if n == 6 - .byte $18,$00 ; JR +0 - .byte $18,$00 ; JR +0 - .endif - .if n == 7 - push af - pop af - .endif - .if n == 8 - push af - pop af - nop - .endif - .if n == 9 - push af - pop af - nop - nop - .endif - .if n >= 10 - call delay_unrolled_ + 10 - n - .endif -.endm diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/gb.inc b/playing-coffee - Copy/roms/instr_timing/source/common/gb.inc deleted file mode 100644 index 31bbf14..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/gb.inc +++ /dev/null @@ -1,64 +0,0 @@ -; Game Boy hardware addresses - -; Memory -.define VRAM $8000 ; video memory -.define TILES $8000 ; tile images -.define BGMAP0 $9800 ; first 32x32 tilemap -.define BGMAP1 $9C00 ; second 32x32 tilemap -.define WRAM $C000 ; internal memory -.define OAM $FE00 ; sprite memory -.define HRAM $FF80 ; fast memory for LDH - -.define P1 $FF00 - -; Game link I/O -.define SB $FF01 -.define SC $FF02 - -; Interrupts -.define DIV $FF04 -.define TIMA $FF05 -.define TMA $FF06 -.define TAC $FF07 -.define IF $FF0F -.define IE $FFFF - -; LCD registers -.define LCDC $FF40 ; control -.define STAT $FF41 ; status -.define SCY $FF42 ; scroll Y -.define SCX $FF43 ; scroll X -.define LY $FF44 ; current Y being rendered -.define BGP $FF47 - -.define KEY1 $FF4D ; for changing CPU speed -.define VBK $FF4F - -; Sound registers -.define NR10 $FF10 -.define NR11 $FF11 -.define NR12 $FF12 -.define NR13 $FF13 -.define NR14 $FF14 - -.define NR21 $FF16 -.define NR22 $FF17 -.define NR23 $FF18 -.define NR24 $FF19 - -.define NR30 $FF1A -.define NR31 $FF1B -.define NR32 $FF1C -.define NR33 $FF1D -.define NR34 $FF1E - -.define NR41 $FF20 -.define NR42 $FF21 -.define NR43 $FF22 -.define NR44 $FF23 - -.define NR50 $FF24 -.define NR51 $FF25 -.define NR52 $FF26 - -.define WAVE $FF30 diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/macros.inc b/playing-coffee - Copy/roms/instr_timing/source/common/macros.inc deleted file mode 100644 index c413bd5..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/macros.inc +++ /dev/null @@ -1,73 +0,0 @@ -; General macros - -; Reads A from addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 3 cycles -.macro lda ARGS addr - ldh a,(addr - $FF00) -.endm - -; Writes A to addr, from $FF00 to $FFFF -; Preserved: AF, BC, DE, HL -; Time: 3 cycles -.macro sta ARGS addr - ldh (addr - $FF00),a -.endm - -; Writes immediate data to addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 5 cycles -.macro wreg ARGS addr, data - ld a,data - sta addr -.endm - -; Calls routine multiple times, with A having the -; value 'start' the first time, 'start+step' the -; second time, up to 'end' for the last time. -; Preserved: BC, DE, HL -.macro for_loop ; routine,start,end,step - ld a,\2 - -for_loop\@: - push af - call \1 - pop af - - add \4 - cp <(\3 + \4) - jr nz,for_loop\@ -.endm - -; Calls routine n times. The value of A in the routine -; counts from 0 to n-1. -; Preserved: BC, DE, HL -.macro loop_n_times ; routine,n - for_loop \1,0,\2 - 1,+1 -.endm - -; Same as for_loop, but counts with 16-bit value in BC. -; Preserved: DE, HL -.macro for_loop16 ; routine,start,end,step - ld bc,\2 - -for_loop16\@: - push bc - call \1 - pop bc - - ld a,c - add <\4 - ld c,a - - ld a,b - adc >\4 - ld b,a - - cp >(\3+\4) - jr nz,for_loop16\@ - - ld a,c - cp <(\3+\4) - jr nz,for_loop16\@ -.endm diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/numbers.s b/playing-coffee - Copy/roms/instr_timing/source/common/numbers.s deleted file mode 100644 index 6d6faf8..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/numbers.s +++ /dev/null @@ -1,177 +0,0 @@ -; Printing of numeric values - -; Prints value of indicated register/pair -; as 2/4 hex digits, followed by a space. -; Updates checksum with printed values. -; Preserved: AF, BC, DE, HL - -print_regs: - call print_af - call print_bc - call print_de - call print_hl - call print_newline - ret - -print_a: - push af -print_a_: - call print_hex - ld a,' ' - call print_char_nocrc - pop af - ret - -print_af: - push af - call print_hex - pop af -print_f: - push bc - push af - pop bc - call print_c - pop bc - ret - -print_b: - push af - ld a,b - jr print_a_ - -print_c: - push af - ld a,c - jr print_a_ - -print_d: - push af - ld a,d - jr print_a_ - -print_e: - push af - ld a,e - jr print_a_ - -print_h: - push af - ld a,h - jr print_a_ - -print_l: - push af - ld a,l - jr print_a_ - -print_bc: - push af - push bc -print_bc_: - ld a,b - call print_hex - ld a,c - pop bc - jr print_a_ - -print_de: - push af - push bc - ld b,d - ld c,e - jr print_bc_ - -print_hl: - push af - push bc - ld b,h - ld c,l - jr print_bc_ - - -; Prints A as two hex chars and updates checksum -; Preserved: BC, DE, HL -print_hex: - call update_crc -print_hex_nocrc: - push af - swap a - call + - pop af - -+ and $0F - cp 10 - jr c,+ - add 7 -+ add '0' - jp print_char_nocrc - - -; Prints char_nz if Z flag is clear, -; char_z if Z flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nz ARGS char_nz, char_z - push af - ld a,char_nz - jr nz,print_nz\@ - ld a,char_z -print_nz\@: - call print_char - pop af -.endm - - -; Prints char_nc if C flag is clear, -; char_c if C flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nc ARGS char_nc, char_c - push af - ld a,char_nc - jr nz,print_nc\@ - ld a,char_c -print_nc\@: - call print_char - pop af -.endm - - -; Prints A as 2 decimal digits -; Preserved: AF, BC, DE, HL -print_dec2: - push af - push bc - jr + - - -; Prints A as 1-3 digit decimal value -; Preserved: AF, BC, DE, HL -print_dec: - push af - push bc - - cp 10 - jr c,++ - ld c,100 - cp c - call nc,@digit -+ ld c,10 - call @digit -++ add '0' - call print_char - - pop bc - pop af - ret - -@digit: - ld b,'0'-1 -- inc b - sub c - jr nc,- - add c - - ld c,a - ld a,b - call print_char - ld a,c - ret diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/printing.s b/playing-coffee - Copy/roms/instr_timing/source/common/printing.s deleted file mode 100644 index ad9d811..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/printing.s +++ /dev/null @@ -1,98 +0,0 @@ -; Main printing routine that checksums and -; prints to output device - -; Character that does equivalent of print_newline -.define newline 10 - -; Prints char without updating checksum -; Preserved: BC, DE, HL -.define print_char_nocrc bss -.redefine bss bss+3 - - -; Initializes printing. HL = print routine -init_printing: - ld a,l - ld (print_char_nocrc+1),a - ld a,h - ld (print_char_nocrc+2),a - jr show_printing - - -; Hides/shows further printing -; Preserved: BC, DE, HL -hide_printing: - ld a,$C9 ; RET - jr + -show_printing: - ld a,$C3 ; JP (nn) -+ ld (print_char_nocrc),a - ret - - -; Prints character and updates checksum UNLESS -; it's a newline. -; Preserved: AF, BC, DE, HL -print_char: - push af - cp newline - call nz,update_crc - call print_char_nocrc - pop af - ret - - -; Prints space. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_space: - push af - ld a,' ' - call print_char_nocrc - pop af - ret - - -; Advances to next line. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_newline: - push af - ld a,newline - call print_char_nocrc - pop af - ret - - -; Prints immediate string -; Preserved: AF, BC, DE, HL -.macro print_str ; string,string2 - push hl - call print_str_ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 - pop hl -.endm - -print_str_: - pop hl - call print_str_hl - jp hl - - -; Prints zero-terminated string pointed to by HL. -; On return, HL points to byte AFTER zero terminator. -; Preserved: AF, BC, DE -print_str_hl: - push af - jr + -- call print_char -+ ldi a,(hl) - or a - jr nz,- - pop af - ret diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/runtime.s b/playing-coffee - Copy/roms/instr_timing/source/common/runtime.s deleted file mode 100644 index 90cd24f..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/runtime.s +++ /dev/null @@ -1,142 +0,0 @@ -; Common routines and runtime - -; Must be defined by target-specific runtime: -; -; init_runtime: ; target-specific inits -; std_print: ; default routine to print char A -; post_exit: ; called at end of std_exit -; report_byte: ; report A to user - -.define RUNTIME_INCLUDED 1 - -.ifndef bss - ; address of next normal variable - .define bss $D800 -.endif - -.ifndef dp - ; address of next direct-page ($FFxx) variable - .define dp $FF80 -.endif - -; DMG/CGB hardware identifier -.define gb_id_cgb $10 ; mask for testing CGB bit -.define gb_id_devcart $04 ; mask for testing "on devcart" bit - -.define gb_id bss -.redefine bss bss+1 - -; Stack is normally here -.define std_stack $DFFF - -; Copies $1000 bytes from HL to $C000, then jumps to it. -; A is preserved for jumped-to code. -copy_to_wram_then_run: - ld b,a - - ld de,$C000 - ld c,$10 -- ldi a,(hl) - ld (de),a - inc e - jr nz,- - inc d - dec c - jr nz,- - - ld a,b - jp $C000 - -.ifndef CUSTOM_RESET - reset: - ; Run code from $C000, as is done on devcart. This - ; ensures minimal difference in how it behaves. - ld hl,$4000 - jp copy_to_wram_then_run - - .bank 1 slot 1 - .org $0 ; otherwise wla pads with lots of zeroes - jp std_reset -.endif - -; Common routines -.include "gb.inc" -.include "macros.inc" -.include "delay.s" -.include "crc.s" -.include "printing.s" -.include "numbers.s" -.include "testing.s" - -; Sets up hardware and runs main -std_reset: - - ; Init hardware - di - ld sp,std_stack - - ; Save DMG/CGB id - ld (gb_id),a - - ; Init hardware - .ifndef BUILD_GBS - wreg TAC,$00 - wreg IF,$00 - wreg IE,$00 - .endif - - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - - ; TODO: clear all memory? - - ld hl,std_print - call init_printing - call init_testing - call init_runtime - call reset_crc ; in case init_runtime prints anything - - delay_msec 250 - - ; Run user code - call main - - ; Default is to successful exit - ld a,0 - jp exit - - -; Exits code and reports value of A -exit: - ld sp,std_stack - push af - call + - pop af - jp post_exit - -+ push af - call print_newline - call show_printing - pop af - - ; Report exit status - cp 1 - - ; 0: "" - ret c - - ; 1: "Failed" - jr nz,+ - print_str "Failed",newline - ret - - ; n: "Failed #n" -+ print_str "Failed #" - call print_dec - call print_newline - ret - -; returnOrg puts this code AFTER user code. -.section "runtime" returnOrg diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/testing.s b/playing-coffee - Copy/roms/instr_timing/source/common/testing.s deleted file mode 100644 index c102f78..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/testing.s +++ /dev/null @@ -1,176 +0,0 @@ -; Diagnostic and testing utilities - -.define result bss+0 -.define test_name bss+1 -.redefine bss bss+3 - - -; Sets test code and optional error text -; Preserved: AF, BC, DE, HL -.macro set_test ; code[,text[,text2]] - push hl - call set_test_ - jr @set_test\@ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 -@set_test\@: - pop hl -.endm - -set_test_: - pop hl - push hl - push af - inc hl - inc hl - ldi a,(hl) - ld (result),a - ld a,l - ld (test_name),a - ld a,h - ld (test_name+1),a - pop af - ret - - -; Initializes testing module -init_testing: - set_test $FF - call init_crc - ret - - -; Reports "Passed", then exits with code 0 -tests_passed: - call print_newline - print_str "Passed" - ld a,0 - jp exit - - -; Reports "Done" if set_test has never been used, -; "Passed" if set_test 0 was last used, or -; failure if set_test n was last used. -tests_done: - ld a,(result) - inc a - jr z,+ - dec a - jr z,tests_passed - jr test_failed -+ print_str "Done" - ld a,0 - jp exit - - -; Reports current error text and exits with result code -test_failed: - ld a,(test_name) - ld l,a - ld a,(test_name+1) - ld h,a - ld a,(hl) - or a - jr z,+ - call print_newline - call print_str_hl - call print_newline -+ - ld a,(result) - cp 1 ; if a = 0 then a = 1 - adc 0 - jp exit - - -; Prints checksum as 8-character hex value -; Preserved: AF, BC, DE, HL -print_crc: - push af - - ; Must read checksum entirely before printing, - ; since printing updates it. - lda checksum - cpl - push af - - lda checksum+1 - cpl - push af - - lda checksum+2 - cpl - push af - - lda checksum+3 - cpl - - call print_hex - pop af - call print_hex - pop af - call print_hex - pop af - call print_a - - pop af - ret - - -; If checksum doesn't match expected, reports failed test. -; Passing 0 just prints checksum. Clears checksum afterwards. -.macro check_crc ARGS crc - .if crc == 0 - call show_printing - call print_newline - call print_crc - .else - ld bc,(crc >> 16) ~ $FFFF - ld de,(crc & $FFFF) ~ $FFFF - call check_crc_ - .endif -.endm - -check_crc_: - lda checksum+0 - cp e - jr nz,+ - - lda checksum+1 - cp d - jr nz,+ - - lda checksum+2 - cp c - jr nz,+ - - lda checksum+3 - cp b - jr nz,+ - - jp reset_crc - -+ call print_crc - jp test_failed - - -; Updates checksum with bytes from addr to addr+size-1 -.macro checksum_mem ARGS addr,size - ld hl,addr - ld bc,size - call checksum_mem_ -.endm - -checksum_mem_: -- ldi a,(hl) - call update_crc - dec bc - ld a,b - or c - jr nz,- - ret diff --git a/playing-coffee - Copy/roms/instr_timing/source/common/timer.s b/playing-coffee - Copy/roms/instr_timing/source/common/timer.s deleted file mode 100644 index 32c713e..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/common/timer.s +++ /dev/null @@ -1,88 +0,0 @@ -; Cycle-accurate timer - -; TIMA is incremented every 4 cycles. Loops -; check for increment within 3-cycle window, -; so when it occurs outside this, loop is -; exactly synchronized. Loop iterations are -; one more or less than 12 cycles, so they -; will never run more than 4 times. - -; Initializes timer -; Preserved: AF, BC, DE, HL -init_timer: - push af - di - lda IE ; disable timer interrupt - and ~$04 - sta IE - wreg TMA,0 ; max period - wreg TAC,$05 ; 262144 Hz - - ; Be sure timer doesn't expire - ; immediately or take too long - wreg IF,0 - wreg TIMA,-20 - delay 70 - lda IF - and $04 - jp nz,test_failed - lda IF - and $04 - jp z,test_failed - - pop af - ret - - -; Starts timer -; Preserved: AF, BC, DE, HL -start_timer: - push af - -- xor a ; 1 - sta TIMA ; 3 - lda TIMA ; 3 - or a ; 1 - jr nz,- ; 3 - - pop af - ret - - -; Stops timer and determines cycles since -; it was started. A = cycles (0 to 255). -; Preserved: BC, DE, HL -stop_timer: - push de - call stop_timer_word - ld a,e - sub 10 - pop de - ret - - -; Same as stop_timer, but with greater range. -; DE = cycles (0 to 1019). -; Preserved: BC, HL -stop_timer_word: - - ld d,0 - - ; Get main count (TIMA*4) - lda TIMA - sub 5 - add a - rl d - add a - rl d - ld e,a - - ; One iteration per remaining cycle -- xor a ; 1 - sta TIMA ; 3 - lda TIMA ; 3 - dec de ; 2 - or a ; 1 - jr nz,- ; 3 - - ret diff --git a/playing-coffee - Copy/roms/instr_timing/source/instr_timing.s b/playing-coffee - Copy/roms/instr_timing/source/instr_timing.s deleted file mode 100644 index b6b7338..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/instr_timing.s +++ /dev/null @@ -1,336 +0,0 @@ -; Tests number of cycles taken by instructions -; except STOP, HALT, and illegals. - -.include "shell.inc" -.include "timer.s" - -.define saved_sp bss+0 -.define instr bss+2 ; 3-byte instr + JP instr_end -.define instr_addr bss+8 ; JP instr_end -.redefine bss bss+11 - -main: - call init_timer - call test_timer - set_test 0 - call test_main_ops - call test_cb_ops - jp tests_done - - -; Ensures timer works -test_timer: - call start_timer - call stop_timer - or a - ret z - set_test 2,"Timer doesn't work properly" - jp test_failed - - -; Tests main opcodes -test_main_ops: - ld l,0 -- ld h,>op_times - ld a,(hl) - cp 0 - call nz,@test_op - inc l - jr nz,- - ret - -@test_op: - ; Can't test the 8 RST instructions on devcart - ld a,l - cpl - and $C7 - jr nz,+ - ld a,(gb_id) - and gb_id_devcart - ret nz -+ - ; Test with flags set so that branches are - ; not taken - ld a,l ; e = (l & 0x08 ? 0 : 0xFF) - and $08 - add $F8 - ld e,a - call @copy_and_exec - ld d,0 - cp (hl) - jr z,+ - ld d,a - call print_failed_opcode -+ - - ; Time with branches not taken - ld a,e - cpl - ld e,a - call @copy_and_exec - ld h,>op_times_taken - cp (hl) - ret z - - ; If opcode already failed and timed the - ; same again, avoid re-reporting. - cp d - ret z - - call print_failed_opcode - ret - -@copy_and_exec: - push de - push hl - - ld h,>op_lens - ld c,(hl) - ld a,l - ld hl,instr - ld (hl+),a - dec c - jr z,@one_byte - ld a,0 - dec c - jr z,@two_bytes - ld a,instr_addr -@two_bytes: - ld (hl+),a -@one_byte: - ld a,e - call time_instruction - - pop hl - pop de - ret - - -; Tests CB opcodes -test_cb_ops: - ld hl,cb_op_times -- ld a,(hl) - cp 0 - call nz,@test_op_cb - inc l - jr nz,- - ret - -@test_op_cb: - ; Test with flags clear - ld e,$00 - call @copy_and_exec_cb - cp (hl) - jr nz,+ - - ; Test with flags set - ld e,$FF - call @copy_and_exec_cb - cp (hl) - jr nz,+ - - ret -+ print_str "CB " - call print_failed_opcode - ret - -@copy_and_exec_cb: - push hl - - ; Copy instr to exec space - ld a,l - ld hl,instr+1 - ld (hl+),a - ld a,$CB - ld (instr),a - call time_instruction - - pop hl - ret - - -; Reports failed opcode -; L -> opcode -; A -> cycles it took -; (HL) -> cycles it should have taken -; Preserved: HL -print_failed_opcode: - ; Print opcode - push af - ld a,l - call print_hex - ld a,':' - call print_char - pop af - - ; Print actual and correct times - call print_dec - ld a,'-' - call print_char - ld a,(hl) - call print_dec - ld a,' ' - call print_char - - ; Remember that failure occurred - set_test 1 - - ret - - -; Times instruction. -; HL -> address of byte just after instruction -; A -> flags when executing instruction -; A <- number of cycles instruction took -time_instruction: - ld c,a - - ; Write JP instr_end to HL and instr_addr - ld a,$C3 ; JP - ld (hl+),a - ld (instr_addr),a - - ld a,instr_end - ld (instr_addr+2),a - ld (hl),a - - ; Save sp - ld (saved_sp),sp - - ; Set regs and stack contents - push bc - ld bc,instr_addr - ld de,instr_addr - ld hl,instr_addr - call start_timer - pop af - push hl - - ; Environment instruction executes in: - ; 1 byte: OP - ; 2 byte: OP 00 - ; 3 byte: OP instr_addr - ; BC,DE,HL = instr_addr - ; Stack has instr_addr pushed on it. - ; Stack pointer can be trashed by instr. - ; instr_addr contains JP instr_end, that - ; can be trashed. Instructions which trash - ; this don't execute it. - - jp instr -instr_end: ; instruction jumps here when done - di - - ; Restore sp - ld sp,saved_sp - pop hl - ld sp,hl - - call stop_timer - sub 24 - ret - -.section "page_aligned" align 256 - -; Instruction lengths of opcodes. -; 0 for instructions not timed. -op_lens: - .byte 1,3,1,1,1,1,2,1,3,1,1,1,1,1,2,1 ; 0 - .byte 0,3,1,1,1,1,2,1,2,1,1,1,1,1,2,1 ; 1 - .byte 2,3,1,1,1,1,2,1,2,1,1,1,1,1,2,1 ; 2 - .byte 2,3,1,1,1,1,2,1,2,1,1,1,1,1,2,1 ; 3 - .byte 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 4 - .byte 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 5 - .byte 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 6 - .byte 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 7 - .byte 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 8 - .byte 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; 9 - .byte 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; A - .byte 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; B - .byte 1,1,3,3,3,1,2,1,1,1,3,0,3,3,2,1 ; C - .byte 1,1,3,0,3,1,2,1,1,1,3,0,3,0,2,1 ; D - .byte 2,1,1,0,0,1,2,1,2,1,3,0,0,0,2,1 ; E - .byte 2,1,1,1,0,1,2,1,2,1,3,1,0,0,2,1 ; F - -; Timings for main opcodes -op_times: - .byte 1,3,2,2,1,1,2,1,5,2,2,2,1,1,2,1 - .byte 0,3,2,2,1,1,2,1,3,2,2,2,1,1,2,1 - .byte 2,3,2,2,1,1,2,1,2,2,2,2,1,1,2,1 - .byte 2,3,2,2,3,3,3,1,2,2,2,2,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 2,2,2,2,2,2,0,2,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 2,3,3,4,3,4,2,4,2,4,3,0,3,6,2,4 - .byte 2,3,3,0,3,4,2,4,2,4,3,0,3,0,2,4 - .byte 3,3,2,0,0,4,2,4,4,1,4,0,0,0,2,4 - .byte 3,3,2,1,0,4,2,4,3,2,4,1,0,0,2,4 - -; Timings when conditionals are taken -op_times_taken: - .byte 1,3,2,2,1,1,2,1,5,2,2,2,1,1,2,1 - .byte 0,3,2,2,1,1,2,1,3,2,2,2,1,1,2,1 - .byte 3,3,2,2,1,1,2,1,3,2,2,2,1,1,2,1 - .byte 3,3,2,2,3,3,3,1,3,2,2,2,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 2,2,2,2,2,2,0,2,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1 - .byte 5,3,4,4,6,4,2,4,5,4,4,0,6,6,2,4 - .byte 5,3,4,0,6,4,2,4,5,4,4,0,6,0,2,4 - .byte 3,3,2,0,0,4,2,4,4,1,4,0,0,0,2,4 - .byte 3,3,2,1,0,4,2,4,3,2,4,1,0,0,2,4 - -; Timings for CB-prefixed opcodes -cb_op_times: - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2 - .byte 2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2 - .byte 2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2 - .byte 2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 - .byte 2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2 -.ends - -; RST handlers -.bank 0 slot 0 -.org $00 - jp instr_end -.org $08 - jp instr_end -.org $10 - jp instr_end -.org $18 - jp instr_end -.org $20 - jp instr_end -.org $28 - jp instr_end -.org $30 - jp instr_end -.org $38 - jp instr_end diff --git a/playing-coffee - Copy/roms/instr_timing/source/linkfile b/playing-coffee - Copy/roms/instr_timing/source/linkfile deleted file mode 100644 index 02a5a2e..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/linkfile +++ /dev/null @@ -1,2 +0,0 @@ -[objects] -test.o diff --git a/playing-coffee - Copy/roms/instr_timing/source/shell.inc b/playing-coffee - Copy/roms/instr_timing/source/shell.inc deleted file mode 100644 index 277a9b7..0000000 --- a/playing-coffee - Copy/roms/instr_timing/source/shell.inc +++ /dev/null @@ -1,21 +0,0 @@ -.incdir "common" - -; GBS music file -.ifdef BUILD_GBS - .include "build_gbs.s" -.endif - -; Devcart -.ifdef BUILD_DEVCART - .include "build_devcart.s" -.endif - -; Sub-test in a multi-test ROM -.ifdef BUILD_MULTI - .include "build_multi.s" -.endif - -; GB ROM (default) -.ifndef RUNTIME_INCLUDED - .include "build_rom.s" -.endif diff --git a/playing-coffee - Copy/roms/interrupt_time/interrupt_time.gb b/playing-coffee - Copy/roms/interrupt_time/interrupt_time.gb deleted file mode 100644 index 1b17845..0000000 Binary files a/playing-coffee - Copy/roms/interrupt_time/interrupt_time.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/interrupt_time/interrupt_time.s b/playing-coffee - Copy/roms/interrupt_time/interrupt_time.s deleted file mode 100644 index ae29d8a..0000000 --- a/playing-coffee - Copy/roms/interrupt_time/interrupt_time.s +++ /dev/null @@ -1,57 +0,0 @@ -; Tests interrupt handling time for slow and fast -; CPU. First value is CPU speed (0=slow, 1=fast), -; second is number of cycles taken by interrupt. -; Should take 13 cycles at either speed. -.define REQUIRE_CGB 1 - -.include "shell.inc" -.include "cpu_speed.s" -.include "timer.s" -.include "apu.s" - -; $58: JP $DEC3 -; $DEC3: RET -.define sint $DEC3 - -main: - call init_timer - - ld d,0 - call test_interrupt - ld d,8 - call test_interrupt - call cpu_fast - ld d,0 - call test_interrupt - ld d,8 - call test_interrupt - - check_crc $C86CC74D - jp tests_passed - -test_interrupt: - call get_cpu_speed - call print_a - call print_d - - ld a,$C9 ; RET - ld (sint),a - - wreg IE,$08 - wreg IF,$00 - call start_timer - ei - ld a,d - ld (IF),a ; $00 = 0 clocks, $08 = 13 clocks - di - call stop_timer - sub 3+4 ; instruction overhead - call print_a - call print_newline - - ret - -; RST handler that matches the one in my devcart -.bank 0 slot 0 -.org $58 - jp $DEC3 diff --git a/playing-coffee - Copy/roms/kwirk.gb b/playing-coffee - Copy/roms/kwirk.gb deleted file mode 100644 index c25d3c7..0000000 Binary files a/playing-coffee - Copy/roms/kwirk.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/mem_timing-2/mem_timing.gb b/playing-coffee - Copy/roms/mem_timing-2/mem_timing.gb deleted file mode 100644 index 2665aa2..0000000 Binary files a/playing-coffee - Copy/roms/mem_timing-2/mem_timing.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/mem_timing-2/readme.txt b/playing-coffee - Copy/roms/mem_timing-2/readme.txt deleted file mode 100644 index f6577c1..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/readme.txt +++ /dev/null @@ -1,114 +0,0 @@ -Game Boy CPU Memory Access Timing Test --------------------------------------- -These tests verify the timing of memory reads and writes made by -instructions, except stack and program counter accesses. These tests -require correct instruction timing and proper timer operation (TAC, -TIMA, TMA). - -The read and write tests list failing instructions as - - [CB] opcode:tested-correct - -The read-modify-write test lists failing instructions as - - [CB] opcode:tested read/tested write-correct read/correct write - -The values after the opcode refer to which instruction cycle the access -occurs on, with 1 being the first. If a time couldn't be determined due -to some other problem, it prints 0. - -For instructions which either read or write, but not both, the CPU makes -the access on the last cycle. For instructions which read, modify, then -write back, the CPU reads on the next-to-last cycle, and writes on the -last cycle. - - -Internal operation ------------------- -The tests have the timer increment TIMA every 64 cycles, synchronize -with this, delay a variable amount, then have the instruction under test -access the timer. By varying the delay in one-cycle increments, the -memory access made by the instruction can be made to fall before and -after a TIMA increment. By then examining the registers and value in -TIMA, it can be determined which occurred. - - -Multi-ROM ---------- -In the main directory is a single ROM/GBS which runs all the tests. It -prints a test's number, runs the test, then "ok" if it passes, otherwise -a failure code. Once all tests have completed it either reports that all -tests passed, or reports the number of the first failed test as the -result code (1 = first). Finally, it makes several beeps. If a test -fails, it can be run on its own by finding the corresponding ROM/GBS in -the singles directories. - -Ths compact format on screen is to avoid having the results scroll off -the top, so the test can be started and allowed to run without having to -constantly monitor the display. - - -Failure information -------------------- -For more information about a failure code or information printed, see -the test's source code in source/. To find failure code N, search for -"set_test N", which will usually be before the subtest which failed. - - -Flashes, clicks, other glitches -------------------------------- -Some tests might need to turn the screen off and on, or cause slight -audio clicks. This does not indicate failure, and should be ignored. -Only the test result reported at the end is important, unless stated -otherwise. - - -LCD support ------------ -Tests generally print information on screen. The tests will work fine if -run on an emulator with NO LCD support, or as an GBS which has no -inherent screen; in particular, the VBL wait routine has a timeout in -case LY doesn't reflect the current LCD line. The text printing will -also work if the LCD doesn't support scrolling. - - -Output to memory ----------------- -Text output and the final result are also written to memory at $A000, -allowing testing a very minimal emulator that supports little more than -CPU and RAM. To reliably indicate that the data is from a test and not -random data, $A001-$A003 are written with a signature: $DE,$B0,$61. If -this is present, then the text string and final result status are valid. - -$A000 holds the overall status. If the test is still running, it holds -$80, otherwise it holds the final result code. - -All text output is appended to a zero-terminated string at $A004. An -emulator could regularly check this string for any additional -characters, and output them, allowing real-time text output, rather than -just printing the final output at the end. - - -GBS versions ------------- -Many GBS-based tests require that the GBS player either not interrupt -the init routine with the play routine, or if they do, not interrupt the -play routine again if it hasn't returned yet. This is because many tests -need to run for a while without returning. - -In addition to the other text output methods described above, GBS builds -report essential information bytes audibly, including the final result. -A byte is reported as a series of tones. The code is in binary, with a -low tone for 0 and a high tone for 1. The first tone is always a zero. A -final code of 0 means passed, 1 means failure, and 2 or higher indicates -a specific reason as listed in the source code by the corresponding -set_code line. Examples: - -Tones Binary Decimal Meaning -- - - - - - - - - - - - - - - - - - - - -low 0 0 passed -low high 01 1 failed -low high low 010 2 error 2 - --- -Shay Green diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/01-read_timing.s b/playing-coffee - Copy/roms/mem_timing-2/source/01-read_timing.s deleted file mode 100644 index 5084d4b..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/01-read_timing.s +++ /dev/null @@ -1,150 +0,0 @@ -; Tests timing of accesses made by -; memory read instructions - -.define ROM_NAME "foo" - -.include "shell.inc" -.include "tima_64.s" - -instructions: - ; last value is time of read - .byte $B6,$00,$00,2 ; OR (HL) - .byte $BE,$00,$00,2 ; CP (HL) - .byte $86,$00,$00,2 ; ADD (HL) - .byte $8E,$00,$00,2 ; ADC (HL) - .byte $96,$00,$00,2 ; SUB (HL) - .byte $9E,$00,$00,2 ; SBC (HL) - .byte $A6,$00,$00,2 ; AND (HL) - .byte $AE,$00,$00,2 ; XOR (HL) - .byte $46,$00,$00,2 ; LD B,(HL) - .byte $4E,$00,$00,2 ; LD C,(HL) - .byte $56,$00,$00,2 ; LD D,(HL) - .byte $5E,$00,$00,2 ; LD E,(HL) - .byte $66,$00,$00,2 ; LD H,(HL) - .byte $6E,$00,$00,2 ; LD L,(HL) - .byte $7E,$00,$00,2 ; LD A,(HL) - .byte $F2,$00,$00,2 ; LDH A,(C) - .byte $0A,$00,$00,2 ; LD A,(BC) - .byte $1A,$00,$00,2 ; LD A,(DE) - .byte $2A,$00,$00,2 ; LD A,(HL+) - .byte $3A,$00,$00,2 ; LD A,(HL-) - .byte $F0,tima_64,4 ; LD A,($0000) - - .byte $CB,$46,$00,3 ; BIT 0,(HL) - .byte $CB,$4E,$00,3 ; BIT 1,(HL) - .byte $CB,$56,$00,3 ; BIT 2,(HL) - .byte $CB,$5E,$00,3 ; BIT 3,(HL) - .byte $CB,$66,$00,3 ; BIT 4,(HL) - .byte $CB,$6E,$00,3 ; BIT 5,(HL) - .byte $CB,$76,$00,3 ; BIT 6,(HL) - .byte $CB,$7E,$00,3 ; BIT 7,(HL) -instructions_end: - -main: - call init_tima_64 - set_test 0 - - ; Test instructions - ld hl,instructions -- call @time_instr - cp (hl) - call nz,@print_failed - inc hl - ld a,l - cp 3-byte instruction -; HL <- HL + 3 -@time_instr: - ; Copy instr - ld a,(hl+) - ld (instr+0),a - ld a,(hl+) - ld (instr+1),a - ld a,(hl+) - ld (instr+2),a - push hl - - ; Find result when access doesn't occur - ld b,0 - call @time_access - ld c,a - - ; Test for accesses on each cycle - ld b,0 -- push bc - call @time_access - pop bc - cp c - jr nz,@found - inc b - ld a,b - cp 10 - jr nz,- - ld b,0 - -@found: - ld a,b - pop hl - ret - -; Tests for read -; B -> which cycle to test -; A <- timer value after test -@time_access: - call sync_tima_64 - ld a,9 - sub b - call delay_a_20_cycles - xor a ; clear flags - ld hl,tima_64 - ld (hl),$7F - ld bc,tima_64 - ld de,tima_64 - ld a,$7F -instr: - nop - nop - nop - - ; Add all registers together to yield - ; unique value that differs based on - ; read occurring before or after tima_64 - ; increments. - push af - add hl,bc - add hl,de - pop de - add hl,de - ld a,h - add l - ret diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/02-write_timing.s b/playing-coffee - Copy/roms/mem_timing-2/source/02-write_timing.s deleted file mode 100644 index acd6d9d..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/02-write_timing.s +++ /dev/null @@ -1,115 +0,0 @@ -; Tests timing of accesses made by -; memory write instructions - -.include "shell.inc" -.include "tima_64.s" - -instructions: - ; last value is time of write - .byte $36,$FF,$00,3 ; LD (HL),n - .byte $70,$00,$00,2 ; LD (HL),B - .byte $71,$00,$00,2 ; LD (HL),C - .byte $72,$00,$00,2 ; LD (HL),D - .byte $73,$00,$00,2 ; LD (HL),E - .byte $74,$00,$00,2 ; LD (HL),H - .byte $75,$00,$00,2 ; LD (HL),L - .byte $77,$00,$00,2 ; LD (HL),A - .byte $02,$00,$00,2 ; LD (BC),A - .byte $12,$00,$00,2 ; LD (DE),A - .byte $22,$00,$00,2 ; LD (HL+),A - .byte $32,$00,$00,2 ; LD (HL-),A - .byte $E2,$00,$00,2 ; LDH (C),A - .byte $E0,tima_64,4 ; LD (nn),A -instructions_end: - -main: - call init_tima_64 - set_test 0 - - ; Test instructions - ld hl,instructions -- call @test_instr - cp (hl) - call nz,@print_failed - inc hl - ld a,l - cp 3-byte instruction -; HL <- HL + 3 -@test_instr: - ; Copy instr - ld a,(hl+) - ld (instr+0),a - ld a,(hl+) - ld (instr+1),a - ld a,(hl+) - ld (instr+2),a - push hl - - ; Test for writes on each cycle - ld b,0 -- push bc - call @time_write - pop bc - cp tima_64 - jr z,@no_write - jr @found -@no_write: - inc b - ld a,b - cp 10 - jr nz,- - ld b,0 - -@found: - ld a,b - pop hl - ret - -; Tests for write -; B -> which cycle to test -; A <- timer value after test -@time_write: - call sync_tima_64 - ld a,13 - sub b - call delay_a_20_cycles - ld hl,tima_64 - ld bc,tima_64 - ld de,tima_64 - ld a, 3-byte instruction -; HL <- HL + 3 -@time_instr: - ; Copy instr - ld a,(hl+) - ld (instr+0),a - ld a,(hl+) - ld (instr+1),a - ld a,(hl+) - ld (instr+2),a - push hl - - ; Find result when access doesn't occur - ld b,0 - call @time_access - - ; Find first access - call @find_next_access - ld d,b - - ; Find second access - call @find_next_access - ld e,b - - pop hl - ret - -; A -> current timer result -; B -> starting clock -; B <- clock next access occurs on -; A <- new timer result -@find_next_access: - ld c,a -- call @time_access - cp c - ret nz - inc b - ld a,b - cp 10 - jr c,- - - ; Couldn't find time, so return 0/0 - ld a,c - ld b,0 - ld d,b - ret - -; Tests for access -; B -> which cycle to test -; A <- timer value after test -@time_access: - call sync_tima_64 - ld hl,tima_64 - ld (hl),$7F - ld a,17 - sub b - call delay_a_20_cycles - xor a ; clear flags -instr: - nop - nop - nop - delay 32 - ld a,(tima_64) - ret diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/build_gbs.s b/playing-coffee - Copy/roms/mem_timing-2/source/common/build_gbs.s deleted file mode 100644 index 877754f..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/build_gbs.s +++ /dev/null @@ -1,139 +0,0 @@ -; Build as GBS music file - -.memoryMap - defaultSlot 0 - slot 0 $2000 size $2000 - slot 1 $C000 size $2000 -.endMe - -.romBankSize $2000 -.romBanks 2 - -.define RST_OFFSET $70 - -.ifndef GBS_TMA - .define GBS_TMA 0 -.endif - -.ifndef GBS_TAC - .define GBS_TAC 0 -.endif - -;;;; GBS music file header - -.ifndef CUSTOM_HEADER - .byte "GBS" - .byte 1,1,1 ; vers, song count, first song - .word load_addr, reset, gbs_play_, std_stack - .byte GBS_TMA,GBS_TAC ; timer -.endif - .org $10 - .ds $60,0 -load_addr: - .org RST_OFFSET+$70 ; space for RST vectors - .ds $148-RST_OFFSET-$70,0 - .org $150 ; wla insists on generating GB header - -gbs_play_: - jp gbs_play ; GBS spec disallows having gbs_play in RAM - -;;;; Shell - -.include "shell.s" - -.define gbs_idle nv_ram -.redefine nv_ram nv_ram+2 - -init_runtime: - ; Identify as DMG hardware - ld a,$01 - ld (gb_id),a - - ; Save return address - pop hl - ld a,l - ld (gbs_idle),a - ld a,h - ld (gbs_idle+1),a - - ; Delay 1/4 second to give time - ; for GBS player to interrupt with - ; play, if it's going to do so - delay_msec 250 - -.ifndef CUSTOM_PLAY -gbs_play: -.endif - ; Get return address - ld a,(gbs_idle) - ld l,a - ld a,(gbs_idle+1) - ld h,a - - ; If zero, then play interrupted init - ; call, or another play call, and we - ; can't run the program properly. - or l - jp z,internal_error - - setw gbs_idle,0 - jp hl - - -; Reports A in binary as high and low tones, with -; leading low tone for reference. Omits leading -; zeroes. -; Preserved: AF, BC, DE, HL -play_byte: - push af - push hl - - ; HL = (A << 1) | 1 - scf - rla - ld l,a - ld h,0 - rl h - - ; Shift left until next-to-top bit is 1 -- add hl,hl - bit 6,h - jr z,- - - ; Reset sound - delay_msec 400 - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - -- add hl,hl - - ; Low or high pitch based on bit shifted out - ; of HL - ld a,0 - jr nc,+ - ld a,$FF -+ sta NR23 - - ; Play short tone - wreg NR21,$A0 - wreg NR22,$F0 - wreg NR24,$86 - delay_msec 75 - wreg NR22,0 - wreg NR23,$F8 - wreg NR24,$87 - delay_msec 200 - - ; Loop until HL = $8000 - ld a,h - xor $80 - or l - jr nz,- - - pop hl - pop af - ret - -.ends diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/build_rom.s b/playing-coffee - Copy/roms/mem_timing-2/source/common/build_rom.s deleted file mode 100644 index 0f090aa..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/build_rom.s +++ /dev/null @@ -1,84 +0,0 @@ -; Build as GB ROM - -.memoryMap - defaultSlot 0 - slot 0 $0000 size $4000 - slot 1 $C000 size $4000 -.endMe - -.romBankSize $4000 -.romBanks 2 - -.cartridgeType 3 ; MBC1+RAM+battery -.ramsize 02 ; 8K -.computeChecksum -.computeComplementCheck -.emptyfill $FF - -;;;; GB ROM header - -.org $134 - .ds 15,0 - - ; Reserve space for RST handlers - .org $70 - - ; Keep unused space filled, otherwise - ; wla moves code here - .ds $90,0 - - ; GB header read by bootrom - .org $100 - nop - jp reset - - ; Nintendo logo required for proper boot - .byte $CE,$ED,$66,$66,$CC,$0D,$00,$0B - .byte $03,$73,$00,$83,$00,$0C,$00,$0D - .byte $00,$08,$11,$1F,$88,$89,$00,$0E - .byte $DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 - .byte $BB,$BB,$67,$63,$6E,$0E,$EC,$CC - .byte $DD,$DC,$99,$9F,$BB,$B9,$33,$3E - -.section "HEADER" OVERWRITE - ; Internal name - .ifdef ROM_NAME - .byte ROM_NAME - .else - .ifdef ROM_NAME_DEFAULT - .byte ROM_NAME_DEFAULT - .endif - .endif -.ends - - ; CGB/DMG requirements - .org $143 - .ifdef REQUIRE_CGB - .byte $C0 - .else - .ifndef REQUIRE_DMG - .byte $80 - .endif - .endif - .byte 0,0,0 - - .org $14A - .byte 0,0,0 - - ; Keep unused space filled, otherwise - ; wla moves code here - .org $150 - .ds $2150-$150,$FF - -;;;; Shell - -.define NEED_CONSOLE 1 -.include "shell.s" - -init_runtime: - ret - -play_byte: - ret - -.ends diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/console.bin b/playing-coffee - Copy/roms/mem_timing-2/source/common/console.bin deleted file mode 100644 index b02f2d3..0000000 Binary files a/playing-coffee - Copy/roms/mem_timing-2/source/common/console.bin and /dev/null differ diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/console.s b/playing-coffee - Copy/roms/mem_timing-2/source/common/console.s deleted file mode 100644 index 403fa5c..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/console.s +++ /dev/null @@ -1,285 +0,0 @@ -; Scrolling text console - -; Console is 20x18 characters. Buffers lines, so -; output doesn't appear until a newline or flush. -; If scrolling isn't supported (i.e. SCY is treated -; as if always zero), the first 18 lines will -; still print properly). Also works properly if -; LY isn't supported (always reads back as the same -; value). - -.define console_width 20 - -.define console_buf bss+0 -.define console_pos bss+console_width -.define console_mode bss+console_width+1 -.define console_scroll bss+console_width+2 -.redefine bss bss+console_width+3 - - -; Waits for start of LCD blanking period -; Preserved: BC, DE, HL -console_wait_vbl: - push bc - - ; Wait for start of vblank, with - ; timeout in case LY doesn't work - ; or LCD is disabled. - ld bc,-1250 -- inc bc - ld a,b - or c - jr z,@timeout - lda LY - cp 144 - jr nz,- -@timeout: - - pop bc - ret - - -; Initializes text console -console_init: - call console_hide - - ; CGB-specific inits - ld a,(gb_id) - and gb_id_cgb - call nz,@init_cgb - - ; Clear nametable - ld a,' ' - call @fill_nametable - - ; Load tiles - ld hl,TILES+$200 - ld c,0 - call @load_tiles - ld hl,TILES+$A00 - ld c,$FF - call @load_tiles - - ; Init state - setb console_pos,console_width - setb console_mode,0 - setb console_scroll,-8 - call console_scroll_up_ - jr console_show - -@fill_nametable: - ld hl,BGMAP0 - ld b,4 -- ld (hl),a - inc l - jr nz,- - inc h - dec b - jr nz,- - ret - -@init_cgb: - ; Clear palette - wreg $FF68,$80 - ld b,16 -- wreg $FF69,$FF - wreg $FF69,$7F - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - dec b - jr nz,- - - ; Clear attributes - wreg VBK,1 - ld a,0 - call @fill_nametable - - wreg VBK,0 - ret - -@load_tiles: - ld de,ASCII - ld b,96 --- push bc - ld b,8 -- ld a,(de) - inc de - xor c - ldi (hl),a - ldi (hl),a - dec b - jr nz,- - pop bc - dec b - jr nz,-- - ret - - -; Shows console display -; Preserved: AF, BC, DE, HL -console_show: - push af - - ; Enable LCD - call console_wait_vbl - wreg LCDC,$91 - wreg SCX,0 - wreg BGP,$E4 - - jp console_apply_scroll_ - - -; Hides console display by turning LCD off -; Preserved: AF, BC, DE, HL -console_hide: - push af - - ; LCD off - call console_wait_vbl - wreg LCDC,$11 - - pop af - ret - - -; Changes to normal text mode -; Preserved: BC, DE, HL -console_normal: - xor a - jr console_set_mode - -; Changes to inverse text mode -; Preserved: BC, DE, HL -console_inverse: - ld a,$80 - -; Changes console mode to A. -; 0: Normal, $80: Inverse -; Preserved: BC, DE, HL -console_set_mode: - and $80 - ld (console_mode),a - ret - - -; Prints char A to console. Will not appear until -; a newline or flush occurs. -; Preserved: AF, BC, DE, HL -console_print: - push af - - cp 10 - jr z,console_newline_ - - push hl - push af - ld hl,console_pos - ldi a,(hl) - cp BGMAP0) >> 2 - add hl,hl - add hl,hl - - ; Copy line - ld de,console_buf + console_width -- dec e - ld a,(de) - ldi (hl),a - ld a,e - cp checksum - ldi (hl),a - ld (hl),d - inc l - ld (hl),c - inc l - ld (hl),b - - pop hl - pop de - pop bc - pop af - ret diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/delay.s b/playing-coffee - Copy/roms/mem_timing-2/source/common/delay.s deleted file mode 100644 index cbcdcf3..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/delay.s +++ /dev/null @@ -1,220 +0,0 @@ -; Delays in cycles, milliseconds, etc. - -; All routines are re-entrant (no global data). Routines never -; touch BC, DE, or HL registers. These ASSUME CPU is at normal -; speed. If running at double speed, msec/usec delays are half advertised. - -; Delays n cycles, from 0 to 16777215 -; Preserved: AF, BC, DE, HL -.macro delay ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 16777215 - .printt "Delay must be < 16777216" - .fail - .endif - delay_ n&$FFFF, n>>16 -.endm - -; Delays n clocks, from 0 to 16777216*4. Must be multiple of 4. -; Preserved: AF, BC, DE, HL -.macro delay_clocks ARGS n - .if n # 4 != 0 - .printt "Delay must be a multiple of 4" - .fail - .endif - delay_ (n/4)&$FFFF,(n/4)>>16 -.endm - -; Delays n microseconds (1/1000000 second) -; n can range from 0 to 4000 usec. -; Preserved: AF, BC, DE, HL -.macro delay_usec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 4000 - .printt "Delay must be <= 4000 usec" - .fail - .endif - delay_ ((n * 1048576 + 500000) / 1000000)&$FFFF,((n * 1048576 + 500000) / 1000000)>>16 -.endm - -; Delays n milliseconds (1/1000 second) -; n can range from 0 to 10000 msec. -; Preserved: AF, BC, DE, HL -.macro delay_msec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 10000 - .printt "Delay must be <= 10000 msec" - .fail - .endif - delay_ ((n * 1048576 + 500) / 1000)&$FFFF, ((n * 1048576 + 500) / 1000)>>16 -.endm - - ; All the low/high quantities are to deal wla-dx's asinine - ; restriction full expressions must evaluate to a 16-bit - ; value. If the author ever rectifies this, all "high" - ; arguments can be treated as zero and removed. Better yet, - ; I'll just find an assembler that didn't crawl out of - ; the sewer (this is one of too many bugs I've wasted - ; hours working around). - - .define max_short_delay 28 - - .macro delay_long_ ARGS n, high - ; 0+ to avoid assembler treating as memory read - ld a,0+(((high<<16)+n) - 11) >> 16 - call delay_65536a_9_cycles_ - delay_nosave_ (((high<<16)+n) - 11)&$FFFF, 0 -.endm - - ; Doesn't save AF, allowing minimization of AF save/restore - .macro delay_nosave_ ARGS n, high - ; 65536+11 = maximum delay using delay_256a_9_cycles_ - ; 255+22 = maximum delay using delay_a_20_cycles - ; 22 = minimum delay using delay_a_20_cycles - .if high > 1 - delay_long_ n, high - .else - .if high*n > 11 - delay_long_ n, high - .else - .if (high*(255+22+1))|n > 255+22 - ld a,>(((high<<16)+n) - 11) - call delay_256a_9_cycles_ - delay_nosave_ <(((high<<16)+n) - 11), 0 - .else - .if n >= 22 - ld a,n - 22 - call delay_a_20_cycles - .else - delay_short_ n - .endif - .endif - .endif - .endif -.endm - - .macro delay_ ARGS low, high - .if (high*(max_short_delay+1))|low > max_short_delay - push af - delay_nosave_ ((high<<16)+low - 7)&$FFFF, ((high<<16)+low - 7)>>16 - pop af - .else - delay_short_ low - .endif -.endm - - -; Delays A cycles + overhead -; Preserved: BC, DE, HL -; Time: A+20 cycles (including CALL) -delay_a_20_cycles: -- sub 5 ; 2 - jr nc,- ;3/2 do multiples of 5 - rra ; 1 - jr nc,+ ;3/2 bit 0 -+ adc 1 ; 2 - ret nc ;5/2 -1: 0 cycles - ret z ;5/2 0: 2 cycles - nop ; 1 1: 4 cycles - ret ; 4 (thanks to dclxvi for original algorithm) - -; Delays A*256 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*256+12 cycles (including CALL) -delay_256a_12_cycles: - or a ; 1 - ret z ; 5/2 -delay_256a_9_cycles_: -- delay 256-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays A*65536 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*65536+12 cycles (including CALL) -delay_65536a_12_cycles: - or a ; 1 - ret z ;5/2 -delay_65536a_9_cycles_: -- delay 65536-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays H*256+L cycles + overhead -; Preserved: AF, BC, DE, HL -; Time: H*256+L+51 cycles -delay_hl_51_cycles: - push af - ld a,h - call delay_256a_12_cycles - ld a,l - call delay_a_20_cycles - pop af - ret - - ; delay_short_ macro calls into these - .ds max_short_delay-10,$00 ; NOP repeated several times -delay_unrolled_: - ret - -.macro delay_short_ ARGS n - .if n < 0 - .fail - .endif - .if n > max_short_delay - .fail - .endif - - .if n == 1 - nop - .endif - .if n == 2 - nop - nop - .endif - .if n == 3 - .byte $18,$00 ; JR +0 - .endif - .if n == 4 - .byte $18,$00 ; JR +0 - nop - .endif - .if n == 5 - .byte $18,$00 ; JR +0 - nop - nop - .endif - .if n == 6 - .byte $18,$00 ; JR +0 - .byte $18,$00 ; JR +0 - .endif - .if n == 7 - push af - pop af - .endif - .if n == 8 - push af - pop af - nop - .endif - .if n == 9 - push af - pop af - nop - nop - .endif - .if n >= 10 - call delay_unrolled_ + 10 - n - .endif -.endm diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/gb.inc b/playing-coffee - Copy/roms/mem_timing-2/source/common/gb.inc deleted file mode 100644 index 2d0118d..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/gb.inc +++ /dev/null @@ -1,81 +0,0 @@ -; Game Boy hardware addresses - -; $0000-$3FFF Fixed ROM bank -; $4000-$7FFF Switchable bank -; $8000-$9FFF VRAM -; $A000-$BFFF optional cartridge RAM -; $C000-$DFFF RAM -; $E000-$FDFF RAM mirror -; $FE00-$FE9F OAM -; $FEA0-$FEFF unused -; $FF00-$FF7F registers -; $FF80-$FFFE RAM -; $FFFF register - -; Memory -.define VRAM $8000 ; video memory -.define TILES $8000 ; tile images -.define BGMAP0 $9800 ; first 32x32 tilemap -.define BGMAP1 $9C00 ; second 32x32 tilemap -.define BRAM $A000 ; cart memory -.define WRAM $C000 ; internal memory -.define OAM $FE00 ; sprite memory -.define HRAM $FF80 ; fast memory for LDH - -; Registers - -.define RAMEN $0000 ; cartridge WRAM control -.define BANK $2000 ; bank select -.define P1 $FF00 ; controller - -; Game link I/O -.define SB $FF01 ; serial buffer -.define SC $FF02 ; serial control - -; Interrupts -.define DIV $FF04 -.define TIMA $FF05 -.define TMA $FF06 -.define TAC $FF07 -.define IF $FF0F -.define IE $FFFF - -; LCD registers -.define LCDC $FF40 ; control -.define STAT $FF41 ; status -.define SCY $FF42 ; scroll Y -.define SCX $FF43 ; scroll X -.define LY $FF44 ; current Y being rendered -.define BGP $FF47 - -.define KEY1 $FF4D ; for changing CPU speed -.define VBK $FF4F - -; Sound registers -.define NR10 $FF10 -.define NR11 $FF11 -.define NR12 $FF12 -.define NR13 $FF13 -.define NR14 $FF14 - -.define NR21 $FF16 -.define NR22 $FF17 -.define NR23 $FF18 -.define NR24 $FF19 - -.define NR30 $FF1A -.define NR31 $FF1B -.define NR32 $FF1C -.define NR33 $FF1D -.define NR34 $FF1E - -.define NR41 $FF20 -.define NR42 $FF21 -.define NR43 $FF22 -.define NR44 $FF23 - -.define NR50 $FF24 -.define NR51 $FF25 -.define NR52 $FF26 - -.define WAVE $FF30 diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/macros.inc b/playing-coffee - Copy/roms/mem_timing-2/source/common/macros.inc deleted file mode 100644 index 9d7cf44..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/macros.inc +++ /dev/null @@ -1,91 +0,0 @@ -; General macros - -; Reads A from addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 3 cycles -.macro lda ; addr - ldh a,(\1 - $FF00) -.endm - -; Writes A to addr, from $FF00 to $FFFF -; Preserved: AF, BC, DE, HL -; Time: 3 cycles -.macro sta ; addr - ldh (\1 - $FF00),a -.endm - -; Writes immediate data to addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 5 cycles -.macro wreg ARGS addr, data - ld a,data - sta addr -.endm - -; Writes byte to addr -; Preserved: F, BC, DE, HL -; Time: 6 cycles -.macro setb ; addr, data - ld a,\2 - ld (\1),a -.endm - -; Writes word to addr -; Preserved: F, BC, DE, HL -; Time: 12 cycles -.macro setw ; addr, data - ld a,<\2 - ld (\1),a - ld a,>\2 - ld (\1+1),a -.endm - -; Calls routine multiple times, with A having the -; value 'start' the first time, 'start+step' the -; second time, up to 'end' for the last time. -; Preserved: BC, DE, HL -.macro for_loop ; routine,start,end,step - ld a,\2 - -for_loop\@: - push af - call \1 - pop af - - add \4 - cp <(\3 + \4) - jr nz,for_loop\@ -.endm - -; Calls routine n times. The value of A in the routine -; counts from 0 to n-1. -; Preserved: BC, DE, HL -.macro loop_n_times ; routine,n - for_loop \1,0,\2 - 1,+1 -.endm - -; Same as for_loop, but counts with 16-bit value in BC. -; Preserved: DE, HL -.macro for_loop16 ; routine,start,end,step - ld bc,\2 - -for_loop16\@: - push bc - call \1 - pop bc - - ld a,c - add <\4 - ld c,a - - ld a,b - adc >\4 - ld b,a - - cp >(\3+\4) - jr nz,for_loop16\@ - - ld a,c - cp <(\3+\4) - jr nz,for_loop16\@ -.endm diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/numbers.s b/playing-coffee - Copy/roms/mem_timing-2/source/common/numbers.s deleted file mode 100644 index 6d6faf8..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/numbers.s +++ /dev/null @@ -1,177 +0,0 @@ -; Printing of numeric values - -; Prints value of indicated register/pair -; as 2/4 hex digits, followed by a space. -; Updates checksum with printed values. -; Preserved: AF, BC, DE, HL - -print_regs: - call print_af - call print_bc - call print_de - call print_hl - call print_newline - ret - -print_a: - push af -print_a_: - call print_hex - ld a,' ' - call print_char_nocrc - pop af - ret - -print_af: - push af - call print_hex - pop af -print_f: - push bc - push af - pop bc - call print_c - pop bc - ret - -print_b: - push af - ld a,b - jr print_a_ - -print_c: - push af - ld a,c - jr print_a_ - -print_d: - push af - ld a,d - jr print_a_ - -print_e: - push af - ld a,e - jr print_a_ - -print_h: - push af - ld a,h - jr print_a_ - -print_l: - push af - ld a,l - jr print_a_ - -print_bc: - push af - push bc -print_bc_: - ld a,b - call print_hex - ld a,c - pop bc - jr print_a_ - -print_de: - push af - push bc - ld b,d - ld c,e - jr print_bc_ - -print_hl: - push af - push bc - ld b,h - ld c,l - jr print_bc_ - - -; Prints A as two hex chars and updates checksum -; Preserved: BC, DE, HL -print_hex: - call update_crc -print_hex_nocrc: - push af - swap a - call + - pop af - -+ and $0F - cp 10 - jr c,+ - add 7 -+ add '0' - jp print_char_nocrc - - -; Prints char_nz if Z flag is clear, -; char_z if Z flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nz ARGS char_nz, char_z - push af - ld a,char_nz - jr nz,print_nz\@ - ld a,char_z -print_nz\@: - call print_char - pop af -.endm - - -; Prints char_nc if C flag is clear, -; char_c if C flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nc ARGS char_nc, char_c - push af - ld a,char_nc - jr nz,print_nc\@ - ld a,char_c -print_nc\@: - call print_char - pop af -.endm - - -; Prints A as 2 decimal digits -; Preserved: AF, BC, DE, HL -print_dec2: - push af - push bc - jr + - - -; Prints A as 1-3 digit decimal value -; Preserved: AF, BC, DE, HL -print_dec: - push af - push bc - - cp 10 - jr c,++ - ld c,100 - cp c - call nc,@digit -+ ld c,10 - call @digit -++ add '0' - call print_char - - pop bc - pop af - ret - -@digit: - ld b,'0'-1 -- inc b - sub c - jr nc,- - add c - - ld c,a - ld a,b - call print_char - ld a,c - ret diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/printing.s b/playing-coffee - Copy/roms/mem_timing-2/source/common/printing.s deleted file mode 100644 index bb9389b..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/printing.s +++ /dev/null @@ -1,77 +0,0 @@ -; Main printing routine that checksums and -; prints to output device - -; Character that does equivalent of print_newline -.define newline 10 - -; Prints char without updating checksum -; Preserved: BC, DE, HL -;print_char_nocrc (defined by user) - - -; Prints character and updates checksum UNLESS -; it's a newline. -; Preserved: AF, BC, DE, HL -print_char: - push af - cp newline - call nz,update_crc - call print_char_nocrc - pop af - ret - - -; Prints space. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_space: - push af - ld a,' ' - call print_char_nocrc - pop af - ret - - -; Advances to next line. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_newline: - push af - ld a,newline - call print_char_nocrc - pop af - ret - - -; Prints immediate string -; Preserved: AF, BC, DE, HL -.macro print_str ; string,string2 - push hl - call print_str_ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 - pop hl -.endm - -print_str_: - pop hl - call print_str_hl - jp hl - - -; Prints zero-terminated string pointed to by HL. -; On return, HL points to byte AFTER zero terminator. -; Preserved: AF, BC, DE -print_str_hl: - push af - jr + -- call print_char -+ ldi a,(hl) - or a - jr nz,- - pop af - ret diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/shell.s b/playing-coffee - Copy/roms/mem_timing-2/source/common/shell.s deleted file mode 100644 index a045121..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/shell.s +++ /dev/null @@ -1,266 +0,0 @@ -; Common routines and runtime - -.define RUNTIME_INCLUDED 1 - -; A few bytes of RAM that aren't cleared -.define nv_ram_base $D800 -.define nv_ram nv_ram_base - -; Address of next normal variable -.define bss_base nv_ram_base+$80 -.define bss bss_base - -; Address of next direct-page ($FFxx) variable -.define dp_base $FF80 -.define dp dp_base - -; Top of stack -.define std_stack $DFFF+1 - -; Final exit result byte is written here -.define final_result $A000 - -; Text output is written here as zero-terminated string -.define text_out_base $A004 - -; DMG/CGB hardware identifier -.define gb_id_cgb $10 ; mask for testing CGB bit -.define gb_id_devcart $04 ; mask for testing "on devcart" bit -.define gb_id nv_ram -.redefine nv_ram nv_ram+1 - -; Copies C*$100 bytes from HL to $C000, then jumps to it. -; A is preserved for jumped-to code. -copy_to_wram_then_run: - ld b,a - - ld de,$C000 -- ld a,(hl+) - ld (de),a - inc e - jr nz,- - inc d - dec c - jr nz,- - - ld a,b - jp $C000 - - -.ifndef RST_OFFSET - .define RST_OFFSET 0 -.endif - -.ifndef CUSTOM_RESET - reset: - di - - ; Run code from $C000, as is done on devcart. This - ; ensures minimal difference in how it behaves. - ld hl,$4000 - ld c,$14 - jp copy_to_wram_then_run - - .bank 1 slot 1 - .org 0 - jp std_reset -.endif - -; returnOrg puts this code AFTER user code. -.section "runtime" returnOrg - - ; Catch user code running off end - jp internal_error - -; Common routines -.include "gb.inc" -.include "macros.inc" -.include "delay.s" -.include "crc.s" -.include "printing.s" -.include "numbers.s" -.include "testing.s" - -; Sets up hardware and runs main -std_reset: - - ; Init hardware - di - ld sp,std_stack - - ; Save DMG/CGB id - ld b,a - and $EA - jr z,+ - ld b,0 -+ ld a,b - ld (gb_id),a - - ; Clear memory except very top of stack - ld bc,std_stack-bss_base - 2 - ld hl,bss_base - call clear_mem - ld bc,$FFFF-dp_base - ld hl,dp_base - call clear_mem - - ; Init hardware - wreg TAC,$00 - wreg IF,$00 - wreg IE,$00 - - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - - call init_runtime - call init_text_out - call console_init - call init_testing - - .ifdef TEST_NAME - print_str TEST_NAME,newline,newline - .endif - - call reset_crc ; in case init_runtime prints anything - - delay_msec 250 - - ; Run user code - call main - - ; Default is to successful exit - ld a,0 - jp exit - - -; Exits code and reports value of A -exit: - ld sp,std_stack - push af - call + - call console_show - pop af - call play_byte - jp post_exit - -+ push af - call print_newline - pop af - - ; Report exit status - cp 1 - - ; 0: "" - ret c - - ; 1: "Failed" - jr nz,+ - print_str "Failed",newline - ret - - ; n: "Failed #n" -+ print_str "Failed #" - call print_dec - call print_newline - ret - - -; Clears BC bytes starting at HL -clear_mem: - ; If C>0, increment B - dec bc - inc c - inc b - - ld a,0 -- ld (hl+),a - dec c - jr nz,- - dec b - jr nz,- - ret - - -; Reports internal error and exits with code 255 -internal_error: - print_str "Internal error" - ld a,255 - jp exit - - -; build_devcart and build_multi customize this -.ifndef CUSTOM_PRINT - .define text_out_addr bss+0 - .redefine bss bss+2 - - ; Initializes text output to cartridge RAM - init_text_out: - ; Enable cartridge RAM and set text output pointer - setb RAMEN,$0A - setw text_out_addr,text_out_base - setb text_out_base-3,$DE - setb text_out_base-2,$B0 - setb text_out_base-1,$61 - setb text_out_base,0 - setb final_result,$80 - ret - - - ; Appends character to text output string - ; Preserved: AF, BC, DE, HL - write_text_out: - push hl - push af - ld a,(text_out_addr) - ld l,a - ld a,(text_out_addr+1) - ld h,a - inc hl - ld (hl),0 - ld a,l - ld (text_out_addr),a - ld a,h - ld (text_out_addr+1),a - dec hl - pop af - ld (hl),a - pop hl - ret - - print_char_nocrc: - call write_text_out - jp console_print -.endif - - -; only build_rom uses console -.ifdef NEED_CONSOLE - .include "console.s" -.else - console_init: - console_print: - console_flush: - console_normal: - console_inverse: - console_show: - console_set_mode: - ret -.endif - - -; build_devcart and build_multi need to customize this -.ifndef CUSTOM_EXIT - post_exit: - ld (final_result),a - forever: - wreg NR52,0 ; sound off -- jr - -.endif - - -.macro def_rst ARGS addr - .bank 0 slot 0 - .org addr+RST_OFFSET -.endm diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/testing.s b/playing-coffee - Copy/roms/mem_timing-2/source/common/testing.s deleted file mode 100644 index 5dd63ce..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/testing.s +++ /dev/null @@ -1,195 +0,0 @@ -; Diagnostic and testing utilities - -.define test_code bss+0 -.define test_name bss+1 -.redefine bss bss+3 - - -; Sets test code and optional error text. -; Takes multiple strings due to wla's idiotic -; default limit of 63 chars per string. -; Preserved: AF, BC, DE, HL -.macro set_test ; code[,text[,text2[,text3]]] - push hl - call set_test_ - jr @set_test\@ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .if NARGS > 3 - .byte \4 - .endif - .byte 0 -@set_test\@: - pop hl -.endm - -set_test_: - pop hl - push hl - push af - inc hl - inc hl - ldi a,(hl) - ld (test_code),a - ld a,l - ld (test_name),a - ld a,h - ld (test_name+1),a - pop af - ret - - -; Initializes testing module -init_testing: - set_test $FF - call init_crc - ret - - -; Reports "Passed", then exits with code 0 -tests_passed: - call print_newline - print_str "Passed" - ld a,0 - jp exit - - -; Reports "Done" if set_test has never been used, -; "Passed" if set_test 0 was last used, or -; failure if set_test n was last used. -tests_done: - ld a,(test_code) - inc a - jr z,+ - dec a - jr z,tests_passed - jr test_failed -+ print_str "Done" - ld a,0 - jp exit - - -; Reports current error text and exits with result code -test_failed: - ld a,(test_name) - ld l,a - ld a,(test_name+1) - ld h,a - ld a,(hl) - or a - jr z,+ - call print_newline - call print_str_hl - call print_newline -+ - ld a,(test_code) - cp $FF ; if a = $FF then a = 1 - jr nz,+ - ld a,1 -+ jp exit - - -; Prints checksum as 8-character hex value -; Preserved: AF, BC, DE, HL -print_crc: - push af - - ; Must read checksum entirely before printing, - ; since printing updates it. - lda checksum - cpl - push af - - lda checksum+1 - cpl - push af - - lda checksum+2 - cpl - push af - - lda checksum+3 - cpl - - call print_hex - pop af - call print_hex - pop af - call print_hex - pop af - call print_a - - pop af - ret - - -; If checksum doesn't match expected, reports failed test. -; Passing 0 just prints checksum. Clears checksum afterwards. -.macro check_crc ARGS crc - .if crc == 0 - call print_newline - call print_crc - .else - ld bc,(crc >> 16) ~ $FFFF - ld de,(crc & $FFFF) ~ $FFFF - call check_crc_ - .endif -.endm - -; Checks CRC, differing based on DMG or CGB build -.macro check_crc_dmg_cgb ARGS dmg, cgb - .ifdef REQUIRE_DMG - check_crc dmg - .else - .ifdef REQUIRE_CGB - check_crc cgb - .else - .printt "CGB or DMG must be specified" - .fail - .endif - .endif -.endm - -check_crc_: - lda checksum+0 - cp e - jr nz,+ - - lda checksum+1 - cp d - jr nz,+ - - lda checksum+2 - cp c - jr nz,+ - - lda checksum+3 - cp b - jr nz,+ - - jp reset_crc - -+ call print_crc - jp test_failed - - -; Updates checksum with bytes from addr to addr+size-1 -.macro checksum_mem ARGS addr,size - ld hl,addr - ld bc,size - call checksum_mem_ -.endm - -checksum_mem_: -- ldi a,(hl) - call update_crc - dec bc - ld a,b - or c - jr nz,- - ret diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/common/tima_64.s b/playing-coffee - Copy/roms/mem_timing-2/source/common/tima_64.s deleted file mode 100644 index 5b6c3a1..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/common/tima_64.s +++ /dev/null @@ -1,36 +0,0 @@ -; Timer that's incremented every 64 cycles - -; Initializes timer for use by sync_tima_64 -init_tima_64: - wreg TMA,0 - wreg TAC,$07 - ret - -; Synchronizes to timer -; Preserved: AF, BC, DE, HL -sync_tima_64: - push af - push hl - - ; Coarse - ld hl,TIMA - ld a,0 - ld (hl),a -- or (hl) - jr z,- - - ; Fine -- delay 65-12 - xor a - ld (hl),a - or (hl) - delay 4 - jr z,- - - pop hl - pop af - ret - -; Read from this to get count that's incremented -; every 64 cycles. -.define tima_64 TIMA diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/linkfile b/playing-coffee - Copy/roms/mem_timing-2/source/linkfile deleted file mode 100644 index 02a5a2e..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/linkfile +++ /dev/null @@ -1,2 +0,0 @@ -[objects] -test.o diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/readme.txt b/playing-coffee - Copy/roms/mem_timing-2/source/readme.txt deleted file mode 100644 index a0269c1..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/readme.txt +++ /dev/null @@ -1,82 +0,0 @@ -Game Boy Tests Source Code --------------------------- - -Building with wla-dx --------------------- -To assemble a test ROM with wla-dx, use the following commands: - - wla -o source_filename_here.s test.o - wlalink linkfile test.gb - -To assemble as a GBS music file: - - wla -o source_filename_here.s test.o -DBUILD_GBS - wlalink linkfile test.gbs - -Note that some tests might only work when built as a ROM or GBS file, -but not both. - -Some tests might include a ROM/GBS that has all the tests combined. -Building such a multi-test is complex and the necessary files aren't -included. - - -Framework ---------- -Each test is in a single source file, and makes use of several library -source files from common/. This framework provides common services and -reduces code to only that which performs the actual test. Virtually all -tests include "shell.inc" at the beginning, which sets things up and -includes all the appropriate library files. - -The reset handler does minimal GB hardware initialization, clears RAM, -sets up the text console, then runs main. Main can exit by returning or -jumping to "exit" with an error code in A. Exit reports the code then -goes into an infinite loop. If the code is 0, it doesn't do anything, -otherwise it reports the code. Code 1 is reported as "Failed", and the -rest as "Error ". - -The default is to build a ROM. Defining BUILD_GBS will build as an GBS. -The other build types aren't supported due to their complexity. I load -the code into RAM at $C000 since my devcart requires it, and I don't -want the normal ROM to differ in any way from what I've tested. This -also allows easy self-modifying code. - -Several routines are available to print values and text to the console. -Most update a running CRC-32 checksum which can be checked with -check_crc, allowing ALL the output to be checked very easily. If the -checksum doesn't match, it is printed, so you can run the code on a GB -and paste the correct checksum into your code. - - -Macros ------- -Some macros are used to make common operations more convenient. The left -is equivalent to the right: - - Macro Equivalent - ------------------------------------- - lda addr ldh a,(addr-$FF00) - - sta addr ldh (addr-$FF00),a - - wreg addr,data ld a,data - ldh (addr-$FF00),a - - setb ld a,data - ld (addr),a - - setw setb addr+0,data - - for_loop routine,begin,end,step - calls routine with A set to successive values - - loop_n_times routine,count - calls routine with A from 0 to count-1 - - print_str "str" prints string - - --- -Shay Green diff --git a/playing-coffee - Copy/roms/mem_timing-2/source/shell.inc b/playing-coffee - Copy/roms/mem_timing-2/source/shell.inc deleted file mode 100644 index 0d43faa..0000000 --- a/playing-coffee - Copy/roms/mem_timing-2/source/shell.inc +++ /dev/null @@ -1,27 +0,0 @@ -; Included at beginning of all programs -; that use standard shell - -; Get include files from common/ -.incdir "common" - -; Sub-test in a multi-test ROM -.ifdef BUILD_MULTI - .include "build_multi.s" -.else - -; GBS music file -.ifdef BUILD_GBS - .include "build_gbs.s" -.endif - -; Devcart -.ifdef BUILD_DEVCART - .include "build_devcart.s" -.endif - -; GB ROM (default) -.ifndef RUNTIME_INCLUDED - .include "build_rom.s" -.endif - -.endif ; .ifdef BUILD_MULTI diff --git a/playing-coffee - Copy/roms/mem_timing/individual/01-read_timing.gb b/playing-coffee - Copy/roms/mem_timing/individual/01-read_timing.gb deleted file mode 100644 index d0836aa..0000000 Binary files a/playing-coffee - Copy/roms/mem_timing/individual/01-read_timing.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/mem_timing/individual/02-write_timing.gb b/playing-coffee - Copy/roms/mem_timing/individual/02-write_timing.gb deleted file mode 100644 index cfe7c0f..0000000 Binary files a/playing-coffee - Copy/roms/mem_timing/individual/02-write_timing.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/mem_timing/individual/03-modify_timing.gb b/playing-coffee - Copy/roms/mem_timing/individual/03-modify_timing.gb deleted file mode 100644 index 28f1ae6..0000000 Binary files a/playing-coffee - Copy/roms/mem_timing/individual/03-modify_timing.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/mem_timing/mem_timing.gb b/playing-coffee - Copy/roms/mem_timing/mem_timing.gb deleted file mode 100644 index 78766b5..0000000 Binary files a/playing-coffee - Copy/roms/mem_timing/mem_timing.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/mem_timing/readme.txt b/playing-coffee - Copy/roms/mem_timing/readme.txt deleted file mode 100644 index 98d76e2..0000000 --- a/playing-coffee - Copy/roms/mem_timing/readme.txt +++ /dev/null @@ -1,122 +0,0 @@ -Game Boy CPU Memory Access Timing Test --------------------------------------- -This ROM tests the timing of memory reads and writes made by -instructions, except stack and program counter accesses. These tests -require correct instruction timing and proper timer operation (TAC, -TIMA, TMA). - -The read and write tests list failing instructions as - - [CB] opcode:tested-correct - -The read-modify-write test lists failing instructions as - - [CB] opcode:tested read/tested write-correct read/correct write - -The values after the opcode refer to which instruction cycle the access -occurs on, with 1 being the first. If a time couldn't be determined due -to some other problem, it prints 0. - -For instructions which either read or write, but not both, the CPU makes -the access on the last cycle. For instructions which read, modify, then -write back, the CPU reads on the next-to-last cycle, and writes on the -last cycle. - - -Internal operation ------------------- -The tests have the timer increment TIMA every 64 cycles, synchronize -with this, delay a variable amount, then have the instruction under test -access the timer. By varying the delay in one-cycle increments, the -memory access made by the instruction can be made to fall before and -after a TIMA increment. By then examining the registers and value in -TIMA, it can be determined which occurred. - - -Multi-ROM ---------- -In the main directory is a single ROM which runs all the tests. It -prints a test's number, runs the test, then "ok" if it passes, otherwise -a failure code. Once all tests have completed it either reports that all -tests passed, or prints the number of failed tests. Finally, it makes -several beeps. If a test fails, it can be run on its own by finding the -corresponding ROM in individual/. - -Ths compact format on screen is to avoid having the results scroll off -the top, so the test can be started and allowed to run without having to -constantly monitor the display. - -Currently there is no well-defined way for an emulator test rig to -programatically find the result of the test; contact me if you're trying -to do completely automated testing of your emulator. One simple approach -is to take a screenshot after all tests have run, or even just a -checksum of one, and compare this with a previous run. - - -Failure codes -------------- -Failed tests may print a failure code, and also short description of the -problem. For more information about a failure code, look in the -corresponding source file in source/; the point in the code where -"set_test n" occurs is where that failure code will be generated. -Failure code 1 is a general failure of the test; any further information -will be printed. - -Note that once a sub-test fails, no further tests for that file are run. - - -Console output --------------- -Information is printed on screen in a way that needs only minimum LCD -support, and won't hang if LCD output isn't supported at all. -Specifically, while polling LY to wait for vblank, it will time out if -it takes too long, so LY always reading back as the same value won't -hang the test. It's also OK if scrolling isn't supported; in this case, -text will appear starting at the top of the screen. - -Everything printed on screen is also sent to the game link port by -writing the character to SB, then writing $81 to SC. This is useful for -tests which print lots of information that scrolls off screen. - - -Source code ------------ -Source code is included for all tests, in source/. It can be used to -build the individual test ROMs. Code for the multi test isn't included -due to the complexity of putting everything together. - -Code is written for the wla-dx assembler. To assemble a particular test, -execute - - wla -o "source_filename.s" test.o - wlalink linkfile test.gb - -Test code uses a common shell framework contained in common/. - - -Internal framework operation ----------------------------- -Tests use a common framework for setting things up, reporting results, -and ending. All files first include "shell.inc", which sets up the ROM -header and shell code, and includes other commonly-used modules. - -One oddity is that test code is first copied to internal RAM at $D000, -then executed there. This allows self-modification, and ensures the code -is executed the same way it is on my devcart, which doesn't have a -rewritable ROM as most do. - -Some macros are used to simplify common tasks: - - Macro Behavior - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wreg addr,data Writes data to addr using LDH - lda addr Loads byte from addr into A using LDH - sta addr Stores A at addr using LDH - delay n Delays n cycles, where NOP = 1 cycle - delay_msec n Delays n milliseconds - set_test n,"Cause" Sets failure code and optional string - -Routines and macros are documented where they are defined. - --- -Shay Green diff --git a/playing-coffee - Copy/roms/mem_timing/source/01-read_timing.s b/playing-coffee - Copy/roms/mem_timing/source/01-read_timing.s deleted file mode 100644 index e119615..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/01-read_timing.s +++ /dev/null @@ -1,148 +0,0 @@ -; Tests timing of accesses made by -; memory read instructions - -.include "shell.inc" -.include "tima_64.s" - -instructions: - ; last value is time of read - .byte $B6,$00,$00,2 ; OR (HL) - .byte $BE,$00,$00,2 ; CP (HL) - .byte $86,$00,$00,2 ; ADD (HL) - .byte $8E,$00,$00,2 ; ADC (HL) - .byte $96,$00,$00,2 ; SUB (HL) - .byte $9E,$00,$00,2 ; SBC (HL) - .byte $A6,$00,$00,2 ; AND (HL) - .byte $AE,$00,$00,2 ; XOR (HL) - .byte $46,$00,$00,2 ; LD B,(HL) - .byte $4E,$00,$00,2 ; LD C,(HL) - .byte $56,$00,$00,2 ; LD D,(HL) - .byte $5E,$00,$00,2 ; LD E,(HL) - .byte $66,$00,$00,2 ; LD H,(HL) - .byte $6E,$00,$00,2 ; LD L,(HL) - .byte $7E,$00,$00,2 ; LD A,(HL) - .byte $F2,$00,$00,2 ; LDH A,(C) - .byte $0A,$00,$00,2 ; LD A,(BC) - .byte $1A,$00,$00,2 ; LD A,(DE) - .byte $2A,$00,$00,2 ; LD A,(HL+) - .byte $3A,$00,$00,2 ; LD A,(HL-) - .byte $F0,tima_64,4 ; LD A,($0000) - - .byte $CB,$46,$00,3 ; BIT 0,(HL) - .byte $CB,$4E,$00,3 ; BIT 1,(HL) - .byte $CB,$56,$00,3 ; BIT 2,(HL) - .byte $CB,$5E,$00,3 ; BIT 3,(HL) - .byte $CB,$66,$00,3 ; BIT 4,(HL) - .byte $CB,$6E,$00,3 ; BIT 5,(HL) - .byte $CB,$76,$00,3 ; BIT 6,(HL) - .byte $CB,$7E,$00,3 ; BIT 7,(HL) -instructions_end: - -main: - call init_tima_64 - set_test 0 - - ; Test instructions - ld hl,instructions -- call @time_instr - cp (hl) - call nz,@print_failed - inc hl - ld a,l - cp 3-byte instruction -; HL <- HL + 3 -@time_instr: - ; Copy instr - ld a,(hl+) - ld (instr+0),a - ld a,(hl+) - ld (instr+1),a - ld a,(hl+) - ld (instr+2),a - push hl - - ; Find result when access doesn't occur - ld b,0 - call @time_access - ld c,a - - ; Test for accesses on each cycle - ld b,0 -- push bc - call @time_access - pop bc - cp c - jr nz,@found - inc b - ld a,b - cp 10 - jr nz,- - ld b,0 - -@found: - ld a,b - pop hl - ret - -; Tests for read -; B -> which cycle to test -; A <- timer value after test -@time_access: - call sync_tima_64 - ld a,9 - sub b - call delay_a_20_cycles - xor a ; clear flags - ld hl,tima_64 - ld (hl),$7F - ld bc,tima_64 - ld de,tima_64 - ld a,$7F -instr: - nop - nop - nop - - ; Add all registers together to yield - ; unique value that differs based on - ; read occurring before or after tima_64 - ; increments. - push af - add hl,bc - add hl,de - pop de - add hl,de - ld a,h - add l - ret diff --git a/playing-coffee - Copy/roms/mem_timing/source/02-write_timing.s b/playing-coffee - Copy/roms/mem_timing/source/02-write_timing.s deleted file mode 100644 index acd6d9d..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/02-write_timing.s +++ /dev/null @@ -1,115 +0,0 @@ -; Tests timing of accesses made by -; memory write instructions - -.include "shell.inc" -.include "tima_64.s" - -instructions: - ; last value is time of write - .byte $36,$FF,$00,3 ; LD (HL),n - .byte $70,$00,$00,2 ; LD (HL),B - .byte $71,$00,$00,2 ; LD (HL),C - .byte $72,$00,$00,2 ; LD (HL),D - .byte $73,$00,$00,2 ; LD (HL),E - .byte $74,$00,$00,2 ; LD (HL),H - .byte $75,$00,$00,2 ; LD (HL),L - .byte $77,$00,$00,2 ; LD (HL),A - .byte $02,$00,$00,2 ; LD (BC),A - .byte $12,$00,$00,2 ; LD (DE),A - .byte $22,$00,$00,2 ; LD (HL+),A - .byte $32,$00,$00,2 ; LD (HL-),A - .byte $E2,$00,$00,2 ; LDH (C),A - .byte $E0,tima_64,4 ; LD (nn),A -instructions_end: - -main: - call init_tima_64 - set_test 0 - - ; Test instructions - ld hl,instructions -- call @test_instr - cp (hl) - call nz,@print_failed - inc hl - ld a,l - cp 3-byte instruction -; HL <- HL + 3 -@test_instr: - ; Copy instr - ld a,(hl+) - ld (instr+0),a - ld a,(hl+) - ld (instr+1),a - ld a,(hl+) - ld (instr+2),a - push hl - - ; Test for writes on each cycle - ld b,0 -- push bc - call @time_write - pop bc - cp tima_64 - jr z,@no_write - jr @found -@no_write: - inc b - ld a,b - cp 10 - jr nz,- - ld b,0 - -@found: - ld a,b - pop hl - ret - -; Tests for write -; B -> which cycle to test -; A <- timer value after test -@time_write: - call sync_tima_64 - ld a,13 - sub b - call delay_a_20_cycles - ld hl,tima_64 - ld bc,tima_64 - ld de,tima_64 - ld a, 3-byte instruction -; HL <- HL + 3 -@time_instr: - ; Copy instr - ld a,(hl+) - ld (instr+0),a - ld a,(hl+) - ld (instr+1),a - ld a,(hl+) - ld (instr+2),a - push hl - - ; Find result when access doesn't occur - ld b,0 - call @time_access - - ; Find first access - call @find_next_access - ld d,b - - ; Find second access - call @find_next_access - ld e,b - - pop hl - ret - -; A -> current timer result -; B -> starting clock -; B <- clock next access occurs on -; A <- new timer result -@find_next_access: - ld c,a -- call @time_access - cp c - ret nz - inc b - ld a,b - cp 10 - jr c,- - - ; Couldn't find time, so return 0/0 - ld a,c - ld b,0 - ld d,b - ret - -; Tests for access -; B -> which cycle to test -; A <- timer value after test -@time_access: - call sync_tima_64 - ld hl,tima_64 - ld (hl),$7F - ld a,17 - sub b - call delay_a_20_cycles - xor a ; clear flags -instr: - nop - nop - nop - delay 32 - ld a,(tima_64) - ret diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/build_gbs.s b/playing-coffee - Copy/roms/mem_timing/source/common/build_gbs.s deleted file mode 100644 index 7ac8d3c..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/build_gbs.s +++ /dev/null @@ -1,121 +0,0 @@ -; Build as GBS music file - -.memoryMap - defaultSlot 0 - slot 0 $3000 size $1000 - slot 1 $C000 size $1000 -.endMe - -.romBankSize $1000 -.romBanks 2 - - -;;;; GBS music file header - -.byte "GBS" -.byte 1 ; vers -.byte 1 ; songs -.byte 1 ; first song -.word load_addr -.word reset -.word gbs_play -.word std_stack -.byte 0,0 ; timer -.ds $60,0 -load_addr: - -; WLA assumes we're building ROM and messes -; with bytes at the beginning, so skip them. -.ds $100,0 - - -;;;; Shell - -.include "runtime.s" - -init_runtime: - ld a,$01 ; Identify as DMG hardware - ld (gb_id),a - .ifdef TEST_NAME - print_str TEST_NAME,newline,newline - .endif - ret - -std_print: - sta SB - wreg SC,$81 - delay 2304 - ret - -post_exit: - call play_byte -forever: - wreg NR52,0 ; sound off -- jp - - -.ifndef CUSTOM_RESET - gbs_play: -.endif -console_flush: -console_normal: -console_inverse: -console_set_mode: - ret - -; Reports A in binary as high and low tones, with -; leading low tone for reference. Omits leading -; zeroes. -; Preserved: AF, BC, DE, HL -play_byte: - push af - push hl - - ; HL = (A << 1) | 1 - scf - rla - ld l,a - ld h,0 - rl h - - ; Shift left until next-to-top bit is 1 -- add hl,hl - bit 6,h - jr z,- - - ; Reset sound - delay_msec 400 - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - -- add hl,hl - - ; Low or high pitch based on bit shifted out - ; of HL - ld a,0 - jr nc,+ - ld a,$FF -+ sta NR23 - - ; Play short tone - wreg NR21,$A0 - wreg NR22,$F0 - wreg NR24,$86 - delay_msec 75 - wreg NR22,0 - wreg NR23,$F8 - wreg NR24,$87 - delay_msec 200 - - ; Loop until HL = $8000 - ld a,h - xor $80 - or l - jr nz,- - - pop hl - pop af - ret - -.ends diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/build_rom.s b/playing-coffee - Copy/roms/mem_timing/source/common/build_rom.s deleted file mode 100644 index e1e220f..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/build_rom.s +++ /dev/null @@ -1,80 +0,0 @@ -; Build as GB ROM - -.memoryMap - defaultSlot 0 - slot 0 $0000 size $4000 - slot 1 $C000 size $4000 -.endMe - -.romBankSize $4000 ; generates $8000 byte ROM -.romBanks 2 - -.cartridgeType 1 ; MBC1 -.computeChecksum -.computeComplementCheck - - -;;;; GB ROM header - -; GB header read by bootrom -.org $100 - nop - jp reset - -; Nintendo logo required for proper boot -.byte $CE,$ED,$66,$66,$CC,$0D,$00,$0B -.byte $03,$73,$00,$83,$00,$0C,$00,$0D -.byte $00,$08,$11,$1F,$88,$89,$00,$0E -.byte $DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 -.byte $BB,$BB,$67,$63,$6E,$0E,$EC,$CC -.byte $DD,$DC,$99,$9F,$BB,$B9,$33,$3E - -; Internal name -.ifdef ROM_NAME - .byte ROM_NAME -.endif - -; CGB/DMG requirements -.org $143 - .ifdef REQUIRE_CGB - .byte $C0 - .else - .ifndef REQUIRE_DMG - .byte $80 - .endif - .endif - -.org $200 - - -;;;; Shell - -.include "runtime.s" -.include "console.s" - -init_runtime: - call console_init - .ifdef TEST_NAME - print_str TEST_NAME,newline,newline - .endif - ret - -std_print: - push af - sta SB - wreg SC,$81 - delay 2304 - pop af - jp console_print - -post_exit: - call console_show - call play_byte -forever: - wreg NR52,0 ; sound off -- jr - - -play_byte: - ret - -.ends diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/console.bin b/playing-coffee - Copy/roms/mem_timing/source/common/console.bin deleted file mode 100644 index b02f2d3..0000000 Binary files a/playing-coffee - Copy/roms/mem_timing/source/common/console.bin and /dev/null differ diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/console.s b/playing-coffee - Copy/roms/mem_timing/source/common/console.s deleted file mode 100644 index 5307f6b..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/console.s +++ /dev/null @@ -1,291 +0,0 @@ -; Scrolling text console - -; Console is 20x18 characters. Buffers lines, so -; output doesn't appear until a newline or flush. -; If scrolling isn't supported (i.e. SCY is treated -; as if always zero), the first 18 lines will -; still print properly). Also works properly if -; LY isn't supported (always reads back as the same -; value). - -.define console_width 20 - -.define console_buf bss+0 -.define console_pos bss+console_width -.define console_mode bss+console_width+1 -.define console_scroll bss+console_width+2 -.redefine bss bss+console_width+3 - - -; Waits for start of LCD blanking period -; Preserved: BC, DE, HL -console_wait_vbl: - push bc - - ; Wait for start of vblank, with - ; timeout in case LY doesn't work - ; or LCD is disabled. - ld bc,-1250 -- inc bc - ld a,b - or c - jr z,@timeout - lda LY - cp 144 - jr nz,- -@timeout: - - pop bc - ret - - -; Initializes text console -console_init: - call console_hide - - ; CGB-specific inits - ld a,(gb_id) - and gb_id_cgb - call nz,@init_cgb - - ; Clear nametable - ld a,' ' - call @fill_nametable - - ; Load tiles - ld hl,TILES+$200 - ld c,0 - call @load_tiles - ld hl,TILES+$A00 - ld c,$FF - call @load_tiles - - ; Init state - ld a,console_width - ld (console_pos),a - ld a,0 - ld (console_mode),a - ld a,-8 - ld (console_scroll),a - call console_scroll_up_ - jr console_show - -@fill_nametable: - ld hl,BGMAP0 - ld b,4 -- ld (hl),a - inc l - jr nz,- - inc h - dec b - jr nz,- - ret - -@init_cgb: - ; Clear palette - wreg $FF68,$80 - ld b,16 -- wreg $FF69,$FF - wreg $FF69,$7F - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - dec b - jr nz,- - - ; Clear attributes - ld a,1 - ld (VBK),a - ld a,0 - call @fill_nametable - - ld a,0 - ld (VBK),a - ret - -@load_tiles: - ld de,ASCII - ld b,96 --- push bc - ld b,8 -- ld a,(de) - inc de - xor c - ldi (hl),a - ldi (hl),a - dec b - jr nz,- - pop bc - dec b - jr nz,-- - ret - - -; Shows console display -; Preserved: AF, BC, DE, HL -console_show: - push af - - ; Enable LCD - call console_wait_vbl - wreg LCDC,$91 - wreg SCX,0 - wreg BGP,$E4 - - jp console_apply_scroll_ - - -; Hides console display by turning LCD off -; Preserved: AF, BC, DE, HL -console_hide: - push af - - ; LCD off - call console_wait_vbl - wreg LCDC,$11 - - pop af - ret - - -; Changes to normal text mode -; Preserved: BC, DE, HL -console_normal: - xor a - jr console_set_mode - -; Changes to inverse text mode -; Preserved: BC, DE, HL -console_inverse: - ld a,$80 - -; Changes console mode to A. -; 0: Normal, $80: Inverse -; Preserved: BC, DE, HL -console_set_mode: - and $80 - ld (console_mode),a - ret - - -; Prints char A to console. Will not appear until -; a newline or flush occurs. -; Preserved: AF, BC, DE, HL -console_print: - push af - - cp 10 - jr z,console_newline_ - - push hl - push af - ld hl,console_pos - ldi a,(hl) - cp BGMAP0) >> 2 - add hl,hl - add hl,hl - - ; Copy line - ld de,console_buf + console_width -- dec e - ld a,(de) - ldi (hl),a - ld a,e - cp checksum - ldi (hl),a - ld (hl),d - inc l - ld (hl),c - inc l - ld (hl),b - - pop hl - pop de - pop bc - pop af - ret diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/delay.s b/playing-coffee - Copy/roms/mem_timing/source/common/delay.s deleted file mode 100644 index 65eb9c0..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/delay.s +++ /dev/null @@ -1,220 +0,0 @@ -; Delays in cycles, milliseconds, etc. - -; All routines are re-entrant (no global data). Routines never -; touch BC, DE, or HL registers. These ASSUME CPU is at normal -; speed. If running at double speed, msec/usec delays are half advertised. - -; Delays n cycles, from 0 to 16777215 -; Preserved: AF, BC, DE, HL -.macro delay ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 16777215 - .printt "Delay must be < 16777216" - .fail - .endif - delay_ n&$FFFF, n>>16 -.endm - -; Delays n clocks, from 0 to 16777216*4. Must be multiple of 4. -; Preserved: AF, BC, DE, HL -.macro delay_clocks ARGS n - .if n # 4 != 0 - .printt "Delay must be a multiple of 4" - .fail - .endif - delay_ (n/4)&$FFFF,(n/4)>>16 -.endm - -; Delays n microseconds (1/1000000 second) -; n can range from 0 to 4000 usec. -; Preserved: AF, BC, DE, HL -.macro delay_usec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 4000 - .printt "Delay must be <= 4000 usec" - .fail - .endif - delay_ ((n * 1048576 + 500000) / 1000000)&$FFFF,((n * 1048576 + 500000) / 1000000)>>16 -.endm - -; Delays n milliseconds (1/1000 second) -; n can range from 0 to 10000 msec. -; Preserved: AF, BC, DE, HL -.macro delay_msec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 10000 - .printt "Delay must be <= 10000 msec" - .fail - .endif - delay_ ((n * 1048576 + 500) / 1000)&$FFFF, ((n * 1048576 + 500) / 1000)>>16 -.endm - - ; All the low/high quantities are to deal wla-dx's asinine - ; restriction full expressions must evaluate to a 16-bit - ; value. If the author ever rectifies this, all "high" - ; arguments can be treated as zero and removed. Better yet, - ; I'll just find an assembler that didn't crawl out of - ; the sewer (this is one of too many bugs I've wasted - ; hours working around). - - .define max_short_delay 28 - - .macro delay_long_ ARGS n, high - ; 0+ to avoid assembler treating as memory read - ld a,0+(((high<<16)+n) - 11) >> 16 - call delay_65536a_9_cycles_ - delay_nosave_ (((high<<16)+n) - 11)&$FFFF, 0 - .endm - - ; Doesn't save AF, allowing minimization of AF save/restore - .macro delay_nosave_ ARGS n, high - ; 65536+11 = maximum delay using delay_256a_9_cycles_ - ; 255+22 = maximum delay using delay_a_20_cycles - ; 22 = minimum delay using delay_a_20_cycles - .if high > 1 - delay_long_ n, high - .else - .if high*n > 11 - delay_long_ n, high - .else - .if (high*(255+22+1))|n > 255+22 - ld a,>(((high<<16)+n) - 11) - call delay_256a_9_cycles_ - delay_nosave_ <(((high<<16)+n) - 11), 0 - .else - .if n >= 22 - ld a,n - 22 - call delay_a_20_cycles - .else - delay_short_ n - .endif - .endif - .endif - .endif - .endm - - .macro delay_ ARGS low, high - .if (high*(max_short_delay+1))|low > max_short_delay - push af - delay_nosave_ ((high<<16)+low - 7)&$FFFF, ((high<<16)+low - 7)>>16 - pop af - .else - delay_short_ low - .endif - .endm - - -; Delays A cycles + overhead -; Preserved: BC, DE, HL -; Time: A+20 cycles (including CALL) -delay_a_20_cycles: -- sub 5 ; 2 - jr nc,- ;3/2 do multiples of 5 - rra ; 1 - jr nc,+ ;3/2 bit 0 -+ adc 1 ; 2 - ret nc ;5/2 -1: 0 cycles - ret z ;5/2 0: 2 cycles - nop ; 1 1: 4 cycles - ret ; 4 (thanks to dclxvi for original algorithm) - -; Delays A*256 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*256+12 cycles (including CALL) -delay_256a_12_cycles: - or a ; 1 - ret z ; 5/2 -delay_256a_9_cycles_: -- delay 256-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays A*65536 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*65536+12 cycles (including CALL) -delay_65536a_12_cycles: - or a ; 1 - ret z ;5/2 -delay_65536a_9_cycles_: -- delay 65536-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays H*256+L cycles + overhead -; Preserved: AF, BC, DE, HL -; Time: H*256+L+51 cycles -delay_hl_51_cycles: - push af - ld a,h - call delay_256a_12_cycles - ld a,l - call delay_a_20_cycles - pop af - ret - - ; delay_short_ macro calls into these - .ds max_short_delay-10,$00 ; NOP repeated several times -delay_unrolled_: - ret - -.macro delay_short_ ARGS n - .if n < 0 - .fail - .endif - .if n > max_short_delay - .fail - .endif - - .if n == 1 - nop - .endif - .if n == 2 - nop - nop - .endif - .if n == 3 - .byte $18,$00 ; JR +0 - .endif - .if n == 4 - .byte $18,$00 ; JR +0 - nop - .endif - .if n == 5 - .byte $18,$00 ; JR +0 - nop - nop - .endif - .if n == 6 - .byte $18,$00 ; JR +0 - .byte $18,$00 ; JR +0 - .endif - .if n == 7 - push af - pop af - .endif - .if n == 8 - push af - pop af - nop - .endif - .if n == 9 - push af - pop af - nop - nop - .endif - .if n >= 10 - call delay_unrolled_ + 10 - n - .endif -.endm diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/gb.inc b/playing-coffee - Copy/roms/mem_timing/source/common/gb.inc deleted file mode 100644 index 31bbf14..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/gb.inc +++ /dev/null @@ -1,64 +0,0 @@ -; Game Boy hardware addresses - -; Memory -.define VRAM $8000 ; video memory -.define TILES $8000 ; tile images -.define BGMAP0 $9800 ; first 32x32 tilemap -.define BGMAP1 $9C00 ; second 32x32 tilemap -.define WRAM $C000 ; internal memory -.define OAM $FE00 ; sprite memory -.define HRAM $FF80 ; fast memory for LDH - -.define P1 $FF00 - -; Game link I/O -.define SB $FF01 -.define SC $FF02 - -; Interrupts -.define DIV $FF04 -.define TIMA $FF05 -.define TMA $FF06 -.define TAC $FF07 -.define IF $FF0F -.define IE $FFFF - -; LCD registers -.define LCDC $FF40 ; control -.define STAT $FF41 ; status -.define SCY $FF42 ; scroll Y -.define SCX $FF43 ; scroll X -.define LY $FF44 ; current Y being rendered -.define BGP $FF47 - -.define KEY1 $FF4D ; for changing CPU speed -.define VBK $FF4F - -; Sound registers -.define NR10 $FF10 -.define NR11 $FF11 -.define NR12 $FF12 -.define NR13 $FF13 -.define NR14 $FF14 - -.define NR21 $FF16 -.define NR22 $FF17 -.define NR23 $FF18 -.define NR24 $FF19 - -.define NR30 $FF1A -.define NR31 $FF1B -.define NR32 $FF1C -.define NR33 $FF1D -.define NR34 $FF1E - -.define NR41 $FF20 -.define NR42 $FF21 -.define NR43 $FF22 -.define NR44 $FF23 - -.define NR50 $FF24 -.define NR51 $FF25 -.define NR52 $FF26 - -.define WAVE $FF30 diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/macros.inc b/playing-coffee - Copy/roms/mem_timing/source/common/macros.inc deleted file mode 100644 index c413bd5..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/macros.inc +++ /dev/null @@ -1,73 +0,0 @@ -; General macros - -; Reads A from addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 3 cycles -.macro lda ARGS addr - ldh a,(addr - $FF00) -.endm - -; Writes A to addr, from $FF00 to $FFFF -; Preserved: AF, BC, DE, HL -; Time: 3 cycles -.macro sta ARGS addr - ldh (addr - $FF00),a -.endm - -; Writes immediate data to addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 5 cycles -.macro wreg ARGS addr, data - ld a,data - sta addr -.endm - -; Calls routine multiple times, with A having the -; value 'start' the first time, 'start+step' the -; second time, up to 'end' for the last time. -; Preserved: BC, DE, HL -.macro for_loop ; routine,start,end,step - ld a,\2 - -for_loop\@: - push af - call \1 - pop af - - add \4 - cp <(\3 + \4) - jr nz,for_loop\@ -.endm - -; Calls routine n times. The value of A in the routine -; counts from 0 to n-1. -; Preserved: BC, DE, HL -.macro loop_n_times ; routine,n - for_loop \1,0,\2 - 1,+1 -.endm - -; Same as for_loop, but counts with 16-bit value in BC. -; Preserved: DE, HL -.macro for_loop16 ; routine,start,end,step - ld bc,\2 - -for_loop16\@: - push bc - call \1 - pop bc - - ld a,c - add <\4 - ld c,a - - ld a,b - adc >\4 - ld b,a - - cp >(\3+\4) - jr nz,for_loop16\@ - - ld a,c - cp <(\3+\4) - jr nz,for_loop16\@ -.endm diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/numbers.s b/playing-coffee - Copy/roms/mem_timing/source/common/numbers.s deleted file mode 100644 index 6d6faf8..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/numbers.s +++ /dev/null @@ -1,177 +0,0 @@ -; Printing of numeric values - -; Prints value of indicated register/pair -; as 2/4 hex digits, followed by a space. -; Updates checksum with printed values. -; Preserved: AF, BC, DE, HL - -print_regs: - call print_af - call print_bc - call print_de - call print_hl - call print_newline - ret - -print_a: - push af -print_a_: - call print_hex - ld a,' ' - call print_char_nocrc - pop af - ret - -print_af: - push af - call print_hex - pop af -print_f: - push bc - push af - pop bc - call print_c - pop bc - ret - -print_b: - push af - ld a,b - jr print_a_ - -print_c: - push af - ld a,c - jr print_a_ - -print_d: - push af - ld a,d - jr print_a_ - -print_e: - push af - ld a,e - jr print_a_ - -print_h: - push af - ld a,h - jr print_a_ - -print_l: - push af - ld a,l - jr print_a_ - -print_bc: - push af - push bc -print_bc_: - ld a,b - call print_hex - ld a,c - pop bc - jr print_a_ - -print_de: - push af - push bc - ld b,d - ld c,e - jr print_bc_ - -print_hl: - push af - push bc - ld b,h - ld c,l - jr print_bc_ - - -; Prints A as two hex chars and updates checksum -; Preserved: BC, DE, HL -print_hex: - call update_crc -print_hex_nocrc: - push af - swap a - call + - pop af - -+ and $0F - cp 10 - jr c,+ - add 7 -+ add '0' - jp print_char_nocrc - - -; Prints char_nz if Z flag is clear, -; char_z if Z flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nz ARGS char_nz, char_z - push af - ld a,char_nz - jr nz,print_nz\@ - ld a,char_z -print_nz\@: - call print_char - pop af -.endm - - -; Prints char_nc if C flag is clear, -; char_c if C flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nc ARGS char_nc, char_c - push af - ld a,char_nc - jr nz,print_nc\@ - ld a,char_c -print_nc\@: - call print_char - pop af -.endm - - -; Prints A as 2 decimal digits -; Preserved: AF, BC, DE, HL -print_dec2: - push af - push bc - jr + - - -; Prints A as 1-3 digit decimal value -; Preserved: AF, BC, DE, HL -print_dec: - push af - push bc - - cp 10 - jr c,++ - ld c,100 - cp c - call nc,@digit -+ ld c,10 - call @digit -++ add '0' - call print_char - - pop bc - pop af - ret - -@digit: - ld b,'0'-1 -- inc b - sub c - jr nc,- - add c - - ld c,a - ld a,b - call print_char - ld a,c - ret diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/printing.s b/playing-coffee - Copy/roms/mem_timing/source/common/printing.s deleted file mode 100644 index ad9d811..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/printing.s +++ /dev/null @@ -1,98 +0,0 @@ -; Main printing routine that checksums and -; prints to output device - -; Character that does equivalent of print_newline -.define newline 10 - -; Prints char without updating checksum -; Preserved: BC, DE, HL -.define print_char_nocrc bss -.redefine bss bss+3 - - -; Initializes printing. HL = print routine -init_printing: - ld a,l - ld (print_char_nocrc+1),a - ld a,h - ld (print_char_nocrc+2),a - jr show_printing - - -; Hides/shows further printing -; Preserved: BC, DE, HL -hide_printing: - ld a,$C9 ; RET - jr + -show_printing: - ld a,$C3 ; JP (nn) -+ ld (print_char_nocrc),a - ret - - -; Prints character and updates checksum UNLESS -; it's a newline. -; Preserved: AF, BC, DE, HL -print_char: - push af - cp newline - call nz,update_crc - call print_char_nocrc - pop af - ret - - -; Prints space. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_space: - push af - ld a,' ' - call print_char_nocrc - pop af - ret - - -; Advances to next line. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_newline: - push af - ld a,newline - call print_char_nocrc - pop af - ret - - -; Prints immediate string -; Preserved: AF, BC, DE, HL -.macro print_str ; string,string2 - push hl - call print_str_ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 - pop hl -.endm - -print_str_: - pop hl - call print_str_hl - jp hl - - -; Prints zero-terminated string pointed to by HL. -; On return, HL points to byte AFTER zero terminator. -; Preserved: AF, BC, DE -print_str_hl: - push af - jr + -- call print_char -+ ldi a,(hl) - or a - jr nz,- - pop af - ret diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/runtime.s b/playing-coffee - Copy/roms/mem_timing/source/common/runtime.s deleted file mode 100644 index 90cd24f..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/runtime.s +++ /dev/null @@ -1,142 +0,0 @@ -; Common routines and runtime - -; Must be defined by target-specific runtime: -; -; init_runtime: ; target-specific inits -; std_print: ; default routine to print char A -; post_exit: ; called at end of std_exit -; report_byte: ; report A to user - -.define RUNTIME_INCLUDED 1 - -.ifndef bss - ; address of next normal variable - .define bss $D800 -.endif - -.ifndef dp - ; address of next direct-page ($FFxx) variable - .define dp $FF80 -.endif - -; DMG/CGB hardware identifier -.define gb_id_cgb $10 ; mask for testing CGB bit -.define gb_id_devcart $04 ; mask for testing "on devcart" bit - -.define gb_id bss -.redefine bss bss+1 - -; Stack is normally here -.define std_stack $DFFF - -; Copies $1000 bytes from HL to $C000, then jumps to it. -; A is preserved for jumped-to code. -copy_to_wram_then_run: - ld b,a - - ld de,$C000 - ld c,$10 -- ldi a,(hl) - ld (de),a - inc e - jr nz,- - inc d - dec c - jr nz,- - - ld a,b - jp $C000 - -.ifndef CUSTOM_RESET - reset: - ; Run code from $C000, as is done on devcart. This - ; ensures minimal difference in how it behaves. - ld hl,$4000 - jp copy_to_wram_then_run - - .bank 1 slot 1 - .org $0 ; otherwise wla pads with lots of zeroes - jp std_reset -.endif - -; Common routines -.include "gb.inc" -.include "macros.inc" -.include "delay.s" -.include "crc.s" -.include "printing.s" -.include "numbers.s" -.include "testing.s" - -; Sets up hardware and runs main -std_reset: - - ; Init hardware - di - ld sp,std_stack - - ; Save DMG/CGB id - ld (gb_id),a - - ; Init hardware - .ifndef BUILD_GBS - wreg TAC,$00 - wreg IF,$00 - wreg IE,$00 - .endif - - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - - ; TODO: clear all memory? - - ld hl,std_print - call init_printing - call init_testing - call init_runtime - call reset_crc ; in case init_runtime prints anything - - delay_msec 250 - - ; Run user code - call main - - ; Default is to successful exit - ld a,0 - jp exit - - -; Exits code and reports value of A -exit: - ld sp,std_stack - push af - call + - pop af - jp post_exit - -+ push af - call print_newline - call show_printing - pop af - - ; Report exit status - cp 1 - - ; 0: "" - ret c - - ; 1: "Failed" - jr nz,+ - print_str "Failed",newline - ret - - ; n: "Failed #n" -+ print_str "Failed #" - call print_dec - call print_newline - ret - -; returnOrg puts this code AFTER user code. -.section "runtime" returnOrg diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/testing.s b/playing-coffee - Copy/roms/mem_timing/source/common/testing.s deleted file mode 100644 index c102f78..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/testing.s +++ /dev/null @@ -1,176 +0,0 @@ -; Diagnostic and testing utilities - -.define result bss+0 -.define test_name bss+1 -.redefine bss bss+3 - - -; Sets test code and optional error text -; Preserved: AF, BC, DE, HL -.macro set_test ; code[,text[,text2]] - push hl - call set_test_ - jr @set_test\@ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 -@set_test\@: - pop hl -.endm - -set_test_: - pop hl - push hl - push af - inc hl - inc hl - ldi a,(hl) - ld (result),a - ld a,l - ld (test_name),a - ld a,h - ld (test_name+1),a - pop af - ret - - -; Initializes testing module -init_testing: - set_test $FF - call init_crc - ret - - -; Reports "Passed", then exits with code 0 -tests_passed: - call print_newline - print_str "Passed" - ld a,0 - jp exit - - -; Reports "Done" if set_test has never been used, -; "Passed" if set_test 0 was last used, or -; failure if set_test n was last used. -tests_done: - ld a,(result) - inc a - jr z,+ - dec a - jr z,tests_passed - jr test_failed -+ print_str "Done" - ld a,0 - jp exit - - -; Reports current error text and exits with result code -test_failed: - ld a,(test_name) - ld l,a - ld a,(test_name+1) - ld h,a - ld a,(hl) - or a - jr z,+ - call print_newline - call print_str_hl - call print_newline -+ - ld a,(result) - cp 1 ; if a = 0 then a = 1 - adc 0 - jp exit - - -; Prints checksum as 8-character hex value -; Preserved: AF, BC, DE, HL -print_crc: - push af - - ; Must read checksum entirely before printing, - ; since printing updates it. - lda checksum - cpl - push af - - lda checksum+1 - cpl - push af - - lda checksum+2 - cpl - push af - - lda checksum+3 - cpl - - call print_hex - pop af - call print_hex - pop af - call print_hex - pop af - call print_a - - pop af - ret - - -; If checksum doesn't match expected, reports failed test. -; Passing 0 just prints checksum. Clears checksum afterwards. -.macro check_crc ARGS crc - .if crc == 0 - call show_printing - call print_newline - call print_crc - .else - ld bc,(crc >> 16) ~ $FFFF - ld de,(crc & $FFFF) ~ $FFFF - call check_crc_ - .endif -.endm - -check_crc_: - lda checksum+0 - cp e - jr nz,+ - - lda checksum+1 - cp d - jr nz,+ - - lda checksum+2 - cp c - jr nz,+ - - lda checksum+3 - cp b - jr nz,+ - - jp reset_crc - -+ call print_crc - jp test_failed - - -; Updates checksum with bytes from addr to addr+size-1 -.macro checksum_mem ARGS addr,size - ld hl,addr - ld bc,size - call checksum_mem_ -.endm - -checksum_mem_: -- ldi a,(hl) - call update_crc - dec bc - ld a,b - or c - jr nz,- - ret diff --git a/playing-coffee - Copy/roms/mem_timing/source/common/tima_64.s b/playing-coffee - Copy/roms/mem_timing/source/common/tima_64.s deleted file mode 100644 index 1db7211..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/common/tima_64.s +++ /dev/null @@ -1,33 +0,0 @@ -; Timer that's incremented every 64 cycles - -; Initializes timer for use by sync_tima_64 -init_tima_64: - wreg TMA,0 - wreg TAC,$07 - ret - -; Synchronizes to timer -sync_tima_64: - push af - push hl - - ld a,0 - ld hl,TIMA - ld (hl),a -- or (hl) - jr z,- - -- delay 65-12 - xor a - ld (hl),a - or (hl) - delay 4 - jr z,- - - pop hl - pop af - ret - -; Read from this to get count that's incremented -; every 64 cycles. -.define tima_64 TIMA diff --git a/playing-coffee - Copy/roms/mem_timing/source/linkfile b/playing-coffee - Copy/roms/mem_timing/source/linkfile deleted file mode 100644 index 02a5a2e..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/linkfile +++ /dev/null @@ -1,2 +0,0 @@ -[objects] -test.o diff --git a/playing-coffee - Copy/roms/mem_timing/source/shell.inc b/playing-coffee - Copy/roms/mem_timing/source/shell.inc deleted file mode 100644 index 277a9b7..0000000 --- a/playing-coffee - Copy/roms/mem_timing/source/shell.inc +++ /dev/null @@ -1,21 +0,0 @@ -.incdir "common" - -; GBS music file -.ifdef BUILD_GBS - .include "build_gbs.s" -.endif - -; Devcart -.ifdef BUILD_DEVCART - .include "build_devcart.s" -.endif - -; Sub-test in a multi-test ROM -.ifdef BUILD_MULTI - .include "build_multi.s" -.endif - -; GB ROM (default) -.ifndef RUNTIME_INCLUDED - .include "build_rom.s" -.endif diff --git a/playing-coffee - Copy/roms/oam_bug/oam_bug.gb b/playing-coffee - Copy/roms/oam_bug/oam_bug.gb deleted file mode 100644 index 42ff9ca..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/oam_bug.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/readme.txt b/playing-coffee - Copy/roms/oam_bug/readme.txt deleted file mode 100644 index cf59776..0000000 --- a/playing-coffee - Copy/roms/oam_bug/readme.txt +++ /dev/null @@ -1,109 +0,0 @@ -OAM Corruption Test -------------------- -* Verifies OAM corruption bug on DMG. - -* Occurs when 16-bit increment/decrement is made of value in range $FE00 -to $FEFF, during around the first 20 cycles of a visible scanline while -LCD is on, where 114 cycles = 1 scanline. - -* Causes several bytes of OAM to be copied from one place to another. - -* Occurs with instructions that do increment: - INC rp (including SP) - DEC rp - POP rp counts as two increments - PUSH rp counts as two increments - LD A,(HL+) - LD A,(HL-) - -* Doesn't occur with instructions that do 16-bit add: - LD HL,SP+n - ADD HL,rp - ADD SP,n - -* Doesn't occur anytime during the 10 vblank scanlines. - -* Doesn't occur when LCD is off, no matter when it happens. - -* Corruption depends on when it occurs. - - -Multi-ROM ---------- -In the main directory is a single ROM/GBS which runs all the tests. It -prints a test's number, runs the test, then "ok" if it passes, otherwise -a failure code. Once all tests have completed it either reports that all -tests passed, or reports the number of the first failed test as the -result code (1 = first). Finally, it makes several beeps. If a test -fails, it can be run on its own by finding the corresponding ROM/GBS in -the singles directories. - -Ths compact format on screen is to avoid having the results scroll off -the top, so the test can be started and allowed to run without having to -constantly monitor the display. - - -Failure information -------------------- -For more information about a failure code or information printed, see -the test's source code in source/. To find failure code N, search for -"set_test N", which will usually be before the subtest which failed. - - -Flashes, clicks, other glitches -------------------------------- -Some tests might need to turn the screen off and on, or cause slight -audio clicks. This does not indicate failure, and should be ignored. -Only the test result reported at the end is important, unless stated -otherwise. - - -LCD support ------------ -Tests generally print information on screen. The tests will work fine if -run on an emulator with NO LCD support, or as an GBS which has no -inherent screen; in particular, the VBL wait routine has a timeout in -case LY doesn't reflect the current LCD line. The text printing will -also work if the LCD doesn't support scrolling. - - -Output to memory ----------------- -Text output and the final result are also written to memory at $A000, -allowing testing a very minimal emulator that supports little more than -CPU and RAM. To reliably indicate that the data is from a test and not -random data, $A001-$A003 are written with a signature: $DE,$B0,$61. If -this is present, then the text string and final result status are valid. - -$A000 holds the overall status. If the test is still running, it holds -$80, otherwise it holds the final result code. - -All text output is appended to a zero-terminated string at $A004. An -emulator could regularly check this string for any additional -characters, and output them, allowing real-time text output, rather than -just printing the final output at the end. - - -GBS versions ------------- -Many GBS-based tests require that the GBS player either not interrupt -the init routine with the play routine, or if they do, not interrupt the -play routine again if it hasn't returned yet. This is because many tests -need to run for a while without returning. - -In addition to the other text output methods described above, GBS builds -report essential information bytes audibly, including the final result. -A byte is reported as a series of tones. The code is in binary, with a -low tone for 0 and a high tone for 1. The first tone is always a zero. A -final code of 0 means passed, 1 means failure, and 2 or higher indicates -a specific reason as listed in the source code by the corresponding -set_code line. Examples: - -Tones Binary Decimal Meaning -- - - - - - - - - - - - - - - - - - - - -low 0 0 passed -low high 01 1 failed -low high low 010 2 error 2 - --- -Shay Green diff --git a/playing-coffee - Copy/roms/oam_bug/rom_singles/1-lcd_sync.gb b/playing-coffee - Copy/roms/oam_bug/rom_singles/1-lcd_sync.gb deleted file mode 100644 index 8f3d856..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/rom_singles/1-lcd_sync.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/rom_singles/2-causes.gb b/playing-coffee - Copy/roms/oam_bug/rom_singles/2-causes.gb deleted file mode 100644 index b997cda..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/rom_singles/2-causes.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/rom_singles/3-non_causes.gb b/playing-coffee - Copy/roms/oam_bug/rom_singles/3-non_causes.gb deleted file mode 100644 index d545e83..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/rom_singles/3-non_causes.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/rom_singles/4-scanline_timing.gb b/playing-coffee - Copy/roms/oam_bug/rom_singles/4-scanline_timing.gb deleted file mode 100644 index dc38b26..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/rom_singles/4-scanline_timing.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/rom_singles/5-timing_bug.gb b/playing-coffee - Copy/roms/oam_bug/rom_singles/5-timing_bug.gb deleted file mode 100644 index 47a5c02..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/rom_singles/5-timing_bug.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/rom_singles/6-timing_no_bug.gb b/playing-coffee - Copy/roms/oam_bug/rom_singles/6-timing_no_bug.gb deleted file mode 100644 index b4e67e9..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/rom_singles/6-timing_no_bug.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/rom_singles/7-timing_effect.gb b/playing-coffee - Copy/roms/oam_bug/rom_singles/7-timing_effect.gb deleted file mode 100644 index 2212779..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/rom_singles/7-timing_effect.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/rom_singles/8-instr_effect.gb b/playing-coffee - Copy/roms/oam_bug/rom_singles/8-instr_effect.gb deleted file mode 100644 index 464a5f4..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/rom_singles/8-instr_effect.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/source/1-lcd_sync.s b/playing-coffee - Copy/roms/oam_bug/source/1-lcd_sync.s deleted file mode 100644 index 3c4f5e5..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/1-lcd_sync.s +++ /dev/null @@ -1,28 +0,0 @@ -; Verifies LCD timing when turning on. Necessary for -; timing tests to work right. - -; With LCD off, turning it on synchronizes to beginning -; of first visible scanline - -.include "oam_bug.inc" - -main: - set_test 2,"Turning LCD on starts too late in scanline" - call disable_lcd - ld a,$81 - ldh (LCDC-$FF00),a ; LCD on - delay 109 - ldh a,(LY-$FF00) ; just before LY increments - cp 0 - jp nz,test_failed - - set_test 3,"Turning LCD on starts too early in scanline" - call disable_lcd - ld a,$81 - ldh (LCDC-$FF00),a ; LCD on - delay 110 - ldh a,(LY-$FF00) ; just after LY increments - cp 1 - jp nz,test_failed - - jp tests_passed diff --git a/playing-coffee - Copy/roms/oam_bug/source/2-causes.s b/playing-coffee - Copy/roms/oam_bug/source/2-causes.s deleted file mode 100644 index 15b725c..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/2-causes.s +++ /dev/null @@ -1,86 +0,0 @@ -; Things that cause corruption - -.include "oam_bug.inc" - -main: - save_sp - - set_test 2,"LD DE,$FE00 : INC DE" - call begin - ld de,$FE00 - inc de - call end - - set_test 3,"LD DE,$FE00 : DEC DE" - call begin - ld de,$FE00 - dec de - call end - - set_test 4,"LD DE,$FEFF : INC DE" - call begin - ld de,$FEFF - inc de - call end - - set_test 5,"LD BC,$FE00 : INC BC" - call begin - ld bc,$FE00 - inc bc - call end - - set_test 6,"LD HL,$FE00 : INC HL" - call begin - ld hl,$FE00 - inc hl - call end - - set_test 7,"LD SP,$FE00 : INC SP" - call begin - ld sp,$FE00 - inc sp - restore_sp - call end - - set_test 8,"LD SP,$FDFF : POP BC" - call begin - ld sp,$FDFF - pop bc - restore_sp - call end - - set_test 9,"LD SP,$FE00 : PUSH BC" - call begin - ld sp,$FE00 - push bc - restore_sp - call end - - set_test 10,"LD HL,$FE00 : LD A,(HL+)" - call begin - ld hl,$FE00 - ld a,(hl+) - restore_sp - call end - - set_test 11,"LD HL,$FE00 : LD A,(HL-)" - call begin - ld hl,$FE00 - ld a,(hl-) - restore_sp - call end - - jp tests_passed - -begin: - call disable_lcd - call fill_oam - wreg LCDC,$81 - delay 70224 - 6 - ret - -end: - call disable_lcd - call cp_oam - jp z,test_failed - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/3-non_causes.s b/playing-coffee - Copy/roms/oam_bug/source/3-non_causes.s deleted file mode 100644 index c161f97..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/3-non_causes.s +++ /dev/null @@ -1,86 +0,0 @@ -; Things that don't cause corruption - -.include "oam_bug.inc" - -main: - save_sp - - set_test 2,"When LCD is off" - call disable_lcd - call fill_oam - ld bc,2 * 70224/11 ; a couple of frames - ld de,$FE00 -- inc de - dec bc - dec de - ld a,b - or c - jr nz,- - call end - - set_test 3,"LD DE,$FF00 : DEC DE" - call begin - ld de,$FF00 - dec de - call end - - set_test 4,"LD DE,$FDFF : INC DE" - call begin - ld de,$FDFF - inc de - call end - - set_test 5,"LD DE,$7E00 : INC DE" - call begin - ld de,$7E00 - inc de - call end - - set_test 6,"LD DE,$FE00 : INC E" - call begin - ld de,$FE00 - inc e - call end - - set_test 7,"LD SP,$FDFE : POP BC" - call begin - ld sp,$FDFE - pop bc - restore_sp - call end - - set_test 8,"LD SP,$FE00 : LD HL,SP+1" - call begin - ld sp,$FE00 - ld hl,sp+1 - restore_sp - call end - - set_test 9,"LD HL,$FE00 : LD BC,$0001 : ADD HL,BC" - call begin - ld hl,$FE00 - ld bc,$0001 - add hl,bc - call end - - set_test 10,"LD SP,$FE00 : ADD SP,1" - call begin - ld sp,$FE00 - add sp,1 - restore_sp - call end - - jp tests_passed - -begin: - call disable_lcd - call fill_oam - wreg LCDC,$81 - delay 70224 - 6 - ret - -end: - call disable_lcd - call cp_oam - jp nz,test_failed - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/4-scanline_timing.s b/playing-coffee - Copy/roms/oam_bug/source/4-scanline_timing.s deleted file mode 100644 index e5136f2..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/4-scanline_timing.s +++ /dev/null @@ -1,62 +0,0 @@ -; Demonstrates exact timing for first scanline - -; With LCD off, turning it on synchronizes to beginning -; of first visible scanline - -.include "oam_bug.inc" - -main: - set_test 2,"INC DE just before first corruption" - call begin - ld de,$FE00 - ld a,$81 - ldh (LCDC-$FF00),a ; LCD on - delay 70224-3 - inc de - call should_not_corrupt - - set_test 3,"INC DE at first corruption" - call begin - ld de,$FE00 - ld a,$81 - ldh (LCDC-$FF00),a ; LCD on - delay 70224-2 - inc de - call should_corrupt - - set_test 4,"INC DE at last corruption" - call begin - ld de,$FE00 - ld a,$81 - ldh (LCDC-$FF00),a ; LCD on - delay 70224-2+18 - inc de - call should_corrupt - - set_test 5,"INC DE just after last corruption" - call begin - ld de,$FE00 - ld a,$81 - ldh (LCDC-$FF00),a ; LCD on - delay 70224-2+19 - inc de - call should_not_corrupt - - jp tests_passed - -begin: - call disable_lcd - call fill_oam - ret - -should_not_corrupt: - call disable_lcd - call cp_oam - jp nz,test_failed - ret - -should_corrupt: - call disable_lcd - call cp_oam - jp z,test_failed - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/5-timing_bug.s b/playing-coffee - Copy/roms/oam_bug/source/5-timing_bug.s deleted file mode 100644 index cdaa10a..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/5-timing_bug.s +++ /dev/null @@ -1,43 +0,0 @@ -; Verifies corruption at timing edges: -; * Beginning of first scanline, and 18 cycles later -; * Beginning of second scanline -; * End of last scanline - -.include "oam_bug.inc" - -main: - set_test 2,"Should corrupt at beginning of first scanline" - call begin - call end - - set_test 3,"Should corrupt at +18 of first scanline" - call begin - delay 18 - call end - - set_test 4,"Should corrupt at beginning of second scanline" - call begin - delay 114 - call end - - set_test 5,"Should corrupt at +18 of last scanline" - call begin - delay 114*143+18 - call end - - jp tests_passed - -begin: - call disable_lcd - call fill_oam - wreg LCDC,$81 - delay 70224 - 15 - ret - -end: - ld de,$FE00 - inc de - call disable_lcd - call cp_oam - jp z,test_failed - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/6-timing_no_bug.s b/playing-coffee - Copy/roms/oam_bug/source/6-timing_no_bug.s deleted file mode 100644 index 12979cf..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/6-timing_no_bug.s +++ /dev/null @@ -1,57 +0,0 @@ -; Verifies no corruption when done at "safe" times - -.include "oam_bug.inc" - -main: - call disable_lcd - call fill_oam - - call test - - call disable_lcd - call cp_oam - - call print_oam - check_crc $7BB4F198 - jp tests_passed - -test: - ld de,$FE00 - wreg LCDC,$81 - - ; Have first INC DE at scanline 0 beginning - delay 70224 - 7 - - ; Run for several frames - ld h,10 -@loop: - - ; Try to trigger just before and just after - ; window where corruption occurs, for every - ; scanline - ld b,144 -- inc de - delay 18 - dec de - delay 114-22-4 - dec b - jr nz,- - - ; Try to trigger constantly during vblank - ld b,10 - jr + --- delay 13 -+ ld c,12 -- inc de - dec c - dec de - jr nz,- - dec b - jr nz,-- - - delay 4 - - dec h - jr nz,@loop - - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/7-timing_effect.s b/playing-coffee - Copy/roms/oam_bug/source/7-timing_effect.s deleted file mode 100644 index 2bc307b..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/7-timing_effect.s +++ /dev/null @@ -1,38 +0,0 @@ -; Verifies corruption for each timing - -.include "oam_bug.inc" - -main: - loop_n_times test,116 - check_crc $7D792E7C - jp tests_passed - -test: - inc a - ld b,a - push bc - call disable_lcd - call fill_oam - call corrupt_oam - call disable_lcd - call cp_oam - pop bc - - jr z,+ - call print_b - call print_newline - call print_oam - call print_newline - -+ ret - -corrupt_oam: - wreg LCDC,$81 - ld a,b - call delay_a_20_cycles - delay 86 - - ld de,$FE00 - inc de - - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/8-instr_effect.s b/playing-coffee - Copy/roms/oam_bug/source/8-instr_effect.s deleted file mode 100644 index 3d50112..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/8-instr_effect.s +++ /dev/null @@ -1,63 +0,0 @@ -; Verifies corruption pattern for each instruction - -.include "oam_bug.inc" - -main: - save_sp - - set_test 2,"INC/DEC rp pattern is wrong" - call begin - ld de,$FE00 - inc de - call end - - ld de,$FE00 - dec de - call end - check_crc $EF0C266A - - set_test 3,"POP rp pattern is wrong" - call begin - ld sp,$FEF0 - pop bc - restore_sp - call end - check_crc $8C62EE7D - - set_test 4,"PUSH rp pattern is wrong" - call begin - ld sp,$FEF0 - push bc - restore_sp - call end - check_crc $B3693CEE - - set_test 5,"LD A,(HL+/-) pattern is wrong" - call begin - ld hl,$FEF0 - ld a,(hl+) - call end - - ld hl,$FEF0 - ld a,(hl-) - call end - check_crc $06BE41A4 - - jp tests_passed - -begin: - call disable_lcd - call fill_oam - wreg LCDC,$81 - delay 70224 - 4 - ret - -end: - call disable_lcd - call cp_oam - jr z,+ - call print_oam - call print_newline -+ - call begin - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/build_gbs.s b/playing-coffee - Copy/roms/oam_bug/source/common/build_gbs.s deleted file mode 100644 index 877754f..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/build_gbs.s +++ /dev/null @@ -1,139 +0,0 @@ -; Build as GBS music file - -.memoryMap - defaultSlot 0 - slot 0 $2000 size $2000 - slot 1 $C000 size $2000 -.endMe - -.romBankSize $2000 -.romBanks 2 - -.define RST_OFFSET $70 - -.ifndef GBS_TMA - .define GBS_TMA 0 -.endif - -.ifndef GBS_TAC - .define GBS_TAC 0 -.endif - -;;;; GBS music file header - -.ifndef CUSTOM_HEADER - .byte "GBS" - .byte 1,1,1 ; vers, song count, first song - .word load_addr, reset, gbs_play_, std_stack - .byte GBS_TMA,GBS_TAC ; timer -.endif - .org $10 - .ds $60,0 -load_addr: - .org RST_OFFSET+$70 ; space for RST vectors - .ds $148-RST_OFFSET-$70,0 - .org $150 ; wla insists on generating GB header - -gbs_play_: - jp gbs_play ; GBS spec disallows having gbs_play in RAM - -;;;; Shell - -.include "shell.s" - -.define gbs_idle nv_ram -.redefine nv_ram nv_ram+2 - -init_runtime: - ; Identify as DMG hardware - ld a,$01 - ld (gb_id),a - - ; Save return address - pop hl - ld a,l - ld (gbs_idle),a - ld a,h - ld (gbs_idle+1),a - - ; Delay 1/4 second to give time - ; for GBS player to interrupt with - ; play, if it's going to do so - delay_msec 250 - -.ifndef CUSTOM_PLAY -gbs_play: -.endif - ; Get return address - ld a,(gbs_idle) - ld l,a - ld a,(gbs_idle+1) - ld h,a - - ; If zero, then play interrupted init - ; call, or another play call, and we - ; can't run the program properly. - or l - jp z,internal_error - - setw gbs_idle,0 - jp hl - - -; Reports A in binary as high and low tones, with -; leading low tone for reference. Omits leading -; zeroes. -; Preserved: AF, BC, DE, HL -play_byte: - push af - push hl - - ; HL = (A << 1) | 1 - scf - rla - ld l,a - ld h,0 - rl h - - ; Shift left until next-to-top bit is 1 -- add hl,hl - bit 6,h - jr z,- - - ; Reset sound - delay_msec 400 - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - -- add hl,hl - - ; Low or high pitch based on bit shifted out - ; of HL - ld a,0 - jr nc,+ - ld a,$FF -+ sta NR23 - - ; Play short tone - wreg NR21,$A0 - wreg NR22,$F0 - wreg NR24,$86 - delay_msec 75 - wreg NR22,0 - wreg NR23,$F8 - wreg NR24,$87 - delay_msec 200 - - ; Loop until HL = $8000 - ld a,h - xor $80 - or l - jr nz,- - - pop hl - pop af - ret - -.ends diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/build_rom.s b/playing-coffee - Copy/roms/oam_bug/source/common/build_rom.s deleted file mode 100644 index c1595b7..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/build_rom.s +++ /dev/null @@ -1,70 +0,0 @@ -; Build as GB ROM - -.memoryMap - defaultSlot 0 - slot 0 $0000 size $4000 - slot 1 $C000 size $4000 -.endMe - -.romBankSize $4000 -.romBanks 2 - -.cartridgeType 3 ; MBC1+RAM+battery -.ramsize 02 ; 8K -.computeChecksum -.computeComplementCheck - -;;;; GB ROM header - - ; Reserve space for RST handlers - .org $70 - - ; Keep unused space filled, otherwise - ; wla moves code here - .ds $90,0 - - ; GB header read by bootrom - .org $100 - nop - jp reset - - ; Nintendo logo required for proper boot - .byte $CE,$ED,$66,$66,$CC,$0D,$00,$0B - .byte $03,$73,$00,$83,$00,$0C,$00,$0D - .byte $00,$08,$11,$1F,$88,$89,$00,$0E - .byte $DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 - .byte $BB,$BB,$67,$63,$6E,$0E,$EC,$CC - .byte $DD,$DC,$99,$9F,$BB,$B9,$33,$3E - - ; Internal name - .ifdef ROM_NAME - .byte ROM_NAME - .endif - - ; CGB/DMG requirements - .org $143 - .ifdef REQUIRE_CGB - .byte $C0 - .else - .ifndef REQUIRE_DMG - .byte $80 - .endif - .endif - - ; Keep unused space filled, otherwise - ; wla moves code here - .org $150 - .ds $2150-$150,0 - -;;;; Shell - -.define NEED_CONSOLE 1 -.include "shell.s" - -init_runtime: - ret - -play_byte: - ret - -.ends diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/console.bin b/playing-coffee - Copy/roms/oam_bug/source/common/console.bin deleted file mode 100644 index b02f2d3..0000000 Binary files a/playing-coffee - Copy/roms/oam_bug/source/common/console.bin and /dev/null differ diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/console.s b/playing-coffee - Copy/roms/oam_bug/source/common/console.s deleted file mode 100644 index 403fa5c..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/console.s +++ /dev/null @@ -1,285 +0,0 @@ -; Scrolling text console - -; Console is 20x18 characters. Buffers lines, so -; output doesn't appear until a newline or flush. -; If scrolling isn't supported (i.e. SCY is treated -; as if always zero), the first 18 lines will -; still print properly). Also works properly if -; LY isn't supported (always reads back as the same -; value). - -.define console_width 20 - -.define console_buf bss+0 -.define console_pos bss+console_width -.define console_mode bss+console_width+1 -.define console_scroll bss+console_width+2 -.redefine bss bss+console_width+3 - - -; Waits for start of LCD blanking period -; Preserved: BC, DE, HL -console_wait_vbl: - push bc - - ; Wait for start of vblank, with - ; timeout in case LY doesn't work - ; or LCD is disabled. - ld bc,-1250 -- inc bc - ld a,b - or c - jr z,@timeout - lda LY - cp 144 - jr nz,- -@timeout: - - pop bc - ret - - -; Initializes text console -console_init: - call console_hide - - ; CGB-specific inits - ld a,(gb_id) - and gb_id_cgb - call nz,@init_cgb - - ; Clear nametable - ld a,' ' - call @fill_nametable - - ; Load tiles - ld hl,TILES+$200 - ld c,0 - call @load_tiles - ld hl,TILES+$A00 - ld c,$FF - call @load_tiles - - ; Init state - setb console_pos,console_width - setb console_mode,0 - setb console_scroll,-8 - call console_scroll_up_ - jr console_show - -@fill_nametable: - ld hl,BGMAP0 - ld b,4 -- ld (hl),a - inc l - jr nz,- - inc h - dec b - jr nz,- - ret - -@init_cgb: - ; Clear palette - wreg $FF68,$80 - ld b,16 -- wreg $FF69,$FF - wreg $FF69,$7F - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - wreg $FF69,$00 - dec b - jr nz,- - - ; Clear attributes - wreg VBK,1 - ld a,0 - call @fill_nametable - - wreg VBK,0 - ret - -@load_tiles: - ld de,ASCII - ld b,96 --- push bc - ld b,8 -- ld a,(de) - inc de - xor c - ldi (hl),a - ldi (hl),a - dec b - jr nz,- - pop bc - dec b - jr nz,-- - ret - - -; Shows console display -; Preserved: AF, BC, DE, HL -console_show: - push af - - ; Enable LCD - call console_wait_vbl - wreg LCDC,$91 - wreg SCX,0 - wreg BGP,$E4 - - jp console_apply_scroll_ - - -; Hides console display by turning LCD off -; Preserved: AF, BC, DE, HL -console_hide: - push af - - ; LCD off - call console_wait_vbl - wreg LCDC,$11 - - pop af - ret - - -; Changes to normal text mode -; Preserved: BC, DE, HL -console_normal: - xor a - jr console_set_mode - -; Changes to inverse text mode -; Preserved: BC, DE, HL -console_inverse: - ld a,$80 - -; Changes console mode to A. -; 0: Normal, $80: Inverse -; Preserved: BC, DE, HL -console_set_mode: - and $80 - ld (console_mode),a - ret - - -; Prints char A to console. Will not appear until -; a newline or flush occurs. -; Preserved: AF, BC, DE, HL -console_print: - push af - - cp 10 - jr z,console_newline_ - - push hl - push af - ld hl,console_pos - ldi a,(hl) - cp BGMAP0) >> 2 - add hl,hl - add hl,hl - - ; Copy line - ld de,console_buf + console_width -- dec e - ld a,(de) - ldi (hl),a - ld a,e - cp checksum - ldi (hl),a - ld (hl),d - inc l - ld (hl),c - inc l - ld (hl),b - - pop hl - pop de - pop bc - pop af - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/delay.s b/playing-coffee - Copy/roms/oam_bug/source/common/delay.s deleted file mode 100644 index cbcdcf3..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/delay.s +++ /dev/null @@ -1,220 +0,0 @@ -; Delays in cycles, milliseconds, etc. - -; All routines are re-entrant (no global data). Routines never -; touch BC, DE, or HL registers. These ASSUME CPU is at normal -; speed. If running at double speed, msec/usec delays are half advertised. - -; Delays n cycles, from 0 to 16777215 -; Preserved: AF, BC, DE, HL -.macro delay ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 16777215 - .printt "Delay must be < 16777216" - .fail - .endif - delay_ n&$FFFF, n>>16 -.endm - -; Delays n clocks, from 0 to 16777216*4. Must be multiple of 4. -; Preserved: AF, BC, DE, HL -.macro delay_clocks ARGS n - .if n # 4 != 0 - .printt "Delay must be a multiple of 4" - .fail - .endif - delay_ (n/4)&$FFFF,(n/4)>>16 -.endm - -; Delays n microseconds (1/1000000 second) -; n can range from 0 to 4000 usec. -; Preserved: AF, BC, DE, HL -.macro delay_usec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 4000 - .printt "Delay must be <= 4000 usec" - .fail - .endif - delay_ ((n * 1048576 + 500000) / 1000000)&$FFFF,((n * 1048576 + 500000) / 1000000)>>16 -.endm - -; Delays n milliseconds (1/1000 second) -; n can range from 0 to 10000 msec. -; Preserved: AF, BC, DE, HL -.macro delay_msec ARGS n - .if n < 0 - .printt "Delay must be >= 0" - .fail - .endif - .if n > 10000 - .printt "Delay must be <= 10000 msec" - .fail - .endif - delay_ ((n * 1048576 + 500) / 1000)&$FFFF, ((n * 1048576 + 500) / 1000)>>16 -.endm - - ; All the low/high quantities are to deal wla-dx's asinine - ; restriction full expressions must evaluate to a 16-bit - ; value. If the author ever rectifies this, all "high" - ; arguments can be treated as zero and removed. Better yet, - ; I'll just find an assembler that didn't crawl out of - ; the sewer (this is one of too many bugs I've wasted - ; hours working around). - - .define max_short_delay 28 - - .macro delay_long_ ARGS n, high - ; 0+ to avoid assembler treating as memory read - ld a,0+(((high<<16)+n) - 11) >> 16 - call delay_65536a_9_cycles_ - delay_nosave_ (((high<<16)+n) - 11)&$FFFF, 0 -.endm - - ; Doesn't save AF, allowing minimization of AF save/restore - .macro delay_nosave_ ARGS n, high - ; 65536+11 = maximum delay using delay_256a_9_cycles_ - ; 255+22 = maximum delay using delay_a_20_cycles - ; 22 = minimum delay using delay_a_20_cycles - .if high > 1 - delay_long_ n, high - .else - .if high*n > 11 - delay_long_ n, high - .else - .if (high*(255+22+1))|n > 255+22 - ld a,>(((high<<16)+n) - 11) - call delay_256a_9_cycles_ - delay_nosave_ <(((high<<16)+n) - 11), 0 - .else - .if n >= 22 - ld a,n - 22 - call delay_a_20_cycles - .else - delay_short_ n - .endif - .endif - .endif - .endif -.endm - - .macro delay_ ARGS low, high - .if (high*(max_short_delay+1))|low > max_short_delay - push af - delay_nosave_ ((high<<16)+low - 7)&$FFFF, ((high<<16)+low - 7)>>16 - pop af - .else - delay_short_ low - .endif -.endm - - -; Delays A cycles + overhead -; Preserved: BC, DE, HL -; Time: A+20 cycles (including CALL) -delay_a_20_cycles: -- sub 5 ; 2 - jr nc,- ;3/2 do multiples of 5 - rra ; 1 - jr nc,+ ;3/2 bit 0 -+ adc 1 ; 2 - ret nc ;5/2 -1: 0 cycles - ret z ;5/2 0: 2 cycles - nop ; 1 1: 4 cycles - ret ; 4 (thanks to dclxvi for original algorithm) - -; Delays A*256 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*256+12 cycles (including CALL) -delay_256a_12_cycles: - or a ; 1 - ret z ; 5/2 -delay_256a_9_cycles_: -- delay 256-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays A*65536 cycles + overhead -; Preserved: BC, DE, HL -; Time: A*65536+12 cycles (including CALL) -delay_65536a_12_cycles: - or a ; 1 - ret z ;5/2 -delay_65536a_9_cycles_: -- delay 65536-4 - dec a ; 1 - jr nz,- ;3/2 - ret ; 4 - -; Delays H*256+L cycles + overhead -; Preserved: AF, BC, DE, HL -; Time: H*256+L+51 cycles -delay_hl_51_cycles: - push af - ld a,h - call delay_256a_12_cycles - ld a,l - call delay_a_20_cycles - pop af - ret - - ; delay_short_ macro calls into these - .ds max_short_delay-10,$00 ; NOP repeated several times -delay_unrolled_: - ret - -.macro delay_short_ ARGS n - .if n < 0 - .fail - .endif - .if n > max_short_delay - .fail - .endif - - .if n == 1 - nop - .endif - .if n == 2 - nop - nop - .endif - .if n == 3 - .byte $18,$00 ; JR +0 - .endif - .if n == 4 - .byte $18,$00 ; JR +0 - nop - .endif - .if n == 5 - .byte $18,$00 ; JR +0 - nop - nop - .endif - .if n == 6 - .byte $18,$00 ; JR +0 - .byte $18,$00 ; JR +0 - .endif - .if n == 7 - push af - pop af - .endif - .if n == 8 - push af - pop af - nop - .endif - .if n == 9 - push af - pop af - nop - nop - .endif - .if n >= 10 - call delay_unrolled_ + 10 - n - .endif -.endm diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/gb.inc b/playing-coffee - Copy/roms/oam_bug/source/common/gb.inc deleted file mode 100644 index 2d0118d..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/gb.inc +++ /dev/null @@ -1,81 +0,0 @@ -; Game Boy hardware addresses - -; $0000-$3FFF Fixed ROM bank -; $4000-$7FFF Switchable bank -; $8000-$9FFF VRAM -; $A000-$BFFF optional cartridge RAM -; $C000-$DFFF RAM -; $E000-$FDFF RAM mirror -; $FE00-$FE9F OAM -; $FEA0-$FEFF unused -; $FF00-$FF7F registers -; $FF80-$FFFE RAM -; $FFFF register - -; Memory -.define VRAM $8000 ; video memory -.define TILES $8000 ; tile images -.define BGMAP0 $9800 ; first 32x32 tilemap -.define BGMAP1 $9C00 ; second 32x32 tilemap -.define BRAM $A000 ; cart memory -.define WRAM $C000 ; internal memory -.define OAM $FE00 ; sprite memory -.define HRAM $FF80 ; fast memory for LDH - -; Registers - -.define RAMEN $0000 ; cartridge WRAM control -.define BANK $2000 ; bank select -.define P1 $FF00 ; controller - -; Game link I/O -.define SB $FF01 ; serial buffer -.define SC $FF02 ; serial control - -; Interrupts -.define DIV $FF04 -.define TIMA $FF05 -.define TMA $FF06 -.define TAC $FF07 -.define IF $FF0F -.define IE $FFFF - -; LCD registers -.define LCDC $FF40 ; control -.define STAT $FF41 ; status -.define SCY $FF42 ; scroll Y -.define SCX $FF43 ; scroll X -.define LY $FF44 ; current Y being rendered -.define BGP $FF47 - -.define KEY1 $FF4D ; for changing CPU speed -.define VBK $FF4F - -; Sound registers -.define NR10 $FF10 -.define NR11 $FF11 -.define NR12 $FF12 -.define NR13 $FF13 -.define NR14 $FF14 - -.define NR21 $FF16 -.define NR22 $FF17 -.define NR23 $FF18 -.define NR24 $FF19 - -.define NR30 $FF1A -.define NR31 $FF1B -.define NR32 $FF1C -.define NR33 $FF1D -.define NR34 $FF1E - -.define NR41 $FF20 -.define NR42 $FF21 -.define NR43 $FF22 -.define NR44 $FF23 - -.define NR50 $FF24 -.define NR51 $FF25 -.define NR52 $FF26 - -.define WAVE $FF30 diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/macros.inc b/playing-coffee - Copy/roms/oam_bug/source/common/macros.inc deleted file mode 100644 index 9d7cf44..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/macros.inc +++ /dev/null @@ -1,91 +0,0 @@ -; General macros - -; Reads A from addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 3 cycles -.macro lda ; addr - ldh a,(\1 - $FF00) -.endm - -; Writes A to addr, from $FF00 to $FFFF -; Preserved: AF, BC, DE, HL -; Time: 3 cycles -.macro sta ; addr - ldh (\1 - $FF00),a -.endm - -; Writes immediate data to addr, from $FF00 to $FFFF -; Preserved: F, BC, DE, HL -; Time: 5 cycles -.macro wreg ARGS addr, data - ld a,data - sta addr -.endm - -; Writes byte to addr -; Preserved: F, BC, DE, HL -; Time: 6 cycles -.macro setb ; addr, data - ld a,\2 - ld (\1),a -.endm - -; Writes word to addr -; Preserved: F, BC, DE, HL -; Time: 12 cycles -.macro setw ; addr, data - ld a,<\2 - ld (\1),a - ld a,>\2 - ld (\1+1),a -.endm - -; Calls routine multiple times, with A having the -; value 'start' the first time, 'start+step' the -; second time, up to 'end' for the last time. -; Preserved: BC, DE, HL -.macro for_loop ; routine,start,end,step - ld a,\2 - -for_loop\@: - push af - call \1 - pop af - - add \4 - cp <(\3 + \4) - jr nz,for_loop\@ -.endm - -; Calls routine n times. The value of A in the routine -; counts from 0 to n-1. -; Preserved: BC, DE, HL -.macro loop_n_times ; routine,n - for_loop \1,0,\2 - 1,+1 -.endm - -; Same as for_loop, but counts with 16-bit value in BC. -; Preserved: DE, HL -.macro for_loop16 ; routine,start,end,step - ld bc,\2 - -for_loop16\@: - push bc - call \1 - pop bc - - ld a,c - add <\4 - ld c,a - - ld a,b - adc >\4 - ld b,a - - cp >(\3+\4) - jr nz,for_loop16\@ - - ld a,c - cp <(\3+\4) - jr nz,for_loop16\@ -.endm diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/numbers.s b/playing-coffee - Copy/roms/oam_bug/source/common/numbers.s deleted file mode 100644 index 6d6faf8..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/numbers.s +++ /dev/null @@ -1,177 +0,0 @@ -; Printing of numeric values - -; Prints value of indicated register/pair -; as 2/4 hex digits, followed by a space. -; Updates checksum with printed values. -; Preserved: AF, BC, DE, HL - -print_regs: - call print_af - call print_bc - call print_de - call print_hl - call print_newline - ret - -print_a: - push af -print_a_: - call print_hex - ld a,' ' - call print_char_nocrc - pop af - ret - -print_af: - push af - call print_hex - pop af -print_f: - push bc - push af - pop bc - call print_c - pop bc - ret - -print_b: - push af - ld a,b - jr print_a_ - -print_c: - push af - ld a,c - jr print_a_ - -print_d: - push af - ld a,d - jr print_a_ - -print_e: - push af - ld a,e - jr print_a_ - -print_h: - push af - ld a,h - jr print_a_ - -print_l: - push af - ld a,l - jr print_a_ - -print_bc: - push af - push bc -print_bc_: - ld a,b - call print_hex - ld a,c - pop bc - jr print_a_ - -print_de: - push af - push bc - ld b,d - ld c,e - jr print_bc_ - -print_hl: - push af - push bc - ld b,h - ld c,l - jr print_bc_ - - -; Prints A as two hex chars and updates checksum -; Preserved: BC, DE, HL -print_hex: - call update_crc -print_hex_nocrc: - push af - swap a - call + - pop af - -+ and $0F - cp 10 - jr c,+ - add 7 -+ add '0' - jp print_char_nocrc - - -; Prints char_nz if Z flag is clear, -; char_z if Z flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nz ARGS char_nz, char_z - push af - ld a,char_nz - jr nz,print_nz\@ - ld a,char_z -print_nz\@: - call print_char - pop af -.endm - - -; Prints char_nc if C flag is clear, -; char_c if C flag is set. -; Preserved: AF, BC, DE, HL -.macro print_nc ARGS char_nc, char_c - push af - ld a,char_nc - jr nz,print_nc\@ - ld a,char_c -print_nc\@: - call print_char - pop af -.endm - - -; Prints A as 2 decimal digits -; Preserved: AF, BC, DE, HL -print_dec2: - push af - push bc - jr + - - -; Prints A as 1-3 digit decimal value -; Preserved: AF, BC, DE, HL -print_dec: - push af - push bc - - cp 10 - jr c,++ - ld c,100 - cp c - call nc,@digit -+ ld c,10 - call @digit -++ add '0' - call print_char - - pop bc - pop af - ret - -@digit: - ld b,'0'-1 -- inc b - sub c - jr nc,- - add c - - ld c,a - ld a,b - call print_char - ld a,c - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/ppu.s b/playing-coffee - Copy/roms/oam_bug/source/common/ppu.s deleted file mode 100644 index e1d2a6a..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/ppu.s +++ /dev/null @@ -1,14 +0,0 @@ -; Waits for LCD blanking period -; Preserved: BC, DE, HL -wait_vbl: - ; Return if off - lda LCDC - rla - ret nc - - ; Wait for start of vblank -- lda LY - cp 144 - jr nz,- - - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/printing.s b/playing-coffee - Copy/roms/oam_bug/source/common/printing.s deleted file mode 100644 index bb9389b..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/printing.s +++ /dev/null @@ -1,77 +0,0 @@ -; Main printing routine that checksums and -; prints to output device - -; Character that does equivalent of print_newline -.define newline 10 - -; Prints char without updating checksum -; Preserved: BC, DE, HL -;print_char_nocrc (defined by user) - - -; Prints character and updates checksum UNLESS -; it's a newline. -; Preserved: AF, BC, DE, HL -print_char: - push af - cp newline - call nz,update_crc - call print_char_nocrc - pop af - ret - - -; Prints space. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_space: - push af - ld a,' ' - call print_char_nocrc - pop af - ret - - -; Advances to next line. Does NOT update checksum. -; Preserved: AF, BC, DE, HL -print_newline: - push af - ld a,newline - call print_char_nocrc - pop af - ret - - -; Prints immediate string -; Preserved: AF, BC, DE, HL -.macro print_str ; string,string2 - push hl - call print_str_ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .byte 0 - pop hl -.endm - -print_str_: - pop hl - call print_str_hl - jp hl - - -; Prints zero-terminated string pointed to by HL. -; On return, HL points to byte AFTER zero terminator. -; Preserved: AF, BC, DE -print_str_hl: - push af - jr + -- call print_char -+ ldi a,(hl) - or a - jr nz,- - pop af - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/shell.s b/playing-coffee - Copy/roms/oam_bug/source/common/shell.s deleted file mode 100644 index 3e588c7..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/shell.s +++ /dev/null @@ -1,261 +0,0 @@ -; Common routines and runtime - -.define RUNTIME_INCLUDED 1 - -; A few bytes of RAM that aren't cleared -.define nv_ram_base $D800 -.define nv_ram nv_ram_base - -; Address of next normal variable -.define bss_base nv_ram_base+$80 -.define bss bss_base - -; Address of next direct-page ($FFxx) variable -.define dp_base $FF80 -.define dp dp_base - -; Top of stack -.define std_stack $DFFF+1 - -; Final exit result byte is written here -.define final_result $A000 - -; Text output is written here as zero-terminated string -.define text_out_base $A004 - -; DMG/CGB hardware identifier -.define gb_id_cgb $10 ; mask for testing CGB bit -.define gb_id_devcart $04 ; mask for testing "on devcart" bit -.define gb_id nv_ram -.redefine nv_ram nv_ram+1 - -; Copies C*$100 bytes from HL to $C000, then jumps to it. -; A is preserved for jumped-to code. -copy_to_wram_then_run: - ld b,a - - ld de,$C000 -- ld a,(hl+) - ld (de),a - inc e - jr nz,- - inc d - dec c - jr nz,- - - ld a,b - jp $C000 - - -.ifndef RST_OFFSET - .define RST_OFFSET 0 -.endif - -.ifndef CUSTOM_RESET - reset: - di - - ; Run code from $C000, as is done on devcart. This - ; ensures minimal difference in how it behaves. - ld hl,$4000 - ld c,$14 - jp copy_to_wram_then_run - - .bank 1 slot 1 - .org 0 - jp std_reset -.endif - -; returnOrg puts this code AFTER user code. -.section "runtime" returnOrg - - ; Catch user code running off end - jp internal_error - -; Common routines -.include "gb.inc" -.include "macros.inc" -.include "delay.s" -.include "crc.s" -.include "printing.s" -.include "numbers.s" -.include "testing.s" - -; Sets up hardware and runs main -std_reset: - - ; Init hardware - di - ld sp,std_stack - - ; Save DMG/CGB id - ld (gb_id),a - - ; Clear memory except very top of stack - ld bc,std_stack-bss_base - 2 - ld hl,bss_base - call clear_mem - ld bc,$FFFF-dp_base - ld hl,dp_base - call clear_mem - - ; Init hardware - wreg TAC,$00 - wreg IF,$00 - wreg IE,$00 - - wreg NR52,0 ; sound off - wreg NR52,$80 ; sound on - wreg NR51,$FF ; mono - wreg NR50,$77 ; volume - - call init_runtime - call init_text_out - call console_init - call init_testing - - .ifdef TEST_NAME - print_str TEST_NAME,newline,newline - .endif - - call reset_crc ; in case init_runtime prints anything - - delay_msec 250 - - ; Run user code - call main - - ; Default is to successful exit - ld a,0 - jp exit - - -; Exits code and reports value of A -exit: - ld sp,std_stack - push af - call + - call console_show - pop af - call play_byte - jp post_exit - -+ push af - call print_newline - pop af - - ; Report exit status - cp 1 - - ; 0: "" - ret c - - ; 1: "Failed" - jr nz,+ - print_str "Failed",newline - ret - - ; n: "Failed #n" -+ print_str "Failed #" - call print_dec - call print_newline - ret - - -; Clears BC bytes starting at HL -clear_mem: - ; If C>0, increment B - dec bc - inc c - inc b - - ld a,0 -- ld (hl+),a - dec c - jr nz,- - dec b - jr nz,- - ret - - -; Reports internal error and exits with code 255 -internal_error: - print_str "Internal error" - ld a,255 - jp exit - - -; build_devcart and build_multi customize this -.ifndef CUSTOM_PRINT - .define text_out_addr bss+0 - .redefine bss bss+2 - - ; Initializes text output to cartridge RAM - init_text_out: - ; Enable cartridge RAM and set text output pointer - setb RAMEN,$0A - setw text_out_addr,text_out_base - setb text_out_base-3,$DE - setb text_out_base-2,$B0 - setb text_out_base-1,$61 - setb text_out_base,0 - setb final_result,$80 - ret - - - ; Appends character to text output string - ; Preserved: AF, BC, DE, HL - write_text_out: - push hl - push af - ld a,(text_out_addr) - ld l,a - ld a,(text_out_addr+1) - ld h,a - inc hl - ld (hl),0 - ld a,l - ld (text_out_addr),a - ld a,h - ld (text_out_addr+1),a - dec hl - pop af - ld (hl),a - pop hl - ret - - print_char_nocrc: - call write_text_out - jp console_print -.endif - - -; only build_rom uses console -.ifdef NEED_CONSOLE - .include "console.s" -.else - console_init: - console_print: - console_flush: - console_normal: - console_inverse: - console_show: - console_set_mode: - ret -.endif - - -; build_devcart and build_multi need to customize this -.ifndef CUSTOM_EXIT - post_exit: - ld (final_result),a - forever: - wreg NR52,0 ; sound off -- jr - -.endif - - -.macro def_rst ARGS addr - .bank 0 slot 0 - .org addr+RST_OFFSET -.endm diff --git a/playing-coffee - Copy/roms/oam_bug/source/common/testing.s b/playing-coffee - Copy/roms/oam_bug/source/common/testing.s deleted file mode 100644 index 5dd63ce..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/common/testing.s +++ /dev/null @@ -1,195 +0,0 @@ -; Diagnostic and testing utilities - -.define test_code bss+0 -.define test_name bss+1 -.redefine bss bss+3 - - -; Sets test code and optional error text. -; Takes multiple strings due to wla's idiotic -; default limit of 63 chars per string. -; Preserved: AF, BC, DE, HL -.macro set_test ; code[,text[,text2[,text3]]] - push hl - call set_test_ - jr @set_test\@ - .byte \1 - .if NARGS > 1 - .byte \2 - .endif - .if NARGS > 2 - .byte \3 - .endif - .if NARGS > 3 - .byte \4 - .endif - .byte 0 -@set_test\@: - pop hl -.endm - -set_test_: - pop hl - push hl - push af - inc hl - inc hl - ldi a,(hl) - ld (test_code),a - ld a,l - ld (test_name),a - ld a,h - ld (test_name+1),a - pop af - ret - - -; Initializes testing module -init_testing: - set_test $FF - call init_crc - ret - - -; Reports "Passed", then exits with code 0 -tests_passed: - call print_newline - print_str "Passed" - ld a,0 - jp exit - - -; Reports "Done" if set_test has never been used, -; "Passed" if set_test 0 was last used, or -; failure if set_test n was last used. -tests_done: - ld a,(test_code) - inc a - jr z,+ - dec a - jr z,tests_passed - jr test_failed -+ print_str "Done" - ld a,0 - jp exit - - -; Reports current error text and exits with result code -test_failed: - ld a,(test_name) - ld l,a - ld a,(test_name+1) - ld h,a - ld a,(hl) - or a - jr z,+ - call print_newline - call print_str_hl - call print_newline -+ - ld a,(test_code) - cp $FF ; if a = $FF then a = 1 - jr nz,+ - ld a,1 -+ jp exit - - -; Prints checksum as 8-character hex value -; Preserved: AF, BC, DE, HL -print_crc: - push af - - ; Must read checksum entirely before printing, - ; since printing updates it. - lda checksum - cpl - push af - - lda checksum+1 - cpl - push af - - lda checksum+2 - cpl - push af - - lda checksum+3 - cpl - - call print_hex - pop af - call print_hex - pop af - call print_hex - pop af - call print_a - - pop af - ret - - -; If checksum doesn't match expected, reports failed test. -; Passing 0 just prints checksum. Clears checksum afterwards. -.macro check_crc ARGS crc - .if crc == 0 - call print_newline - call print_crc - .else - ld bc,(crc >> 16) ~ $FFFF - ld de,(crc & $FFFF) ~ $FFFF - call check_crc_ - .endif -.endm - -; Checks CRC, differing based on DMG or CGB build -.macro check_crc_dmg_cgb ARGS dmg, cgb - .ifdef REQUIRE_DMG - check_crc dmg - .else - .ifdef REQUIRE_CGB - check_crc cgb - .else - .printt "CGB or DMG must be specified" - .fail - .endif - .endif -.endm - -check_crc_: - lda checksum+0 - cp e - jr nz,+ - - lda checksum+1 - cp d - jr nz,+ - - lda checksum+2 - cp c - jr nz,+ - - lda checksum+3 - cp b - jr nz,+ - - jp reset_crc - -+ call print_crc - jp test_failed - - -; Updates checksum with bytes from addr to addr+size-1 -.macro checksum_mem ARGS addr,size - ld hl,addr - ld bc,size - call checksum_mem_ -.endm - -checksum_mem_: -- ldi a,(hl) - call update_crc - dec bc - ld a,b - or c - jr nz,- - ret diff --git a/playing-coffee - Copy/roms/oam_bug/source/linkfile b/playing-coffee - Copy/roms/oam_bug/source/linkfile deleted file mode 100644 index 02a5a2e..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/linkfile +++ /dev/null @@ -1,2 +0,0 @@ -[objects] -test.o diff --git a/playing-coffee - Copy/roms/oam_bug/source/readme.txt b/playing-coffee - Copy/roms/oam_bug/source/readme.txt deleted file mode 100644 index a0269c1..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/readme.txt +++ /dev/null @@ -1,82 +0,0 @@ -Game Boy Tests Source Code --------------------------- - -Building with wla-dx --------------------- -To assemble a test ROM with wla-dx, use the following commands: - - wla -o source_filename_here.s test.o - wlalink linkfile test.gb - -To assemble as a GBS music file: - - wla -o source_filename_here.s test.o -DBUILD_GBS - wlalink linkfile test.gbs - -Note that some tests might only work when built as a ROM or GBS file, -but not both. - -Some tests might include a ROM/GBS that has all the tests combined. -Building such a multi-test is complex and the necessary files aren't -included. - - -Framework ---------- -Each test is in a single source file, and makes use of several library -source files from common/. This framework provides common services and -reduces code to only that which performs the actual test. Virtually all -tests include "shell.inc" at the beginning, which sets things up and -includes all the appropriate library files. - -The reset handler does minimal GB hardware initialization, clears RAM, -sets up the text console, then runs main. Main can exit by returning or -jumping to "exit" with an error code in A. Exit reports the code then -goes into an infinite loop. If the code is 0, it doesn't do anything, -otherwise it reports the code. Code 1 is reported as "Failed", and the -rest as "Error ". - -The default is to build a ROM. Defining BUILD_GBS will build as an GBS. -The other build types aren't supported due to their complexity. I load -the code into RAM at $C000 since my devcart requires it, and I don't -want the normal ROM to differ in any way from what I've tested. This -also allows easy self-modifying code. - -Several routines are available to print values and text to the console. -Most update a running CRC-32 checksum which can be checked with -check_crc, allowing ALL the output to be checked very easily. If the -checksum doesn't match, it is printed, so you can run the code on a GB -and paste the correct checksum into your code. - - -Macros ------- -Some macros are used to make common operations more convenient. The left -is equivalent to the right: - - Macro Equivalent - ------------------------------------- - lda addr ldh a,(addr-$FF00) - - sta addr ldh (addr-$FF00),a - - wreg addr,data ld a,data - ldh (addr-$FF00),a - - setb ld a,data - ld (addr),a - - setw setb addr+0,data - - for_loop routine,begin,end,step - calls routine with A set to successive values - - loop_n_times routine,count - calls routine with A from 0 to count-1 - - print_str "str" prints string - - --- -Shay Green diff --git a/playing-coffee - Copy/roms/oam_bug/source/shell.inc b/playing-coffee - Copy/roms/oam_bug/source/shell.inc deleted file mode 100644 index 0d43faa..0000000 --- a/playing-coffee - Copy/roms/oam_bug/source/shell.inc +++ /dev/null @@ -1,27 +0,0 @@ -; Included at beginning of all programs -; that use standard shell - -; Get include files from common/ -.incdir "common" - -; Sub-test in a multi-test ROM -.ifdef BUILD_MULTI - .include "build_multi.s" -.else - -; GBS music file -.ifdef BUILD_GBS - .include "build_gbs.s" -.endif - -; Devcart -.ifdef BUILD_DEVCART - .include "build_devcart.s" -.endif - -; GB ROM (default) -.ifndef RUNTIME_INCLUDED - .include "build_rom.s" -.endif - -.endif ; .ifdef BUILD_MULTI diff --git a/playing-coffee - Copy/roms/readme.txt b/playing-coffee - Copy/roms/readme.txt deleted file mode 100644 index 2c40e27..0000000 --- a/playing-coffee - Copy/roms/readme.txt +++ /dev/null @@ -1,4 +0,0 @@ -Blargg's Gameboy hardware test ROMs. Originally hosted at http://blargg.parodius.com/gb-tests/ -before parodious.com went down. -New official location: http://blargg.8bitalley.com/parodius/gb-tests/ - diff --git a/playing-coffee - Copy/roms/solitaire.gb b/playing-coffee - Copy/roms/solitaire.gb deleted file mode 100644 index 8c5b8c6..0000000 Binary files a/playing-coffee - Copy/roms/solitaire.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/supermarioland.gb b/playing-coffee - Copy/roms/supermarioland.gb deleted file mode 100644 index e5d7125..0000000 Binary files a/playing-coffee - Copy/roms/supermarioland.gb and /dev/null differ diff --git a/playing-coffee - Copy/roms/tetris.gb b/playing-coffee - Copy/roms/tetris.gb deleted file mode 100644 index fbcef42..0000000 Binary files a/playing-coffee - Copy/roms/tetris.gb and /dev/null differ diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/application/Application.java b/playing-coffee - Copy/src/main/java/playingcoffee/application/Application.java deleted file mode 100644 index 37b7ab4..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/application/Application.java +++ /dev/null @@ -1,111 +0,0 @@ -package playingcoffee.application; - -import java.awt.Canvas; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.image.BufferStrategy; - -import javax.swing.JFrame; - -public class Application extends Canvas implements Runnable { - - private static final long serialVersionUID = 1L; - - private boolean running; - private Thread thread; - - private GameBoy gameBoy; - - public Application() { - setPreferredSize(new Dimension(320, 288)); - - gameBoy = new GameBoy(); - gameBoy.start(); - } - - public void renderGameBoy() { - BufferStrategy bs = getBufferStrategy(); - if (bs == null) { - createBufferStrategy(2); - return; - } - - Graphics g = bs.getDrawGraphics(); - - g.setColor(Color.WHITE); - g.fillRect(0, 0, getWidth(), getHeight()); - - int lcdControl = (gameBoy.getMMU().read(0xFF40)); - - int tileDataOffset = ((lcdControl & 0x10) != 0) ? 0x8000 : 0x8800; - - 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); - } - } - } - } - } - - g.dispose(); - - bs.show(); - } - - @Override - public void run() { - while (running) { - renderGameBoy(); - } - - gameBoy.stop(); - } - - public void start() { - if (running) return; - - running = true; - - thread = new Thread(this); - thread.start(); - } - - public static void main(String[] args) { - Application application = new Application(); - - JFrame frame = new JFrame("playing-coffee"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setResizable(false); - frame.add(application); - frame.pack(); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - - application.start(); - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/application/GameBoy.java b/playing-coffee - Copy/src/main/java/playingcoffee/application/GameBoy.java deleted file mode 100644 index 25480f7..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/application/GameBoy.java +++ /dev/null @@ -1,85 +0,0 @@ -package playingcoffee.application; - -import playingcoffee.core.Cartridge; -import playingcoffee.core.InterruptManager; -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.CPU; -import playingcoffee.log.Log; -import playingcoffee.ppu.PPU; - -public class GameBoy implements Runnable { - - private Thread thread; - private boolean running = false; - - private InterruptManager interruptManager; - private PPU ppu; - private MMU mmu; - private CPU cpu; - - public GameBoy() { - interruptManager = new InterruptManager(); - mmu = new MMU(); - - ppu = new PPU(mmu, interruptManager); - cpu = new CPU(mmu, interruptManager); - - mmu.connectMemorySpace(interruptManager); - mmu.connectMemorySpace(new Cartridge("roms/kwirk.gb")); - } - - public void start() { - if (running) - return; - - running = true; - thread = new Thread(this); - thread.start(); - } - - public void stop() { - if (!running) - return; - - running = false; - try { - thread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - public void run() { - Log.init(); - - while (running) { - for (int i = 0; i < 8192; i++) { - ppu.clock(); - cpu.clock(); - interruptManager.clock(); - } - - try { - Thread.sleep(1); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - Log.close(); - } - - public PPU getPPU() { - return ppu; - } - - public MMU getMMU() { - return mmu; - } - - public CPU getCPU() { - return cpu; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/Cartridge.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/Cartridge.java deleted file mode 100644 index 21c9dea..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/Cartridge.java +++ /dev/null @@ -1,44 +0,0 @@ -package playingcoffee.core; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; - -import playingcoffee.log.Log; - -public class Cartridge implements MemorySpace { - - private int[] rom; - - public Cartridge(String rom) { - byte[] bin = null; - - try { - bin = Files.readAllBytes(Paths.get(rom)); - } catch (IOException e) { - e.printStackTrace(); - } - - this.rom = new int[bin.length]; - - for (int i = 0; i < bin.length; i++) { - this.rom[i] = Byte.toUnsignedInt(bin[i]); - } - } - - @Override - public int read(int address) { - return rom[address]; - } - - @Override - public void write(int value, int address) { - Log.warn("Attempting to write to ROM at address: 0x%4x.", address); - } - - @Override - public boolean inMemorySpace(int address) { - return address >= 0x0000 && address <= 0x7FFF; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/InterruptListener.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/InterruptListener.java deleted file mode 100644 index 088c107..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/InterruptListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package playingcoffee.core; - -public interface InterruptListener { - - public void interruptOccured(int type); - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/MMU.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/MMU.java deleted file mode 100644 index fecec2e..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/MMU.java +++ /dev/null @@ -1,93 +0,0 @@ -package playingcoffee.core; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -public class MMU { - - private int[] memory; - private int[] bootRom; - - private List memorySpaces; - - public MMU() { - memory = new int[0x10000]; - - memorySpaces = new ArrayList(); - - loadBootROM(); - } - - public void connectMemorySpace(MemorySpace memorySpace) { - memorySpaces.add(memorySpace); - } - - // TODO: Move the ROM into a separate file. - - public void loadROM(String rom) { - byte[] bin = null; - - try { - bin = Files.readAllBytes(Paths.get(rom)); - } catch (IOException e) { - e.printStackTrace(); - } - - for (int i = 0; i < bin.length; i++) { - memory[i] = Byte.toUnsignedInt(bin[i]); - } - } - - // TODO: Move the boot ROM to a separate file. - private void loadBootROM() { - bootRom = new int[0x100]; - - byte[] bin = null; - - try { - bin = Files.readAllBytes(Paths.get("dmg_boot.bin")); - } catch (IOException e) { - e.printStackTrace(); - } - - for (int i = 0; i < 0x100; i++) { - bootRom[i] = Byte.toUnsignedInt(bin[i]); - } - } - - public int read(int address) { - if (address == 0xFF00) return 0xF; // TODO: Remove - - if (address >= 0x00 && address <= 0xFF && read(0xFF50) == 0) - return bootRom[address]; - - for (MemorySpace memorySpace : memorySpaces) { - if (memorySpace.inMemorySpace(address)) { - return memorySpace.read(address); - } - } - - return memory[address]; - } - - public void write(int value, int address) { - if (address == 0xFF00) return; // TODO: Remove - - if (address >= 0x00 && address <= 0xFF && read(0xFF50) == 0) - bootRom[address] = value & 0xFF; - - for (MemorySpace memorySpace : memorySpaces) { - if (memorySpace.inMemorySpace(address)) { - memorySpace.write(value & 0xFF, address); - } - } - memory[address] = value & 0xFF; - } - - public int[] getMemory() { - return memory; - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/MemorySpace.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/MemorySpace.java deleted file mode 100644 index c2ce195..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/MemorySpace.java +++ /dev/null @@ -1,9 +0,0 @@ -package playingcoffee.core; - -public interface MemorySpace { - - public int read(int address); - public void write(int value, int address); - public boolean inMemorySpace(int address); - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/cpu/CPU.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/cpu/CPU.java deleted file mode 100644 index 2c25bf1..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/cpu/CPU.java +++ /dev/null @@ -1,343 +0,0 @@ -package playingcoffee.core.cpu; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; - -import playingcoffee.core.InterruptListener; -import playingcoffee.core.InterruptManager; -import playingcoffee.core.MMU; -import playingcoffee.core.opcode.ALU16Opcode; -import playingcoffee.core.opcode.ALU16Opcode.ALU16Type; -import playingcoffee.core.opcode.ALUOpcode; -import playingcoffee.core.opcode.ALUOpcode.ALUType; -import playingcoffee.core.opcode.Argument; -import playingcoffee.core.opcode.CallOpcode; -import playingcoffee.core.opcode.ComplementOpcode; -import playingcoffee.core.opcode.FlipCarryOpcode; -import playingcoffee.core.opcode.InterruptOpcode; -import playingcoffee.core.opcode.JumpOpcode; -import playingcoffee.core.opcode.JumpRelativeOpcode; -import playingcoffee.core.opcode.LoadOpcode; -import playingcoffee.core.opcode.Opcode; -import playingcoffee.core.opcode.PopOpcode; -import playingcoffee.core.opcode.PushOpcode; -import playingcoffee.core.opcode.RestartOpcode; -import playingcoffee.core.opcode.ReturnOpcode; -import playingcoffee.core.opcode.RotateAOpcode; -import playingcoffee.core.opcode.SetCarryOpcode; -import playingcoffee.core.opcode.prefixed.BitOpcode; -import playingcoffee.core.opcode.prefixed.ResetBitOpcode; -import playingcoffee.core.opcode.prefixed.RotateOpcode; -import playingcoffee.core.opcode.prefixed.SetBitOpcode; -import playingcoffee.core.opcode.prefixed.ShiftOpcode; -import playingcoffee.core.opcode.prefixed.ShiftOpcode.ShiftType; -import playingcoffee.core.opcode.prefixed.SwapOpcode; -import playingcoffee.log.Log; - -public class CPU implements InterruptListener { - - private final MMU mmu; - private final InterruptManager interruptManager; - - private Registers registers; - - private int cycles; - - Opcode[] opcodes; - Opcode[] prefixedOpcodes; - - public CPU(final MMU mmu, final InterruptManager interruptManager) { - this.mmu = mmu; - this.interruptManager = interruptManager; - - registers = new Registers(); - - opcodes = new Opcode[0x100]; - prefixedOpcodes = new Opcode[0x100]; - - loadOpcodes(); - loadPrefixedOpcodes(); - - interruptManager.addListener(this); - } - - private void loadOpcodes() { - // NOP - opcodes[0x00] = new Opcode() { - @Override - public int run(Registers registers, MMU mmu) { - return 0; - } - - @Override - public String toString() { - return "NOP"; - } - }; - - // Load Opcodes - for (Entry val : indexedList(0x01, 0x10, Argument.BC, Argument.DE, Argument.HL, Argument.SP)) { - opcodes[val.getKey()] = new LoadOpcode(Argument.D16, val.getValue()); - } - - for (Entry val : indexedList(0x02, 0x10, Argument._BC, Argument._DE, Argument._HL_INC, Argument._HL_DEC)) { - opcodes[val.getKey()] = new LoadOpcode(Argument.A, val.getValue()); - } - for (Entry val : indexedList(0x06, 0x10, Argument.B, Argument.D, Argument.H, Argument._HL)) { - opcodes[val.getKey()] = new LoadOpcode(Argument.D8, val.getValue()); - } - for (Entry val : indexedList(0x0A, 0x10, Argument._BC, Argument._DE, Argument._HL_INC, Argument._HL_DEC)) { - opcodes[val.getKey()] = new LoadOpcode(val.getValue(), Argument.A); - } - for (Entry val : indexedList(0x0E, 0x10, Argument.C, Argument.E, Argument.L, Argument.A)) { - opcodes[val.getKey()] = new LoadOpcode(Argument.D8, val.getValue()); - } - - for (Entry val : indexedList(0x40, 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - for (Entry row : indexedList(val.getKey(), 0x10, Argument.B, Argument.D, Argument.H, Argument._HL)) { - opcodes[row.getKey()] = new LoadOpcode(val.getValue(), row.getValue()); - } - } - for (Entry val : indexedList(0x48, 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - for (Entry row : indexedList(val.getKey(), 0x10, Argument.C, Argument.E, Argument.L, Argument.A)) { - opcodes[row.getKey()] = new LoadOpcode(val.getValue(), row.getValue()); - } - } - - opcodes[0x08] = new LoadOpcode(Argument.SP, Argument._D16_SHORT); - - opcodes[0xE0] = new LoadOpcode(Argument.A, Argument._D8); - opcodes[0xF0] = new LoadOpcode(Argument._D8, Argument.A); - - opcodes[0xE2] = new LoadOpcode(Argument.A, Argument._C); - opcodes[0xF2] = new LoadOpcode(Argument._C, Argument.A); - - opcodes[0xF9] = new LoadOpcode(Argument.HL, Argument.SP); - - opcodes[0xEA] = new LoadOpcode(Argument.A, Argument._D16); - opcodes[0xFA] = new LoadOpcode(Argument._D16, Argument.A); - - // POP and PUSH - for (Entry val : indexedList(0xC1, 0x10, Argument.BC, Argument.DE, Argument.HL, Argument.AF)) { - opcodes[val.getKey()] = new PopOpcode(val.getValue()); - } - for (Entry val : indexedList(0xC5, 0x10, Argument.BC, Argument.DE, Argument.HL, Argument.AF)) { - opcodes[val.getKey()] = new PushOpcode(val.getValue()); - } - - // TODO: Override 0x76 with HALT - - // Jumps, Calls and Returns - opcodes[0x20] = new JumpRelativeOpcode(Flags.ZERO, Argument.I8, true); - opcodes[0x30] = new JumpRelativeOpcode(Flags.CARRY, Argument.I8, true); - - opcodes[0x18] = new JumpRelativeOpcode(0, Argument.I8, false); - opcodes[0x28] = new JumpRelativeOpcode(Flags.ZERO, Argument.I8, false); - opcodes[0x38] = new JumpRelativeOpcode(Flags.CARRY, Argument.I8, false); - - opcodes[0xC3] = new JumpOpcode(0, Argument.D16, false); - opcodes[0xC2] = new JumpOpcode(Flags.ZERO, Argument.D16, true); - opcodes[0xD2] = new JumpOpcode(Flags.CARRY, Argument.D16, true); - - opcodes[0xE9] = new JumpOpcode(0, Argument.HL, false); - - opcodes[0xCA] = new JumpOpcode(Flags.ZERO, Argument.D16, false); - opcodes[0xDA] = new JumpOpcode(Flags.CARRY, Argument.D16, false); - - opcodes[0xC4] = new CallOpcode(Flags.ZERO, Argument.D16, true); - opcodes[0xD4] = new CallOpcode(Flags.CARRY, Argument.D16, true); - - opcodes[0xCC] = new CallOpcode(Flags.ZERO, Argument.D16, false); - opcodes[0xDC] = new CallOpcode(Flags.CARRY, Argument.D16, false); - - opcodes[0xCD] = new CallOpcode(0, Argument.D16, false); - - opcodes[0xC0] = new ReturnOpcode(Flags.ZERO, true, false, interruptManager); - opcodes[0xD0] = new ReturnOpcode(Flags.CARRY, true, false, interruptManager); - - opcodes[0xC8] = new ReturnOpcode(Flags.ZERO, false, false, interruptManager); - opcodes[0xD8] = new ReturnOpcode(Flags.CARRY, false, false, interruptManager); - - opcodes[0xC9] = new ReturnOpcode(0, false, false, interruptManager); - opcodes[0xD9] = new ReturnOpcode(0, false, true, interruptManager); - - // Bit Operations - - opcodes[0x07] = new RotateAOpcode(true, RotateAOpcode.LEFT); - opcodes[0x17] = new RotateAOpcode(false, RotateAOpcode.LEFT); - opcodes[0x0F] = new RotateAOpcode(true, RotateAOpcode.RIGHT); - opcodes[0x1F] = new RotateAOpcode(false, RotateAOpcode.RIGHT); - - // 16-bit ALU Opcodes - for (Entry val : indexedList(0x03, 0x10, Argument.BC, Argument.DE,Argument.HL, Argument.SP)) { - opcodes[val.getKey()] = new ALU16Opcode(ALU16Type.INC, val.getValue()); - opcodes[val.getKey() + 8] = new ALU16Opcode(ALU16Type.DEC, val.getValue()); - } - for (Entry val : indexedList(0x09, 0x10, Argument.BC, Argument.DE,Argument.HL, Argument.SP)) { - opcodes[val.getKey()] = new ALU16Opcode(ALU16Type.ADD, val.getValue()); - } - - // ALU Opcodes - for (Entry val : indexedList(0x04, 8, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - opcodes[val.getKey()] = new ALUOpcode(ALUType.INC, val.getValue()); - opcodes[val.getKey() + 1] = new ALUOpcode(ALUType.DEC, val.getValue()); - } - - for (Entry val : indexedList(0x80, 8, ALUType.ADD, ALUType.ADC, ALUType.SUB, ALUType.SBC, ALUType.AND, ALUType.XOR, ALUType.OR, ALUType.CP)) { - for (Entry row : indexedList(val.getKey(), 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - opcodes[row.getKey()] = new ALUOpcode(val.getValue(), row.getValue()); - } - } - for (Entry val : indexedList(0xC6, 8, ALUType.ADD, ALUType.ADC, ALUType.SUB, ALUType.SBC, ALUType.AND, ALUType.XOR, ALUType.OR, ALUType.CP)) { - opcodes[val.getKey()] = new ALUOpcode(val.getValue(), Argument.D8); - } - - // Restarts - for (Entry val : indexedList(0xC7, 8, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38)) { - opcodes[val.getKey()] = new RestartOpcode(val.getValue()); - } - - // Interrupts - opcodes[0xF3] = new InterruptOpcode(false, interruptManager); - opcodes[0xFB] = new InterruptOpcode(true, interruptManager); - - // Misc - opcodes[0x2F] = new ComplementOpcode(); - opcodes[0x37] = new SetCarryOpcode(); - opcodes[0x3F] = new FlipCarryOpcode(); - } - - public void loadPrefixedOpcodes() { - for (Entry val : indexedList(0x00, 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - prefixedOpcodes[val.getKey() + 0x00] = new RotateOpcode(true, val.getValue(), RotateOpcode.LEFT); - prefixedOpcodes[val.getKey() + 0x08] = new RotateOpcode(true, val.getValue(), RotateOpcode.RIGHT); - prefixedOpcodes[val.getKey() + 0x10] = new RotateOpcode(false, val.getValue(), RotateOpcode.LEFT); - prefixedOpcodes[val.getKey() + 0x18] = new RotateOpcode(false, val.getValue(), RotateOpcode.RIGHT); - } - - for (Entry val : indexedList(0x40, 8, 0, 1, 2, 3, 4, 5, 6, 7)) { - for (Entry row : indexedList(val.getKey(), 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - prefixedOpcodes[row.getKey()] = new BitOpcode(val.getValue(), row.getValue()); - } - } - - for (Entry val : indexedList(0x30, 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - prefixedOpcodes[val.getKey()] = new SwapOpcode(val.getValue()); - } - - // Reset Bit - for (Entry val : indexedList(0x80, 8, 0, 1, 2, 3, 4, 5, 6, 7)) { - for (Entry row : indexedList(val.getKey(), 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - prefixedOpcodes[row.getKey()] = new ResetBitOpcode(val.getValue(), row.getValue()); - } - } - - // Set Bit - for (Entry val : indexedList(0xC0, 8, 0, 1, 2, 3, 4, 5, 6, 7)) { - for (Entry row : indexedList(val.getKey(), 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - prefixedOpcodes[row.getKey()] = new SetBitOpcode(val.getValue(), row.getValue()); - } - } - - for (Entry val : indexedList(0x20, 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - prefixedOpcodes[val.getKey()] = new ShiftOpcode(ShiftType.SLA, val.getValue()); - } - for (Entry val : indexedList(0x28, 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - prefixedOpcodes[val.getKey()] = new ShiftOpcode(ShiftType.SRA, val.getValue()); - } - for (Entry val : indexedList(0x38, 1, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { - prefixedOpcodes[val.getKey()] = new ShiftOpcode(ShiftType.SRL, val.getValue()); - } - } - - @SafeVarargs - private static Iterable> indexedList(int start, int step, T... values) { - Map map = new LinkedHashMap<>(); - int i = start; - for (T e : values) { - map.put(i, e); - i += step; - } - return map.entrySet(); - } - - public void clock() { - if (cycles == 0) { - //Log.info("PC: 0x%4x", registers.getPC()); - - if (registers.getPC() == 0x2EFC) { - Log.info("Breakpoint."); - } - - int opcodeValue = mmu.read(registers.getPC()); - registers.incPC(); - - if (opcodeValue == 0xCB) { - int prefixedValue = mmu.read(registers.getPC()); - registers.incPC(); - - runPrefixedOpcode(prefixedValue); - - } else { - runOpcode(opcodeValue); - } - } - - cycles--; - } - - private void runOpcode(int opcodeValue) { - Opcode opcode = opcodes[opcodeValue]; - - if (opcode == null) { - Log.error("Unimplemented opcode 0x%2x at 0x%4x!", opcodeValue, registers.getPC()); - - Log.close(); - - throw new IllegalStateException(); - - //System.exit(0); - } - - //Log.info("Executing opcode: 0x%2x (%s)", opcodeValue, opcode.toString()); - cycles += opcode.run(registers, mmu) + 4; // Adding 4 because we fetch the instruction. - } - - private void runPrefixedOpcode(int opcodeValue) { - Opcode opcode = prefixedOpcodes[opcodeValue]; - - if (opcode == null) { - Log.error("Unimplemented prefixed opcode 0x%2x!", opcodeValue); - - Log.close(); - - throw new IllegalStateException(); - - //System.exit(0); - } - - //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. - } - - @Override - public void interruptOccured(int types) { - /*if ((types & InterruptManager.VBLANK) != 0) { - interruptManager.disable(); - - registers.decSP(); - 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()); - - registers.setPC(0x40); - - cycles += 12; - }*/ - } - - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/cpu/Flags.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/cpu/Flags.java deleted file mode 100644 index c4e121a..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/cpu/Flags.java +++ /dev/null @@ -1,29 +0,0 @@ -package playingcoffee.core.cpu; - -public class Flags { - - private int f; // Technically the "correct" notation - - public static final int ZERO = 1 << 7; - public static final int NEGATIVE = 1 << 6; - public static final int HALF_CARRY = 1 << 5; - public static final int CARRY = 1 << 4; - - public void set(int value) { - f = value & 0xFF; - } - - public int get() { - return f; - } - - public void set(int flag, boolean value) { - if (value) f |= flag; - else f &= ~flag; - } - - public boolean get(int flag) { - return (f & flag) != 0; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/cpu/Registers.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/cpu/Registers.java deleted file mode 100644 index 82c97f6..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/cpu/Registers.java +++ /dev/null @@ -1,57 +0,0 @@ -package playingcoffee.core.cpu; - -public class Registers { - - private int a, b, c, d, e, h, l; - - private int pc, sp; - - private Flags flags; - - public Registers() { - flags = new Flags(); - } - - public int getA() { return a; } - public int getB() { return b; } - public int getC() { return c; } - public int getD() { return d; } - public int getE() { return e; } - public int getH() { return h; } - public int getL() { return l; } - - public void setA(int value) { a = value & 0xFF; } - public void setB(int value) { b = value & 0xFF; } - public void setC(int value) { c = value & 0xFF; } - public void setD(int value) { d = value & 0xFF; } - public void setE(int value) { e = value & 0xFF; } - public void setH(int value) { h = value & 0xFF; } - public void setL(int value) { l = value & 0xFF; } - - public Flags getFlags() { return flags; } - - public int getAF() { return (a << 8) | flags.get(); } - public int getBC() { return (b << 8) | c; } - public int getDE() { return (d << 8) | e; } - public int getHL() { return (h << 8) | l; } - - public int getPC() { return pc; } - public int getSP() { return sp; } - - public void setAF(int value) { flags.set(value >> 8); setA(value); } - public void setBC(int value) { setB(value >> 8); setC(value); } - public void setDE(int value) { setD(value >> 8); setE(value); } - public void setHL(int value) { setH(value >> 8); setL(value); } - - public void setPC(int value) { pc = value & 0xFFFF; } - public void setSP(int value) { sp = value & 0xFFFF; } - - public void addPC(int value) { setPC(getPC() + value); }; - public void addSP(int value) { setSP(getSP() + value); }; - - public void incPC() { addPC(1); } - public void incSP() { addSP(1); } - - public void decPC() { addPC(-1); } - public void decSP() { addSP(-1); } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ALU16Opcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ALU16Opcode.java deleted file mode 100644 index b4fef41..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ALU16Opcode.java +++ /dev/null @@ -1,57 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; - -public class ALU16Opcode implements Opcode { - - private final ALU16Type type; - private final Argument register; - - public ALU16Opcode(ALU16Type type, Argument register) { - this.type = type; - this.register = register; - } - - @Override - public int run(Registers registers, MMU mmu) { - int result = 0; - - switch (type) { - case INC: - register.write(register.read(registers, mmu) + 1, registers, mmu); - break; - case DEC: - register.write(register.read(registers, mmu) - 1, registers, mmu); - break; - case ADD: - int value = register.read(registers, mmu); - result = registers.getHL() + value; - - registers.getFlags().set(Flags.NEGATIVE, false); - registers.getFlags().set(Flags.HALF_CARRY, ((value & 0xF) + (registers.getHL() & 0xF) > 0xF)); - registers.getFlags().set(Flags.CARRY, (result & 0xFFFF0000) != 0); - - register.write(result, registers, mmu); - - break; - default: - Log.error("wtf!? how did we get here?!?!?"); - break; - } - - return register.getCycles() + 4; - } - - public enum ALU16Type { - INC, DEC, ADD - } - - @Override - public String toString() { - return type.name() + " " + register.getName(); - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ALUOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ALUOpcode.java deleted file mode 100644 index 8cfa92a..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ALUOpcode.java +++ /dev/null @@ -1,134 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; - -public class ALUOpcode implements Opcode { - - private final ALUType type; - private final Argument register; - - public ALUOpcode(ALUType type, Argument register) { - this.type = type; - this.register = register; - } - - @Override - public int run(Registers registers, MMU mmu) { - int result = 0; - int registerValue = register.read(registers, mmu); - - switch (type) { - case ADD: - result = registers.getA() + registerValue; - - registers.getFlags().set(Flags.ZERO, (result & 0xFF) == 0); - registers.getFlags().set(Flags.NEGATIVE, false); - registers.getFlags().set(Flags.HALF_CARRY, (registers.getA() & 0xF) + (registerValue & 0xF) > 0xF); - registers.getFlags().set(Flags.CARRY, (result & 0xFF00) > 0); - - break; - case ADC: - int value = registerValue + (registers.getFlags().get(Flags.CARRY) ? 1 : 0); - - result = registers.getA() + value; - - registers.getFlags().set(Flags.ZERO, (result & 0xFF) == 0); - registers.getFlags().set(Flags.NEGATIVE, false); - registers.getFlags().set(Flags.HALF_CARRY, (registers.getA() & 0xF) + (value & 0xF) > 0xF); - registers.getFlags().set(Flags.CARRY, (result & 0xFF00) > 0); - - break; - case AND: - result = registers.getA() & registerValue; - - registers.getFlags().set(Flags.ZERO, (result & 0xFF) == 0); - registers.getFlags().set(Flags.NEGATIVE, false); - registers.getFlags().set(Flags.HALF_CARRY, true); - registers.getFlags().set(Flags.CARRY, false); - - break; - case CP: - result = registers.getA(); - - registers.getFlags().set(Flags.ZERO, registers.getA() == registerValue); - registers.getFlags().set(Flags.NEGATIVE, true); - registers.getFlags().set(Flags.HALF_CARRY, (registerValue & 0xF) > (registers.getA() & 0xF)); - registers.getFlags().set(Flags.CARRY, registerValue > registers.getA()); - - break; - case OR: - result = registers.getA() | registerValue; - - registers.getFlags().set(Flags.ZERO, (result & 0xFF) == 0); - registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY | Flags.CARRY, false); - - break; - case SBC: - value = registerValue + (registers.getFlags().get(Flags.CARRY) ? 1 : 0); - - registers.getFlags().set(Flags.ZERO, value == registers.getA()); - registers.getFlags().set(Flags.NEGATIVE, true); - registers.getFlags().set(Flags.HALF_CARRY, (value & 0xF) > (registers.getA() & 0xF)); - registers.getFlags().set(Flags.CARRY, value > registers.getA()); - - result = registers.getA() - value; - - break; - case SUB: - registers.getFlags().set(Flags.ZERO, registerValue == registers.getA()); - registers.getFlags().set(Flags.NEGATIVE, true); - registers.getFlags().set(Flags.HALF_CARRY, registerValue > (registers.getA() & 0xF)); - registers.getFlags().set(Flags.CARRY, registerValue > registers.getA()); - - result = registers.getA() - registerValue; - - break; - case XOR: - result = registers.getA() ^ registerValue; - - registers.getFlags().set(Flags.ZERO, (result & 0xFF) == 0); - registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY | Flags.CARRY, false); - - break; - case INC: - result = registerValue + 1; - - registers.getFlags().set(Flags.ZERO, (result & 0xFF) == 0); - registers.getFlags().set(Flags.NEGATIVE, false); - registers.getFlags().set(Flags.HALF_CARRY, (result & 0x10) != 0); - - register.write(result, registers, mmu); - break; - case DEC: - result = registerValue - 1; - - registers.getFlags().set(Flags.ZERO, (result & 0xFF) == 0); - registers.getFlags().set(Flags.NEGATIVE, true); - registers.getFlags().set(Flags.HALF_CARRY, (registerValue & 0x0F) == 0x0F); - - register.write(result, registers, mmu); - break; - default: - Log.error("wtf!? how did we get here?!?!?"); - break; - } - - if (type != ALUType.INC && type != ALUType.DEC) - registers.setA(result); - - return 0; - } - - public enum ALUType { - ADD, ADC, SUB, SBC, AND, XOR, OR, CP, INC, DEC - } - - @Override - public String toString() { - return type.name() + " A, " + register.getName(); - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/Argument.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/Argument.java deleted file mode 100644 index 6250bad..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/Argument.java +++ /dev/null @@ -1,348 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; - -public enum Argument { - - // Note: The '_' prefix, specifies the value located at the memory address the register is pointing to. - // Example: _HL <=> memory[HL] - - A { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getA(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setA(value); - } - }, B { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getB(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setB(value); - } - }, C { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getC(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setC(value); - } - }, D { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getD(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setD(value); - } - }, E { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getE(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setE(value); - } - }, H { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getH(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setH(value); - } - }, L { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getL(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setL(value); - } - }, AF { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getAF(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setAF(value); - } - }, BC { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getBC(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setBC(value); - } - }, DE { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getDE(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setDE(value); - } - }, HL { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getHL(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setHL(value); - } - }, SP { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getSP(); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - registers.setSP(value); - } - }, _BC("(BC)", 4) { - @Override - public int read(Registers registers, MMU mmu) { - return mmu.read(registers.getBC()); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - mmu.write(value, registers.getBC()); - } - }, _DE("(DE)", 4) { - @Override - public int read(Registers registers, MMU mmu) { - return mmu.read(registers.getDE()); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - mmu.write(value, registers.getDE()); - } - }, _HL("(HL)", 4) { - @Override - public int read(Registers registers, MMU mmu) { - return mmu.read(registers.getHL()); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - mmu.write(value, registers.getHL()); - } - }, _HL_INC("(HL+)", 4) { - @Override - public int read(Registers registers, MMU mmu) { - int value = mmu.read(registers.getHL()); - registers.setHL(registers.getHL() + 1); - return value; - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - int address = registers.getHL(); - registers.setHL(registers.getHL() + 1); - mmu.write(value, address); - } - }, _HL_DEC("(HL-)", 4) { - @Override - public int read(Registers registers, MMU mmu) { - int value = mmu.read(registers.getHL()); - registers.setHL(registers.getHL() - 1); - return value; - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - int address = registers.getHL(); - registers.setHL(registers.getHL() - 1); - mmu.write(value, address); - } - }, D8(4) { - @Override - public int read(Registers registers, MMU mmu) { - int value = mmu.read(registers.getPC()); - registers.incPC(); - - return value; - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - Log.warn("Why are you writing to this argument?"); - } - }, D16(8) { - @Override - public int read(Registers registers, MMU mmu) { - int value = mmu.read(registers.getPC()); - - registers.incPC(); - - value |= mmu.read(registers.getPC()) << 8; - - registers.incPC(); - - return value; - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - Log.warn("Why are you writing to this argument?"); - } - }, I8(4) { - - @Override - public int read(Registers registers, MMU mmu) { - byte relativeAddress = (byte) mmu.read(registers.getPC()); - - registers.incPC(); - - return relativeAddress; - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - Log.warn("Why are you writing to this argument?"); - } - - }, _C("(C)", 4) { // memory[0xFF00 + C] - @Override - public int read(Registers registers, MMU mmu) { - int value = mmu.read(0xFF00 + registers.getC()); - - return value; - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - mmu.write(value, 0xFF00 + registers.getC()); - } - }, _D8("(D8)", 8) { // memory[0xFF00 + memory[PC++]] - @Override - public int read(Registers registers, MMU mmu) { - int value = mmu.read(0xFF00 + mmu.read(registers.getPC())); - - registers.incPC(); - - return value; - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - mmu.write(value, 0xFF00 + mmu.read(registers.getPC())); - - registers.incPC(); - } - }, _D16("(D16)", 12) { - @Override - public int read(Registers registers, MMU mmu) { - int address = mmu.read(registers.getPC()); - - registers.incPC(); - - address |= mmu.read(registers.getPC()) << 8; - - registers.incPC(); - - return mmu.read(address); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - int address = mmu.read(registers.getPC()); - - registers.incPC(); - - address |= mmu.read(registers.getPC()) << 8; - - registers.incPC(); - - mmu.write(value, address); - } - }, _D16_SHORT("(D16 (16 bits))", 16) { - @Override - public int read(Registers registers, MMU mmu) { - int address = mmu.read(registers.getPC()); - - registers.incPC(); - - address |= mmu.read(registers.getPC()) << 8; - - registers.incPC(); - - return (mmu.read(address) << 8) | mmu.read(address); - } - - @Override - public void write(int value, Registers registers, MMU mmu) { - int address = mmu.read(registers.getPC()); - - registers.incPC(); - - address |= mmu.read(registers.getPC()) << 8; - - registers.incPC(); - - mmu.write(value >> 8, address); - mmu.write(value, address + 1); - } - }; - - private String name; - private int cycles; - - Argument(String name, int cycles) { - this.name = name; - this.cycles = cycles; - } - - Argument(int cycles) { - this.name = name(); - this.cycles = cycles; - } - - Argument() { - this.name = name(); - this.cycles = 0; - } - - public abstract int read(Registers registers, MMU mmu); - public abstract void write(int value, Registers registers, MMU mmu); - - public String getName() { - return name; - } - - public int getCycles() { - return cycles; - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/CallOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/CallOpcode.java deleted file mode 100644 index 2a0e2ad..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/CallOpcode.java +++ /dev/null @@ -1,60 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; - -public class CallOpcode implements Opcode { - - private int conditionFlag; - private Argument address; - private boolean not; - - public CallOpcode(int conditionFlag, Argument address, boolean not) { - this.conditionFlag = conditionFlag; - this.address = address; - this.not = not; - } - - public boolean canExecute(Registers registers) { - return (conditionFlag == 0) || (registers.getFlags().get(conditionFlag) ^ not); - } - - @Override - public int run(Registers registers, MMU mmu) { - int addressToJump = address.read(registers, mmu); - - if (canExecute(registers)) { - registers.decSP(); - 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()); - - registers.setPC(addressToJump); - - return 12 + address.getCycles(); // 2 memory writes and additional cycle - } - - return address.getCycles(); - } - - @Override - public String toString() { - if (conditionFlag == 0) - return "CALL " + address.getName(); - - char flag = ' '; - switch (conditionFlag) { - case Flags.ZERO: flag = 'Z'; break; - case Flags.NEGATIVE: flag = 'N'; break; - case Flags.HALF_CARRY: flag = 'H'; break; - case Flags.CARRY: flag = 'C'; break; - } - - return "CALL " + (not ? "" : "N") + flag + ", " + address.getName(); - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ComplementOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ComplementOpcode.java deleted file mode 100644 index ece82c6..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ComplementOpcode.java +++ /dev/null @@ -1,18 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; - -public class ComplementOpcode implements Opcode { - - @Override - public int run(Registers registers, MMU mmu) { - registers.setA(~registers.getA()); - - registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); - - return 0; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/FlipCarryOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/FlipCarryOpcode.java deleted file mode 100644 index 0b32d4a..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/FlipCarryOpcode.java +++ /dev/null @@ -1,17 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; - -public class FlipCarryOpcode implements Opcode { - - @Override - public int run(Registers registers, MMU mmu) { - registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, !registers.getFlags().get(Flags.CARRY)); - - return 0; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/InterruptOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/InterruptOpcode.java deleted file mode 100644 index 9c398f6..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/InterruptOpcode.java +++ /dev/null @@ -1,29 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.InterruptManager; -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; - -public class InterruptOpcode implements Opcode { - - private boolean enable; - private InterruptManager interruptManager; - - public InterruptOpcode(boolean enable, InterruptManager interruptManager) { - this.enable = enable; - this.interruptManager = interruptManager; - } - - @Override - public int run(Registers registers, MMU mmu) { - if (enable) - interruptManager.enable(); - else - interruptManager.disable(); - - return 0; - } - - - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/JumpOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/JumpOpcode.java deleted file mode 100644 index 5444f41..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/JumpOpcode.java +++ /dev/null @@ -1,50 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; - -public class JumpOpcode implements Opcode { - - private int conditionFlag; - private Argument address; - private boolean not; - - public JumpOpcode(int conditionFlag, Argument address, boolean not) { - this.conditionFlag = conditionFlag; - this.address = address; - this.not = not; - } - - public boolean canExecute(Registers registers) { - return (conditionFlag == 0) || (registers.getFlags().get(conditionFlag) ^ not); - } - - @Override - public int run(Registers registers, MMU mmu) { - int addressToJump = address.read(registers, mmu); - - if (canExecute(registers)) { - registers.setPC(addressToJump); - return address.getCycles() + 4; - } - - return address.getCycles(); - } - - @Override - public String toString() { - if (conditionFlag == 0) - return "JP " + address.getName(); - - char flag = ' '; - switch (conditionFlag) { - case Flags.ZERO: flag = 'Z'; break; - case Flags.NEGATIVE: flag = 'N'; break; - case Flags.HALF_CARRY: flag = 'H'; break; - case Flags.CARRY: flag = 'C'; break; - } - - return "JP " + (not ? "" : "N") + flag + ", " + address.getName(); - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/JumpRelativeOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/JumpRelativeOpcode.java deleted file mode 100644 index 3a804a8..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/JumpRelativeOpcode.java +++ /dev/null @@ -1,51 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; - -public class JumpRelativeOpcode implements Opcode { - - private int conditionFlag; - private Argument address; - private boolean not; - - public JumpRelativeOpcode(int conditionFlag, Argument address, boolean not) { - this.conditionFlag = conditionFlag; - this.address = address; - this.not = not; - } - - public boolean canExecute(Registers registers) { - return (conditionFlag == 0) || (registers.getFlags().get(conditionFlag) ^ not); - } - - @Override - public int run(Registers registers, MMU mmu) { - int relativeValue = address.read(registers, mmu); - - int addressToJump = registers.getPC() + relativeValue; - if (canExecute(registers)) { - registers.setPC(addressToJump); - return address.getCycles() + 4; - } - - return address.getCycles(); - } - - @Override - public String toString() { - if (conditionFlag == 0) - return "JR " + address.getName(); - - char flag = ' '; - switch (conditionFlag) { - case Flags.ZERO: flag = 'Z'; break; - case Flags.NEGATIVE: flag = 'N'; break; - case Flags.HALF_CARRY: flag = 'H'; break; - case Flags.CARRY: flag = 'C'; break; - } - - return "JR " + (not ? "" : "N") + flag + ", " + address.getName(); - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/LoadOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/LoadOpcode.java deleted file mode 100644 index a782b65..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/LoadOpcode.java +++ /dev/null @@ -1,26 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; - -public class LoadOpcode implements Opcode { - - private Argument from, to; - - public LoadOpcode(Argument from, Argument to) { - this.from = from; - this.to = to; - } - - @Override - public int run(Registers registers, MMU mmu) { - to.write(from.read(registers, mmu), registers, mmu); - - return to.getCycles() + from.getCycles(); - } - - @Override - public String toString() { - return "LD " + to.getName() + ", " + from.getName(); - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/Opcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/Opcode.java deleted file mode 100644 index 71cdaa5..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/Opcode.java +++ /dev/null @@ -1,10 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; - -public interface Opcode { - - public int run(Registers registers, MMU mmu); - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/PopOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/PopOpcode.java deleted file mode 100644 index ce4daca..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/PopOpcode.java +++ /dev/null @@ -1,32 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; - -public class PopOpcode implements Opcode { - - private final Argument register; - - public PopOpcode(Argument register) { - this.register = register; - } - - @Override - public int run(Registers registers, MMU mmu) { - int value = mmu.read(registers.getSP()); - registers.incSP(); - - value |= mmu.read(registers.getSP()) << 8; - registers.incSP(); - - register.write(value, registers, mmu); - - return 8; - } - - @Override - public String toString() { - return "POP " + register.getName(); - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/PushOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/PushOpcode.java deleted file mode 100644 index fee0abf..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/PushOpcode.java +++ /dev/null @@ -1,35 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; - -public class PushOpcode implements Opcode { - - private final Argument register; - - public PushOpcode(Argument register) { - this.register = register; - } - - @Override - public int run(Registers registers, MMU mmu) { - int value = register.read(registers, mmu); - - registers.decSP(); - mmu.write(value >> 8, registers.getSP()); - - registers.decSP(); - mmu.write(value, registers.getSP()); - - Log.info("Pushing 0x%4x to the stack.", value); - - return 8; - } - - @Override - public String toString() { - return "PUSH " + register.getName(); - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/RestartOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/RestartOpcode.java deleted file mode 100644 index 8ce0964..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/RestartOpcode.java +++ /dev/null @@ -1,26 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; - -public class RestartOpcode implements Opcode { - - private int address; - - public RestartOpcode(int address) { - this.address = address; - } - - @Override - public int run(Registers registers, MMU mmu) { - registers.decSP(); - mmu.write(registers.getPC() >> 8, registers.getSP()); - registers.decSP(); - mmu.write(registers.getPC(), registers.getSP()); - - registers.setPC(address); - - return 12; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ReturnOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ReturnOpcode.java deleted file mode 100644 index 5c4d903..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/ReturnOpcode.java +++ /dev/null @@ -1,67 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.InterruptManager; -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; - -public class ReturnOpcode implements Opcode { - - private int conditionFlag; - private boolean not; - private boolean fromInterupt; - - private final InterruptManager interruptManager; - - public ReturnOpcode(int conditionFlag, boolean not, boolean fromInterupt, final InterruptManager interruptManager) { - this.conditionFlag = conditionFlag; - this.not = not; - this.fromInterupt = fromInterupt; - this.interruptManager = interruptManager; - } - - public boolean canExecute(Registers registers) { - return (conditionFlag == 0) || (registers.getFlags().get(conditionFlag) ^ not); - } - - @Override - 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)) { - Log.info("Returning from 0x%4x to 0x%4x", registers.getPC(), addressToJump); - - registers.setPC(addressToJump); - - if (fromInterupt) { - interruptManager.enable(); - } - - return 16; - } - - return 4; - } - - @Override - public String toString() { - if (conditionFlag == 0) - return "RET" + (fromInterupt ? "I" : ""); - - char flag = ' '; - switch (conditionFlag) { - case Flags.ZERO: flag = 'Z'; break; - case Flags.NEGATIVE: flag = 'N'; break; - case Flags.HALF_CARRY: flag = 'H'; break; - case Flags.CARRY: flag = 'C'; break; - } - - return "RET" + (fromInterupt ? "I" : "") + " " + (not ? "" : "N") + flag; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/RotateAOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/RotateAOpcode.java deleted file mode 100644 index f74c024..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/RotateAOpcode.java +++ /dev/null @@ -1,68 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; - -public class RotateAOpcode implements Opcode { - - private boolean withCarry; - private int direction; - - public static final int LEFT = -1; - public static final int RIGHT = 1; - - public RotateAOpcode(boolean withCarry, int direction) { - this.withCarry = withCarry; - this.direction = direction; - } - - @Override - public int run(Registers registers, MMU mmu) { - if (direction == LEFT) { - if (withCarry) { - int value = registers.getA(); - int result = (value << 1) | ((value >> 7) & 1); - - registers.getFlags().set(Flags.ZERO | Flags.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0); - - registers.setA(result); - } else { - int value = registers.getA(); - int result = (value << 1) | (registers.getFlags().get(Flags.CARRY) ? 1 : 0); - - registers.getFlags().set(Flags.ZERO | Flags.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0); - - registers.setA(result); - } - } else { - if (withCarry) { - int value = registers.getA(); - int result = (value >> 1) | ((value & 1) << 7); - - registers.getFlags().set(Flags.ZERO | Flags.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, (value & 1) != 0); - - registers.setA(result); - } else { - int value = registers.getA(); - int result = (value >> 1) | ((registers.getFlags().get(Flags.CARRY) ? 1 : 0) << 7); - - registers.getFlags().set(Flags.ZERO | Flags.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, (value & 1) != 0); - - registers.setA(result); - } - } - - return 0; - } - - @Override - public String toString() { - return "R" + (direction == LEFT ? "L" : "R") + (withCarry ? "C" : "" + "A"); - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/SetCarryOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/SetCarryOpcode.java deleted file mode 100644 index 9b570b6..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/SetCarryOpcode.java +++ /dev/null @@ -1,17 +0,0 @@ -package playingcoffee.core.opcode; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; - -public class SetCarryOpcode implements Opcode { - - @Override - public int run(Registers registers, MMU mmu) { - registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, true); - - return 0; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/BitOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/BitOpcode.java deleted file mode 100644 index 2053d6a..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/BitOpcode.java +++ /dev/null @@ -1,33 +0,0 @@ -package playingcoffee.core.opcode.prefixed; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; -import playingcoffee.core.opcode.Argument; -import playingcoffee.core.opcode.Opcode; - -public class BitOpcode implements Opcode { - - private int bit; - private Argument argument; - - public BitOpcode(int bit, Argument argument) { - this.bit = bit; - this.argument = argument; - } - - @Override - public int run(Registers registers, MMU mmu) { - registers.getFlags().set(Flags.ZERO, (argument.read(registers, mmu) & (1 << bit)) == 0); - registers.getFlags().set(Flags.NEGATIVE, false); - registers.getFlags().set(Flags.HALF_CARRY, true); - - return argument.getCycles(); - } - - @Override - public String toString() { - return "BIT " + bit + ", " + argument.getName(); - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/ResetBitOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/ResetBitOpcode.java deleted file mode 100644 index 525480e..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/ResetBitOpcode.java +++ /dev/null @@ -1,25 +0,0 @@ -package playingcoffee.core.opcode.prefixed; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; -import playingcoffee.core.opcode.Argument; -import playingcoffee.core.opcode.Opcode; - -public class ResetBitOpcode implements Opcode { - - private int bit; - private Argument argument; - - public ResetBitOpcode(int bit, Argument argument) { - this.bit = bit; - this.argument = argument; - } - - @Override - public int run(Registers registers, MMU mmu) { - argument.write(argument.read(registers, mmu) & (~(1 << bit)), registers, mmu); - - return argument.getCycles() * 2; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/RotateOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/RotateOpcode.java deleted file mode 100644 index b13a21a..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/RotateOpcode.java +++ /dev/null @@ -1,54 +0,0 @@ -package playingcoffee.core.opcode.prefixed; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; -import playingcoffee.core.opcode.Argument; -import playingcoffee.core.opcode.Opcode; - -public class RotateOpcode implements Opcode { - - private boolean withCarry; - private Argument register; - private int direction; - - public static final int LEFT = -1; - public static final int RIGHT = 1; - - public RotateOpcode(boolean withCarry, Argument register, int direction) { - this.withCarry = withCarry; - this.register = register; - this.direction = direction; - } - - @Override - public int run(Registers registers, MMU mmu) { - if (direction == LEFT) { - int value = register.read(registers, mmu); - 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.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0); - - register.write(result, registers, mmu); - - } else { - int value = register.read(registers, mmu); - int result = (value >> 1) | ((!withCarry ? (registers.getFlags().get(Flags.CARRY) ? 1 : 0) : (value & 0x1)) << 7); - - registers.getFlags().set(Flags.ZERO, result == 0); - registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, (value & 1) != 0); - - register.write(result, registers, mmu); - } - - return register.getCycles(); - } - - @Override - public String toString() { - return "R" + (direction == LEFT ? "L" : "R") + (withCarry ? "C " : " " + register.getName()); - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/SetBitOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/SetBitOpcode.java deleted file mode 100644 index f53b6c5..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/SetBitOpcode.java +++ /dev/null @@ -1,25 +0,0 @@ -package playingcoffee.core.opcode.prefixed; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; -import playingcoffee.core.opcode.Argument; -import playingcoffee.core.opcode.Opcode; - -public class SetBitOpcode implements Opcode { - - private int bit; - private Argument argument; - - public SetBitOpcode(int bit, Argument argument) { - this.bit = bit; - this.argument = argument; - } - - @Override - public int run(Registers registers, MMU mmu) { - argument.write(argument.read(registers, mmu) | (1 << bit), registers, mmu); - - return argument.getCycles() * 2; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/ShiftOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/ShiftOpcode.java deleted file mode 100644 index f75e9bd..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/ShiftOpcode.java +++ /dev/null @@ -1,57 +0,0 @@ -package playingcoffee.core.opcode.prefixed; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Flags; -import playingcoffee.core.cpu.Registers; -import playingcoffee.core.opcode.Argument; -import playingcoffee.core.opcode.Opcode; - -public class ShiftOpcode implements Opcode { - - private ShiftType type; - private Argument register; - - public ShiftOpcode(ShiftType type, Argument register) { - this.type = type; - this.register = register; - } - - public enum ShiftType { - SLA, SRA, SRL - } - - @Override - public int run(Registers registers, MMU mmu) { - int value, result; - - switch (type) { - case SLA: - value = register.read(registers, mmu); - result = value << 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); - break; - case SRA: - value = register.read(registers, mmu); - result = (value >> 1) | (value & 0x80); - - registers.getFlags().set(Flags.ZERO, result == 0); - registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, (value & 0x1) != 0); - break; - case SRL: - value = register.read(registers, mmu); - result = (value >> 1); - - registers.getFlags().set(Flags.ZERO, result == 0); - registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, (value & 0x1) != 0); - break; - } - - return register.getCycles() * 2; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/SwapOpcode.java b/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/SwapOpcode.java deleted file mode 100644 index b31cac8..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/opcode/prefixed/SwapOpcode.java +++ /dev/null @@ -1,25 +0,0 @@ -package playingcoffee.core.opcode.prefixed; - -import playingcoffee.core.MMU; -import playingcoffee.core.cpu.Registers; -import playingcoffee.core.opcode.Argument; -import playingcoffee.core.opcode.Opcode; - -public class SwapOpcode implements Opcode { - - private Argument register; - - public SwapOpcode(Argument register) { - this.register = register; - } - - @Override - public int run(Registers registers, MMU mmu) { - int value = register.read(registers, mmu); - - register.write(((value & 0xF0) >> 4) | ((value & 0xF) << 4), registers, mmu); - - return register.getCycles() * 2; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/log/Log.java b/playing-coffee - Copy/src/main/java/playingcoffee/log/Log.java deleted file mode 100644 index 1bb6478..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/log/Log.java +++ /dev/null @@ -1,73 +0,0 @@ -package playingcoffee.log; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.time.LocalTime; - -public class Log { - - public static final String ANSI_RESET = "\033[0m"; - public static final String ANSI_BLACK = "\u001B[30m"; - public static final String ANSI_RED = "\u001B[31m"; - public static final String ANSI_GREEN = "\u001B[32m"; - public static final String ANSI_YELLOW = "\u001B[33m"; - public static final String ANSI_BLUE = "\u001B[34m"; - public static final String ANSI_PURPLE = "\u001B[35m"; - public static final String ANSI_CYAN = "\u001B[36m"; - public static final String ANSI_WHITE = "\u001B[37m"; - - private static FileWriter fileWriter; - - private static boolean useColors = false; - - public static void init() { - try { - File file = new File("log.txt"); - file.createNewFile(); - - fileWriter = new FileWriter(file); - } catch (IOException e) { - e.printStackTrace(); - System.exit(-1); - } - info("Initialized logger"); - } - - public static void close() { - try { - fileWriter.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static void info(String format, Object... args) { - log("Info", ANSI_RESET, format, args); - } - - public static void warn(String format, Object... args) { - log("Warning", ANSI_YELLOW, format, args); - } - - public static void error(String format, Object... args) { - log("Error", ANSI_RED, format, args); - } - - public static void fatal(String format, Object... args) { - log("Fatal", ANSI_RED, format, args); - } - - private static void log(String type, String ansiColor, String format, Object... args) { - String finalMessage = "[" + LocalTime.now() + "] " + type + ": " + String.format(format, args); - - ansiColor = useColors ? ansiColor : ""; - - System.out.println(ansiColor + finalMessage); - try { - fileWriter.write(finalMessage + "\n"); - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/ppu/OAM.java b/playing-coffee - Copy/src/main/java/playingcoffee/ppu/OAM.java deleted file mode 100644 index 8ef0dcd..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/ppu/OAM.java +++ /dev/null @@ -1,52 +0,0 @@ -package playingcoffee.ppu; - -import playingcoffee.core.MemorySpace; -import playingcoffee.log.Log; - -public class OAM implements MemorySpace { - - public OAMEntry entries[]; - - public OAM() { - entries = new OAMEntry[40]; - } - - public int read(int address) { - int entry = (address - 0xFE00) / 4; - - switch (address % 4) { - case 0: return entries[entry].x; - case 1: return entries[entry].y; - case 2: return entries[entry].tileNumber; - case 3: return entries[entry].flags; - } - - Log.error("how in pete's holy christmas tree did we get here?"); - throw new IllegalArgumentException("Invalid address."); - } - - public void write(int value, int address) { - int entry = (address - 0xFE00) / 4; - - switch (address % 4) { - case 0: entries[entry].x = value; - case 1: entries[entry].y = value; - case 2: entries[entry].tileNumber = value; - case 3: entries[entry].flags = value; - } - - Log.error("how in pete's holy christmas tree did we get here?"); - throw new IllegalArgumentException("Invalid address."); - } - - @Override - public boolean inMemorySpace(int address) { - return (address >= 0xFE00 && address <= 0xFE9F); - } - - public class OAMEntry { - public int x, y; - public int tileNumber; - public int flags; - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/ppu/PPU.java b/playing-coffee - Copy/src/main/java/playingcoffee/ppu/PPU.java deleted file mode 100644 index 1a071a7..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/ppu/PPU.java +++ /dev/null @@ -1,73 +0,0 @@ -package playingcoffee.ppu; - -import playingcoffee.core.InterruptManager; -import playingcoffee.core.MMU; - -public class PPU { - - private final MMU mmu; - private final InterruptManager interruptManager; - - private PPURegisters registers; - private VRAM vram; - - private int clockCount = 0; - - public PPU(final MMU mmu, final InterruptManager interruptManager) { - this.mmu = mmu; - this.interruptManager = interruptManager; - - registers = new PPURegisters(); - vram = new VRAM(); - - this.mmu.connectMemorySpace(registers); - this.mmu.connectMemorySpace(vram); - } - - public void OAMSeach() { - registers.setLCDCMode(2); - } - - public void pixelTransfer() { - registers.setLCDCMode(3); - } - - public void HBlank() { - registers.setLCDCMode(0); - } - - public void VBlank() { - registers.setLCDCMode(1); - } - - public void clock() { - registers.lcdcYCoord = clockCount / 114; - - if (clockCount == 114 * 144) - interruptManager.requestInterrupt(InterruptManager.VBLANK); - - if (clockCount < 114 * 144) { - if (clockCount % 114 < 20) OAMSeach(); - else if (clockCount % 114 < 43) pixelTransfer(); - else HBlank(); - - } else { - VBlank(); - } - - clockCount++; - - if (clockCount == 17556) { - clockCount = 0; - } - } - - public PPURegisters getRegisters() { - return registers; - } - - public VRAM getVram() { - return vram; - } - -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/ppu/PPURegisters.java b/playing-coffee - Copy/src/main/java/playingcoffee/ppu/PPURegisters.java deleted file mode 100644 index 54695a8..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/ppu/PPURegisters.java +++ /dev/null @@ -1,61 +0,0 @@ -package playingcoffee.ppu; - -import playingcoffee.core.MemorySpace; - -public class PPURegisters implements MemorySpace { - - public int lcdControl; // 0xFF40 - public int lcdcStatus; // 0xFF41 - public int scrollY, scrollX; // 0xFF42 - 0xFF43 - public int lcdcYCoord; // 0xFF44 - public int lyCompare; // 0xFF45 - public int dmaTransferStart; // 0xFF46 - public int bgPalette; // 0xFF47 - public int objPalette0, objPalette1; // 0xFF48 - 0xFF49 - public int windowY, windowX; // 0xFF4A - 0xFF4B - - public void setLCDCMode(int mode) { - lcdcStatus = (lcdcStatus & 0xFC) | mode; - } - - public int read(int address) { - switch (address) { - case 0xFF40: return lcdControl; - case 0xFF41: return lcdcStatus; - case 0xFF42: return scrollY; - case 0xFF43: return scrollX; - case 0xFF44: return lcdcYCoord; - case 0xFF45: return lyCompare; - case 0xFF46: return dmaTransferStart; // TODO: Do DMA (I have no idea how to do it though...) - case 0xFF47: return bgPalette; - case 0xFF48: return objPalette0; - case 0xFF49: return objPalette1; - case 0xFF4A: return windowY; - case 0xFF4B: return windowX; - } - - throw new IllegalArgumentException("Invalid address"); - } - - public void write(int value, int address) { - switch (address) { - case 0xFF40: lcdControl = value; return; - case 0xFF41: lcdcStatus = value; return; - case 0xFF42: scrollY = value; return; - case 0xFF43: scrollX = 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 0xFF47: bgPalette = value; return; - case 0xFF48: objPalette0 = value; return; - case 0xFF49: objPalette1 = value; return; - case 0xFF4A: windowY = value; return; - case 0xFF4B: windowX = value; return; - } - - throw new IllegalArgumentException("Invalid address"); - } - - public boolean inMemorySpace(int address) { - return (address >= 0xFF40 && address <= 0xFF4B); - } -} diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/ppu/VRAM.java b/playing-coffee - Copy/src/main/java/playingcoffee/ppu/VRAM.java deleted file mode 100644 index c314446..0000000 --- a/playing-coffee - Copy/src/main/java/playingcoffee/ppu/VRAM.java +++ /dev/null @@ -1,35 +0,0 @@ -package playingcoffee.ppu; - -import playingcoffee.core.MemorySpace; - -public class VRAM implements MemorySpace { - - public int[] background0; - public int[] background1; - - public VRAM() { - background0 = new int[32 * 32]; - background1 = new int[32 * 32]; - } - - @Override - public int read(int address) { - if (address >= 0x9800 && address <= 0x9BFF) return background0[address % (32 * 32)]; - if (address >= 0x9C00 && address <= 0x9FFF) return background1[address % (32 * 32)]; - - return 0; - } - - @Override - public void write(int value, int address) { - 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; - } - -} diff --git a/playing-coffee - Copy/src/test/java/playingcoffee/test/GameBoyTest.java b/playing-coffee - Copy/src/test/java/playingcoffee/test/GameBoyTest.java deleted file mode 100644 index 8f2adce..0000000 --- a/playing-coffee - Copy/src/test/java/playingcoffee/test/GameBoyTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package playingcoffee.test; - -import java.io.IOException; - -import org.junit.Test; - -public class GameBoyTest { - - @Test - public void testCPU() throws IOException { - /*Log.init(); - - - byte[] bootRom = Files.readAllBytes(Paths.get("dmg_boot.bin")); - - MMU mmu = new MMU(); - CPU cpu = new CPU(mmu); - - for (int i = 0; i < 0x100; i++) { - mmu.write(Byte.toUnsignedInt(bootRom[i]), i); - } - - while (true) cpu.clock();*/ - } - -} diff --git a/playing-coffee old/.classpath b/playing-coffee old/.classpath deleted file mode 100644 index 51a8bba..0000000 --- a/playing-coffee old/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/playing-coffee old/.project b/playing-coffee old/.project deleted file mode 100644 index e526655..0000000 --- a/playing-coffee old/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - playing-coffee - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/playing-coffee old/.settings/org.eclipse.jdt.core.prefs b/playing-coffee old/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 3a21537..0000000 --- a/playing-coffee old/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,11 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/playing-coffee old/DMG_ROM.bin b/playing-coffee old/DMG_ROM.bin deleted file mode 100644 index afa0ee4..0000000 Binary files a/playing-coffee old/DMG_ROM.bin and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/CPU.class b/playing-coffee old/bin/playingcoffee/core/CPU.class deleted file mode 100644 index b006975..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/CPU.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/MMU.class b/playing-coffee old/bin/playingcoffee/core/MMU.class deleted file mode 100644 index 1df082d..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/MMU.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/Registers.class b/playing-coffee old/bin/playingcoffee/core/Registers.class deleted file mode 100644 index 60292d5..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/Registers.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$1.class b/playing-coffee old/bin/playingcoffee/core/cpu/Argument$1.class deleted file mode 100644 index eaba3c8..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$1.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$2.class b/playing-coffee old/bin/playingcoffee/core/cpu/Argument$2.class deleted file mode 100644 index d8e55fc..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$2.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$3.class b/playing-coffee old/bin/playingcoffee/core/cpu/Argument$3.class deleted file mode 100644 index 6dc78e4..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$3.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$4.class b/playing-coffee old/bin/playingcoffee/core/cpu/Argument$4.class deleted file mode 100644 index cb8caf9..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$4.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$5.class b/playing-coffee old/bin/playingcoffee/core/cpu/Argument$5.class deleted file mode 100644 index 32ba433..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/cpu/Argument$5.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/cpu/Argument.class b/playing-coffee old/bin/playingcoffee/core/cpu/Argument.class deleted file mode 100644 index e29cc3d..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/cpu/Argument.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/core/cpu/Registers.class b/playing-coffee old/bin/playingcoffee/core/cpu/Registers.class deleted file mode 100644 index 865bc0c..0000000 Binary files a/playing-coffee old/bin/playingcoffee/core/cpu/Registers.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/ui/CPUDebugger$1.class b/playing-coffee old/bin/playingcoffee/ui/CPUDebugger$1.class deleted file mode 100644 index 431e33d..0000000 Binary files a/playing-coffee old/bin/playingcoffee/ui/CPUDebugger$1.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/ui/CPUDebugger$2.class b/playing-coffee old/bin/playingcoffee/ui/CPUDebugger$2.class deleted file mode 100644 index de14b9a..0000000 Binary files a/playing-coffee old/bin/playingcoffee/ui/CPUDebugger$2.class and /dev/null differ diff --git a/playing-coffee old/bin/playingcoffee/ui/CPUDebugger.class b/playing-coffee old/bin/playingcoffee/ui/CPUDebugger.class deleted file mode 100644 index db6a71a..0000000 Binary files a/playing-coffee old/bin/playingcoffee/ui/CPUDebugger.class and /dev/null differ diff --git a/playing-coffee old/src/playingcoffee/core/CPU.java b/playing-coffee old/src/playingcoffee/core/CPU.java deleted file mode 100644 index ac2ab94..0000000 --- a/playing-coffee old/src/playingcoffee/core/CPU.java +++ /dev/null @@ -1,112 +0,0 @@ -// Basic CPU implementation. -// This will be changed in the future. - -package playingcoffee.core; - -public class CPU { - - private final MMU mmu; - - private Registers registers; - - private int cycles = 0; - - public static final int[] INSTRUCTION_CYCLE_COUNT = { - 4, 12, 8, 8, 4, 4, 8, 4, 20, 8, 8, 8, 4, 4, 8, 4, - 4, 12, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 4, 4, 8, 4, - 8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4, - 8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 8, 12, 12, 16, 12, 16, 8, 16, 8, 16, 12, 4, 12, 24, 8, 16, - 8, 12, 12, -1, 12, 16, 8, 16, 8, 16, 12, -1, 12, -1, 8, 16, - 12, 12, 8, -1, -1, 16, 8, 16, 16, 4, 16, -1, -1, -1, 8, 16, - 12, 12, 8, 4, -1, 16, 8, 16, 12, 8, 16, 4, -1, -1, 8, 16 - }; - - public static final int[] PREFIXED_CYCLE_COUNT = { - 8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8, - }; - - public CPU(final MMU mmu) { - this.mmu = mmu; - - registers = new Registers(); - } - - public Registers getRegisters() { - return registers; - } - - public int getCycles() { - return cycles; - } - - public void cycle() { - if (cycles == 0) { - - int opcode = mmu.read(registers.pc++); - System.out.printf("Fetched opcode: 0x%02x\n", opcode); - - decodeOpcode(opcode); - } - cycles--; - } - - public void decodeOpcode(int opcode) { - // Apply cycle count - cycles += INSTRUCTION_CYCLE_COUNT[opcode]; - - switch (opcode) { - case 0x00: // NOP - break; - - case 0x21: // LD HL, d16 - registers.writeL(mmu.read(registers.pc++)); - registers.writeH(mmu.read(registers.pc++)); - break; - - case 0x31: // LD SP, d16 - registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8); - break; - - case 0x32: // LD (HL-), A - mmu.write(registers.readA(), registers.readHL()); - registers.writeHL(registers.readHL() - 1); - break; - - case 0xAF: // XOR A - registers.writeA(registers.readA() ^ registers.readA()); - registers.setFlag(Registers.FLAG_Z, registers.readA() == 0); - break; - - case 0xCB: // CB - prefix - decodePrefixedOpcode(mmu.read(registers.pc++)); - break; - - default: - System.err.printf("Unknown opcode: 0x%2x\n", opcode); - } - } - - public void decodePrefixedOpcode(int opcode) { - cycles += INSTRUCTION_CYCLE_COUNT[opcode & 0xF]; - - switch (opcode) { - case 0x7C: - registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0); - registers.setFlag(Registers.FLAG_N, false); - registers.setFlag(Registers.FLAG_H, true); - break; - - default: - System.err.printf("Unknown opcode: 0xcb%2x\n", opcode); - } - } -} diff --git a/playing-coffee old/src/playingcoffee/core/MMU.java b/playing-coffee old/src/playingcoffee/core/MMU.java deleted file mode 100644 index e7b98a8..0000000 --- a/playing-coffee old/src/playingcoffee/core/MMU.java +++ /dev/null @@ -1,34 +0,0 @@ -package playingcoffee.core; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; - -public class MMU { - - private int ram[]; - - public void loadBootRom() { - byte[] data; - try { - data = Files.readAllBytes(Paths.get("DMG_ROM.bin")); - for (int i = 0; i < data.length; i++) { - ram[i] = Byte.toUnsignedInt(data[i]); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - public MMU() { - ram = new int[0x10000]; - } - - public void write(int value, int address) { - ram[address] = value; - } - - public int read(int address) { - return ram[address]; - } -} diff --git a/playing-coffee old/src/playingcoffee/core/Registers.java b/playing-coffee old/src/playingcoffee/core/Registers.java deleted file mode 100644 index 1554b58..0000000 --- a/playing-coffee old/src/playingcoffee/core/Registers.java +++ /dev/null @@ -1,129 +0,0 @@ -package playingcoffee.core; - -public class Registers { - - private int a, f; - private int b, c; - private int d, e; - private int h, l; - - public int pc; - public int sp; - - public static final int FLAG_Z = 1 << 7; - public static final int FLAG_N = 1 << 6; - public static final int FLAG_H = 1 << 5; - public static final int FLAG_C = 1 << 4; - - public void setFlag(int flag, boolean value) { - if (value) - f |= flag; - else - f &= ~flag; - } - - public boolean getFlag(int flag) { - return (f & flag) != 0; - } - - public int readAF() { - return a << 8 | f; - } - - public int readBC() { - return b << 8 | c; - } - - public int readDE() { - return d << 8 | e; - } - - public int readHL() { - return h << 8 | l; - } - - public void writeAF(int af) { - a = (af >> 8) & 0xFF; - f = af & 0xFF; - } - - public void writeBC(int bc) { - b = (bc >> 8) & 0xFF; - c = bc & 0xFF; - } - - public void writeDE(int de) { - d = (de >> 8) & 0xFF; - e = de & 0xFF; - } - - public void writeHL(int hl) { - h = (hl >> 8) & 0xFF; - l = hl & 0xFF; - } - - public int readA() { - return a; - } - - public void writeA(int a) { - this.a = a; - } - - public int readF() { - return f; - } - - public void writeF(int f) { - this.f = f; - } - - public int readB() { - return b; - } - - public void writeB(int b) { - this.b = b; - } - - public int readC() { - return c; - } - - public void writeC(int c) { - this.c = c; - } - - public int readD() { - return d; - } - - public void writeD(int d) { - this.d = d; - } - - public int readE() { - return e; - } - - public void writeE(int e) { - this.e = e; - } - - public int readH() { - return h; - } - - public void writeH(int h) { - this.h = h; - } - - public int readL() { - return l; - } - - public void writeL(int l) { - this.l = l; - } - -} diff --git a/playing-coffee old/src/playingcoffee/core/cpu/Argument.java b/playing-coffee old/src/playingcoffee/core/cpu/Argument.java deleted file mode 100644 index 6d12ee3..0000000 --- a/playing-coffee old/src/playingcoffee/core/cpu/Argument.java +++ /dev/null @@ -1,72 +0,0 @@ -package playingcoffee.core.cpu; - -import playingcoffee.core.MMU; - -public enum Argument { - - A { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getA(); - } - - @Override - public void write(Registers registers, MMU mmu, int value) { - registers.setA(value); - } - }, B { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getB(); - } - - @Override - public void write(Registers registers, MMU mmu, int value) { - registers.setB(value); - } - }, C { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getC(); - } - - @Override - public void write(Registers registers, MMU mmu, int value) { - registers.setC(value); - } - }, D { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getD(); - } - - @Override - public void write(Registers registers, MMU mmu, int value) { - registers.setD(value); - } - }, E { - @Override - public int read(Registers registers, MMU mmu) { - return registers.getE(); - } - - @Override - public void write(Registers registers, MMU mmu, int value) { - registers.setE(value); - } - }; - - private String label; - - public abstract int read(Registers registers, MMU mmu); - public abstract void write(Registers registers, MMU mmu, int value); - - public Argument parse(String argument) { - for (Argument arg : values()) - if (arg.label.equals(argument)) - return arg; - - throw new IllegalArgumentException(String.format("Invalid argument: %s", argument)); - } - -} diff --git a/playing-coffee old/src/playingcoffee/core/cpu/Registers.java b/playing-coffee old/src/playingcoffee/core/cpu/Registers.java deleted file mode 100644 index adc77b7..0000000 --- a/playing-coffee old/src/playingcoffee/core/cpu/Registers.java +++ /dev/null @@ -1,33 +0,0 @@ -package playingcoffee.core.cpu; - -public class Registers { - - private int a, b, c, d, e, h, l; - - private int pc, sp; - - public int getA() { return a & 0xFF; } - public int getB() { return b & 0xFF; } - public int getC() { return c & 0xFF; } - public int getD() { return d & 0xFF; } - public int getE() { return e & 0xFF; } - public int getH() { return h & 0xFF; } - public int getL() { return l & 0xFF; } - - public void setA(int value) { a = value & 0xFF; } - public void setB(int value) { b = value & 0xFF; } - public void setC(int value) { c = value & 0xFF; } - public void setD(int value) { d = value & 0xFF; } - public void setE(int value) { e = value & 0xFF; } - public void setH(int value) { h = value & 0xFF; } - public void setL(int value) { l = value & 0xFF; } - - public int getPC() { return pc & 0xFFFF; } - public int getSP() { return sp & 0xFFFF; } - - public void setPC(int value) { pc = value & 0xFFFF; } - public void setSP(int value) { sp = value & 0xFFFF; } - - public void incPC(int value) { setPC(pc + value); } - public void incSP(int value) { setSP(sp + value); } -} diff --git a/playing-coffee old/src/playingcoffee/ui/CPUDebugger.java b/playing-coffee old/src/playingcoffee/ui/CPUDebugger.java deleted file mode 100644 index c9a71da..0000000 --- a/playing-coffee old/src/playingcoffee/ui/CPUDebugger.java +++ /dev/null @@ -1,158 +0,0 @@ -package playingcoffee.ui; - -import java.awt.EventQueue; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.DefaultListModel; -import javax.swing.GroupLayout; -import javax.swing.GroupLayout.Alignment; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.LayoutStyle.ComponentPlacement; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; - -import playingcoffee.core.CPU; -import playingcoffee.core.MMU; -import playingcoffee.core.Registers; - -import javax.swing.JCheckBox; - -public class CPUDebugger { - - private JFrame frmCpuDebugger; - private JList registerList; - - private JCheckBox chckbxZero; - private JCheckBox chckbxNegative; - private JCheckBox chckbxHalfCarry; - private JCheckBox chckbxCarry; - - private MMU mmu; - private CPU cpu; - - public static void main(String[] args) { - EventQueue.invokeLater(new Runnable() { - public void run() { - try { - CPUDebugger window = new CPUDebugger(); - window.frmCpuDebugger.setVisible(true); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } - - public CPUDebugger() { - initialize(); - - mmu = new MMU(); - cpu = new CPU(mmu); - - mmu.loadBootRom(); - - updateValues(); - } - - private void updateValues() { - DefaultListModel model = new DefaultListModel(); - model.addElement("AF: 0x" + Integer.toHexString(cpu.getRegisters().readAF())); - model.addElement("BC: 0x" + Integer.toHexString(cpu.getRegisters().readBC())); - model.addElement("DE: 0x" + Integer.toHexString(cpu.getRegisters().readDE())); - model.addElement("HL: 0x" + Integer.toHexString(cpu.getRegisters().readHL())); - model.addElement("PC: 0x" + Integer.toHexString(cpu.getRegisters().pc)); - model.addElement("SP: 0x" + Integer.toHexString(cpu.getRegisters().sp)); - - chckbxZero.setSelected(cpu.getRegisters().getFlag(Registers.FLAG_Z)); - chckbxNegative.setSelected(cpu.getRegisters().getFlag(Registers.FLAG_N)); - chckbxHalfCarry.setSelected(cpu.getRegisters().getFlag(Registers.FLAG_H)); - chckbxCarry.setSelected(cpu.getRegisters().getFlag(Registers.FLAG_C)); - - registerList.setModel(model); - } - - private void initialize() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException - | UnsupportedLookAndFeelException e) { - e.printStackTrace(); - } - - frmCpuDebugger = new JFrame(); - frmCpuDebugger.setTitle("CPU Debugger"); - frmCpuDebugger.setBounds(100, 100, 350, 350); - frmCpuDebugger.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - - JButton btnStep = new JButton("Step"); - btnStep.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - do { cpu.cycle(); } while (cpu.getCycles() != 0); - updateValues(); - } - }); - - JButton btnReset = new JButton("Reset"); - - JLabel lblRegisters = new JLabel("Registers:"); - - registerList = new JList(); - - chckbxZero = new JCheckBox("Zero"); - chckbxNegative = new JCheckBox("Negative"); - chckbxHalfCarry = new JCheckBox("Half Carry"); - chckbxCarry = new JCheckBox("Carry"); - - GroupLayout groupLayout = new GroupLayout(frmCpuDebugger.getContentPane()); - groupLayout.setHorizontalGroup( - groupLayout.createParallelGroup(Alignment.LEADING) - .addGroup(groupLayout.createSequentialGroup() - .addContainerGap() - .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) - .addComponent(lblRegisters) - .addComponent(btnStep) - .addComponent(registerList, GroupLayout.PREFERRED_SIZE, 148, GroupLayout.PREFERRED_SIZE)) - .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) - .addGroup(groupLayout.createSequentialGroup() - .addPreferredGap(ComponentPlacement.RELATED, 52, Short.MAX_VALUE) - .addComponent(btnReset) - .addContainerGap()) - .addGroup(groupLayout.createSequentialGroup() - .addPreferredGap(ComponentPlacement.UNRELATED) - .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) - .addComponent(chckbxZero) - .addComponent(chckbxNegative) - .addComponent(chckbxHalfCarry) - .addComponent(chckbxCarry)) - .addGap(73)))) - ); - groupLayout.setVerticalGroup( - groupLayout.createParallelGroup(Alignment.LEADING) - .addGroup(groupLayout.createSequentialGroup() - .addContainerGap() - .addComponent(lblRegisters) - .addPreferredGap(ComponentPlacement.RELATED) - .addGroup(groupLayout.createParallelGroup(Alignment.LEADING) - .addGroup(groupLayout.createSequentialGroup() - .addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE) - .addGap(51) - .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE) - .addComponent(btnReset) - .addComponent(btnStep))) - .addGroup(groupLayout.createSequentialGroup() - .addComponent(chckbxZero) - .addPreferredGap(ComponentPlacement.UNRELATED) - .addComponent(chckbxNegative) - .addPreferredGap(ComponentPlacement.UNRELATED) - .addComponent(chckbxHalfCarry) - .addPreferredGap(ComponentPlacement.UNRELATED) - .addComponent(chckbxCarry))) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); - frmCpuDebugger.getContentPane().setLayout(groupLayout); - } -} diff --git a/playing-coffee/How bugs were fixed.txt b/playing-coffee/How bugs were fixed.txt new file mode 100644 index 0000000..701259b --- /dev/null +++ b/playing-coffee/How bugs were fixed.txt @@ -0,0 +1,2 @@ +One bug was fixed by changing "value" to "result". +Loads of bugs were fixed by making "setAF" actually work, instead of setting a to f and f to a. \ No newline at end of file diff --git a/playing-coffee/gb-test-roms-master.zip b/playing-coffee/gb-test-roms-master.zip deleted file mode 100644 index b66c88f..0000000 Binary files a/playing-coffee/gb-test-roms-master.zip and /dev/null differ diff --git a/playing-coffee/log.txt b/playing-coffee/log.txt deleted file mode 100644 index 74ded37..0000000 Binary files a/playing-coffee/log.txt and /dev/null differ diff --git a/playing-coffee/roms/mooneye/daa.gb b/playing-coffee/roms/mooneye/daa.gb new file mode 100644 index 0000000..8fd2f49 Binary files /dev/null and b/playing-coffee/roms/mooneye/daa.gb differ diff --git a/playing-coffee - Copy/roms/mem_timing-2/rom_singles/02-write_timing.gb b/playing-coffee/roms/mooneye/div_write.gb similarity index 91% rename from playing-coffee - Copy/roms/mem_timing-2/rom_singles/02-write_timing.gb rename to playing-coffee/roms/mooneye/div_write.gb index e92f553..7b491c4 100644 Binary files a/playing-coffee - Copy/roms/mem_timing-2/rom_singles/02-write_timing.gb and b/playing-coffee/roms/mooneye/div_write.gb differ diff --git a/playing-coffee - Copy/roms/mem_timing-2/rom_singles/01-read_timing.gb b/playing-coffee/roms/mooneye/ie_push.gb similarity index 90% rename from playing-coffee - Copy/roms/mem_timing-2/rom_singles/01-read_timing.gb rename to playing-coffee/roms/mooneye/ie_push.gb index 660298b..2cf608e 100644 Binary files a/playing-coffee - Copy/roms/mem_timing-2/rom_singles/01-read_timing.gb and b/playing-coffee/roms/mooneye/ie_push.gb differ diff --git a/playing-coffee/roms/mooneye/rapid_toggle.gb b/playing-coffee/roms/mooneye/rapid_toggle.gb new file mode 100644 index 0000000..b082d11 Binary files /dev/null and b/playing-coffee/roms/mooneye/rapid_toggle.gb differ diff --git a/playing-coffee - Copy/roms/mem_timing-2/rom_singles/03-modify_timing.gb b/playing-coffee/roms/mooneye/reg_f.gb similarity index 90% rename from playing-coffee - Copy/roms/mem_timing-2/rom_singles/03-modify_timing.gb rename to playing-coffee/roms/mooneye/reg_f.gb index 7579c42..1d95080 100644 Binary files a/playing-coffee - Copy/roms/mem_timing-2/rom_singles/03-modify_timing.gb and b/playing-coffee/roms/mooneye/reg_f.gb differ diff --git a/playing-coffee/roms/mooneye/tim00.gb b/playing-coffee/roms/mooneye/tim00.gb new file mode 100644 index 0000000..df3e272 Binary files /dev/null and b/playing-coffee/roms/mooneye/tim00.gb differ diff --git a/playing-coffee/roms/opus5.gb b/playing-coffee/roms/opus5.gb new file mode 100644 index 0000000..a3b8028 Binary files /dev/null and b/playing-coffee/roms/opus5.gb differ diff --git a/playing-coffee/roms/pokemonblue.gb b/playing-coffee/roms/pokemonblue.gb new file mode 100644 index 0000000..f93f8f8 Binary files /dev/null and b/playing-coffee/roms/pokemonblue.gb differ diff --git a/playing-coffee/roms/supermarioland2.gb b/playing-coffee/roms/supermarioland2.gb new file mode 100644 index 0000000..9c62324 Binary files /dev/null and b/playing-coffee/roms/supermarioland2.gb differ diff --git a/playing-coffee/src/main/java/playingcoffee/application/Application.java b/playing-coffee/src/main/java/playingcoffee/application/Application.java index ea0ba15..db92c72 100644 --- a/playing-coffee/src/main/java/playingcoffee/application/Application.java +++ b/playing-coffee/src/main/java/playingcoffee/application/Application.java @@ -8,6 +8,8 @@ import java.awt.image.BufferStrategy; import javax.swing.JFrame; +import playingcoffee.core.GameBoy; + public class Application extends Canvas implements Runnable { private static final long serialVersionUID = 1L; @@ -17,10 +19,19 @@ public class Application extends Canvas implements Runnable { private GameBoy gameBoy; + private SwingJoypad joypad; + public Application() { setPreferredSize(new Dimension(320, 288)); - + setFocusable(true); + requestFocus(); + gameBoy = new GameBoy(); + + joypad = new SwingJoypad(gameBoy.getInterruptManager()); + addKeyListener(joypad); + gameBoy.setJoypad(joypad); + gameBoy.start(); } @@ -76,6 +87,12 @@ public class Application extends Canvas implements Runnable { public void run() { while (running) { renderGameBoy(); + try { + Thread.sleep(15); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } gameBoy.stop(); diff --git a/playing-coffee/src/main/java/playingcoffee/application/SwingJoypad.java b/playing-coffee/src/main/java/playingcoffee/application/SwingJoypad.java new file mode 100644 index 0000000..bcef1df --- /dev/null +++ b/playing-coffee/src/main/java/playingcoffee/application/SwingJoypad.java @@ -0,0 +1,72 @@ +package playingcoffee.application; + +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import playingcoffee.core.Joypad; +import playingcoffee.interrupt.InterruptManager; + +public class SwingJoypad extends Joypad implements KeyListener { + + public static final int BUTTON_LEFT = KeyEvent.VK_LEFT; + public static final int BUTTON_RIGHT = KeyEvent.VK_RIGHT; + public static final int BUTTON_UP = KeyEvent.VK_UP; + public static final int BUTTON_DOWN = KeyEvent.VK_DOWN; + public static final int BUTTON_A = KeyEvent.VK_Z; + public static final int BUTTON_B = KeyEvent.VK_X; + public static final int BUTTON_START = KeyEvent.VK_ENTER; + public static final int BUTTON_SELECT = KeyEvent.VK_SHIFT; + + public boolean[] keys; + + private boolean buttonSelected = false; + + public SwingJoypad(InterruptManager interruptManager) { + super(interruptManager); + + keys = new boolean[0x1000]; + } + + @Override + public void keyTyped(KeyEvent e) {} + + @Override + public void keyPressed(KeyEvent e) { + for (int i = 0; i < keys.length; i++) { + if (i == e.getKeyCode()) keys[i] = true; + } + } + + @Override + public void keyReleased(KeyEvent e) { + for (int i = 0; i < keys.length; i++) { + if (i == e.getKeyCode()) keys[i] = false; + } + } + + @Override + public int read(int address) { + int value = buttonSelected ? (1 << 5) : (1 << 4); + + if (buttonSelected) { + value |= (keys[BUTTON_START] ? 0 : 1) << 3; + value |= (keys[BUTTON_SELECT] ? 0 : 1) << 2; + value |= (keys[BUTTON_B] ? 0 : 1) << 1; + value |= (keys[BUTTON_A] ? 0 : 1) << 0; + } else { + value |= (keys[BUTTON_DOWN] ? 0 : 1) << 3; + value |= (keys[BUTTON_UP] ? 0 : 1) << 2; + value |= (keys[BUTTON_LEFT] ? 0 : 1) << 1; + value |= (keys[BUTTON_RIGHT] ? 0 : 1) << 0; + } + + return value; + } + + @Override + public void write(int value, int address) { + if ((value & 0x30) != 0) { + buttonSelected = (value & 0x20) == 0; + } + } +} diff --git a/playing-coffee/src/main/java/playingcoffee/cartridge/MBC1.java b/playing-coffee/src/main/java/playingcoffee/cartridge/MBC1.java index 43e1230..6263a8a 100644 --- a/playing-coffee/src/main/java/playingcoffee/cartridge/MBC1.java +++ b/playing-coffee/src/main/java/playingcoffee/cartridge/MBC1.java @@ -36,5 +36,13 @@ public class MBC1 extends MBC { return address >= 0x0000 && address <= 0x7FFF; } + public boolean isRAM() { + return ram; + } + + public boolean isBattery() { + return battery; + } + } diff --git a/playing-coffee/src/main/java/playingcoffee/cartridge/ROMOnlyMBC.java b/playing-coffee/src/main/java/playingcoffee/cartridge/ROMOnlyMBC.java index 13181ea..2ca97dd 100644 --- a/playing-coffee/src/main/java/playingcoffee/cartridge/ROMOnlyMBC.java +++ b/playing-coffee/src/main/java/playingcoffee/cartridge/ROMOnlyMBC.java @@ -1,7 +1,5 @@ package playingcoffee.cartridge; -import playingcoffee.log.Log; - public class ROMOnlyMBC extends MBC { protected ROMOnlyMBC(int[] rom) { @@ -16,7 +14,7 @@ public class ROMOnlyMBC extends MBC { @Override public void write(int value, int address) { // Don't do anything - Log.warn("Attempting to write to rom at address: 0x%4x.", address); + //Log.warn("Attempting to write to rom at address: 0x%4x.", address); } @Override diff --git a/playing-coffee/src/main/java/playingcoffee/application/GameBoy.java b/playing-coffee/src/main/java/playingcoffee/core/GameBoy.java similarity index 73% rename from playing-coffee/src/main/java/playingcoffee/application/GameBoy.java rename to playing-coffee/src/main/java/playingcoffee/core/GameBoy.java index 6579928..60a3d7a 100644 --- a/playing-coffee/src/main/java/playingcoffee/application/GameBoy.java +++ b/playing-coffee/src/main/java/playingcoffee/core/GameBoy.java @@ -1,9 +1,9 @@ -package playingcoffee.application; +package playingcoffee.core; import playingcoffee.cartridge.Cartridge; -import playingcoffee.core.InterruptManager; -import playingcoffee.core.MMU; import playingcoffee.core.cpu.CPU; +import playingcoffee.interrupt.InterruptManager; +import playingcoffee.interrupt.Timer; import playingcoffee.log.Log; import playingcoffee.ppu.PPU; @@ -14,20 +14,27 @@ public class GameBoy implements Runnable { private InterruptManager interruptManager; private PPU ppu; - private MMU mmu; private CPU cpu; - + private MMU mmu; + private Timer timer; + public GameBoy() { interruptManager = new InterruptManager(); mmu = new MMU(); ppu = new PPU(mmu, interruptManager); cpu = new CPU(mmu, interruptManager); + timer = new Timer(interruptManager); } public void init() { mmu.connectMemorySpace(interruptManager); - mmu.connectMemorySpace(new Cartridge("roms/drmario.gb").getMBC()); + mmu.connectMemorySpace(new Cartridge("roms/cpu_instrs.gb").getMBC()); + mmu.connectMemorySpace(timer); + } + + public void setJoypad(Joypad joypad) { + mmu.connectMemorySpace(joypad); } public void start() { @@ -60,7 +67,8 @@ public class GameBoy implements Runnable { for (int i = 0; i < 8192; i++) { cpu.clock(); ppu.clock(); - interruptManager.clock(); + //interruptManager.clock(); + //timer.clock(); if (mmu.read(0xFF02) == 0x81) { System.out.print((char)mmu.read(0xFF01)); @@ -71,7 +79,6 @@ public class GameBoy implements Runnable { try { Thread.sleep(1); } catch (InterruptedException e) { - // TODO Auto-generated catch block e.printStackTrace(); } } @@ -90,5 +97,9 @@ public class GameBoy implements Runnable { public CPU getCPU() { return cpu; } + + public InterruptManager getInterruptManager() { + return interruptManager; + } } diff --git a/playing-coffee/src/main/java/playingcoffee/core/InterruptManager.java b/playing-coffee/src/main/java/playingcoffee/core/InterruptManager.java deleted file mode 100644 index 5bd5d61..0000000 --- a/playing-coffee/src/main/java/playingcoffee/core/InterruptManager.java +++ /dev/null @@ -1,76 +0,0 @@ -package playingcoffee.core; - -import java.util.ArrayList; -import java.util.List; - -public class InterruptManager implements MemorySpace { - - private boolean enabled; - - private int interruptEnable; - private int interruptFlag; - - private List listeners; - - public static final int VBLANK = 1 << 0; - public static final int LCD_STAT = 1 << 1; - public static final int TIMER = 1 << 2; - public static final int SERIAL = 1 << 3; - public static final int JOYPAD = 1 << 4; - - public InterruptManager() { - listeners = new ArrayList(); - } - - public void addListener(InterruptListener listener) { - listeners.add(listener); - } - - public void enable() { enabled = true; } - public void disable() { enabled = false; } - - public boolean isEnabled() { return enabled; } - - public void requestInterrupt(int type) { - interruptFlag |= type; - } - - public void clock() { - if (enabled) { - int toOccur = interruptFlag & interruptEnable; - - //System.out.println(toOccur); - - if (toOccur != 0) { - for (int i = 0; i < 8; i++) { - if ((toOccur & (1 << i)) != 0) { - for (InterruptListener listener : listeners) { - listener.interruptOccured(1 << i); - } - interruptFlag &= ~(1 << i); - } - } - } - } - } - - @Override - public int read(int address) { - if (address == 0xFFFF) return interruptEnable; - if (address == 0xFF0F) return interruptFlag; - - return 0; - } - - @Override - public void write(int value, int address) { - if (address == 0xFFFF) interruptEnable = value; - if (address == 0xFF0F) interruptFlag = value; - } - - @Override - public boolean inMemorySpace(int address) { - return address == 0xFFFF || address == 0xFF0F; - } - -} diff --git a/playing-coffee/src/main/java/playingcoffee/core/Joypad.java b/playing-coffee/src/main/java/playingcoffee/core/Joypad.java new file mode 100644 index 0000000..4f85ffc --- /dev/null +++ b/playing-coffee/src/main/java/playingcoffee/core/Joypad.java @@ -0,0 +1,17 @@ +package playingcoffee.core; + +import playingcoffee.interrupt.InterruptManager; + +public abstract class Joypad implements MemorySpace { + + protected final InterruptManager interruptManager; + + protected Joypad(final InterruptManager interruptManager) { + this.interruptManager = interruptManager; + } + + @Override + public boolean inMemorySpace(int address) { + return address == 0xFF00; + } +} diff --git a/playing-coffee/src/main/java/playingcoffee/core/MMU.java b/playing-coffee/src/main/java/playingcoffee/core/MMU.java index 025db43..af34bd8 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/MMU.java +++ b/playing-coffee/src/main/java/playingcoffee/core/MMU.java @@ -61,8 +61,6 @@ public class MMU { } public int read(int address) { - if (address == 0xFF00) return 0xFF; // TODO: Remove - if (address >= 0x00 && address <= 0xFF && read(0xFF50) == 0) return bootRom[address]; @@ -76,8 +74,6 @@ public class MMU { } public void write(int value, int address) { - if (address == 0xFF00) return; // TODO: Remove - if (address >= 0x00 && address <= 0xFF && read(0xFF50) == 0) bootRom[address] = value & 0xFF; diff --git a/playing-coffee/src/main/java/playingcoffee/core/cpu/CPU.java b/playing-coffee/src/main/java/playingcoffee/core/cpu/CPU.java index 7b65a18..b885542 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/cpu/CPU.java +++ b/playing-coffee/src/main/java/playingcoffee/core/cpu/CPU.java @@ -4,13 +4,12 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; -import playingcoffee.core.InterruptListener; -import playingcoffee.core.InterruptManager; import playingcoffee.core.MMU; import playingcoffee.core.opcode.ALU16Opcode; import playingcoffee.core.opcode.ALU16Opcode.ALU16Type; import playingcoffee.core.opcode.ALUOpcode; import playingcoffee.core.opcode.ALUOpcode.ALUType; +import playingcoffee.core.opcode.AddSPI8Opcode; import playingcoffee.core.opcode.Argument; import playingcoffee.core.opcode.BCDOpcode; import playingcoffee.core.opcode.CallOpcode; @@ -34,6 +33,8 @@ import playingcoffee.core.opcode.prefixed.RotateOpcode; import playingcoffee.core.opcode.prefixed.SetBitOpcode; import playingcoffee.core.opcode.prefixed.ShiftOpcode; import playingcoffee.core.opcode.prefixed.ShiftOpcode.ShiftType; +import playingcoffee.interrupt.InterruptListener; +import playingcoffee.interrupt.InterruptManager; import playingcoffee.core.opcode.prefixed.SwapOpcode; import playingcoffee.log.Log; @@ -110,6 +111,7 @@ public class CPU implements InterruptListener { } opcodes[0x08] = new LoadOpcode(Argument.SP, Argument._D16_SHORT); + opcodes[0xF8] = new LoadOpcode(Argument.SP_I8, Argument.HL); opcodes[0xE0] = new LoadOpcode(Argument.A, Argument._D8); opcodes[0xF0] = new LoadOpcode(Argument._D8, Argument.A); @@ -182,6 +184,7 @@ public class CPU implements InterruptListener { for (Entry val : indexedList(0x09, 0x10, Argument.BC, Argument.DE,Argument.HL, Argument.SP)) { opcodes[val.getKey()] = new ALU16Opcode(ALU16Type.ADD, val.getValue()); } + opcodes[0xE8] = new AddSPI8Opcode(); // ALU Opcodes for (Entry val : indexedList(0x04, 8, Argument.B, Argument.C, Argument.D, Argument.E, Argument.H, Argument.L, Argument._HL, Argument.A)) { @@ -276,10 +279,6 @@ public class CPU implements InterruptListener { if (cycles == 0) { //Log.info("PC: 0x%4x", registers.getPC()); - if (registers.getPC() == 0x02cd) { - Log.info("Breakpoint."); - } - int opcodeValue = mmu.read(registers.getPC()); registers.incPC(); @@ -308,7 +307,7 @@ public class CPU implements InterruptListener { throw new IllegalStateException(); } - //Log.info("Executing opcode: 0x%2x (%s)", opcodeValue, opcode.toString()); + Log.info("Executing opcode: 0x%2x (%s) at 0x%4x", opcodeValue, opcode.toString(), registers.getPC()); cycles += opcode.run(registers, mmu) + 4; // Adding 4 because we fetch the instruction. } @@ -323,7 +322,7 @@ public class CPU implements InterruptListener { throw new IllegalStateException(); } - //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. } @@ -340,15 +339,25 @@ public class CPU implements InterruptListener { if ((types & InterruptManager.VBLANK) != 0) { interruptManager.disable(); lowPowerMode = false; - mmu.pushStack(registers.getPC(), registers); - - Log.info("Pushing 0x%4x to the stack.", registers.getPC()); - Log.info("Firing V-Blank"); - - registers.setPC(0x40); - cycles += 12; + registers.setPC(0x40); + } + + if ((types & InterruptManager.LCD_STAT) != 0) { + interruptManager.disable(); + lowPowerMode = false; + mmu.pushStack(registers.getPC(), registers); + cycles += 12; + registers.setPC(0x48); + } + + if ((types & InterruptManager.TIMER) != 0) { + interruptManager.disable(); + lowPowerMode = false; + mmu.pushStack(registers.getPC(), registers); + cycles += 12; + registers.setPC(0x50); } } diff --git a/playing-coffee/src/main/java/playingcoffee/core/cpu/Flags.java b/playing-coffee/src/main/java/playingcoffee/core/cpu/Flags.java index c4e121a..87caf82 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/cpu/Flags.java +++ b/playing-coffee/src/main/java/playingcoffee/core/cpu/Flags.java @@ -10,7 +10,7 @@ public class Flags { public static final int CARRY = 1 << 4; public void set(int value) { - f = value & 0xFF; + f = value & 0xF0; } public int get() { diff --git a/playing-coffee/src/main/java/playingcoffee/core/cpu/Registers.java b/playing-coffee/src/main/java/playingcoffee/core/cpu/Registers.java index 82c97f6..9a22287 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/cpu/Registers.java +++ b/playing-coffee/src/main/java/playingcoffee/core/cpu/Registers.java @@ -38,7 +38,7 @@ public class Registers { public int getPC() { return pc; } public int getSP() { return sp; } - public void setAF(int value) { flags.set(value >> 8); setA(value); } + public void setAF(int value) { setA(value >> 8); flags.set(value); } public void setBC(int value) { setB(value >> 8); setC(value); } public void setDE(int value) { setD(value >> 8); setE(value); } public void setHL(int value) { setH(value >> 8); setL(value); } diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/ALU16Opcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/ALU16Opcode.java index 7fb2f4a..bface08 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/ALU16Opcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/ALU16Opcode.java @@ -22,27 +22,38 @@ public class ALU16Opcode implements Opcode { switch (type) { case INC: register.write(register.read(registers, mmu) + 1, registers, mmu); - break; + return 4; case DEC: register.write(register.read(registers, mmu) - 1, registers, mmu); - break; + return 4; case ADD: int value = register.read(registers, mmu); result = registers.getHL() + value; registers.getFlags().set(Flags.NEGATIVE, false); - registers.getFlags().set(Flags.HALF_CARRY, ((value & 0xF0) + (registers.getHL() & 0xF0) > 0xF0)); + registers.getFlags().set(Flags.HALF_CARRY, ((value & 0xFFF) + (registers.getHL() & 0xFFF) > 0xFFF)); registers.getFlags().set(Flags.CARRY, (result & 0xFFFF0000) != 0); registers.setHL(result); - break; + return 4; + /*case ADD_SP_I8: + value = register.read(registers, mmu); + result = registers.getSP() + value; + + registers.getFlags().set(Flags.ZERO | Flags.NEGATIVE, false); + registers.getFlags().set(Flags.HALF_CARRY, ((registers.getSP() ^ value ^ result) & 0x100) == 0x100); + registers.getFlags().set(Flags.CARRY, ((registers.getSP() ^ value ^ result) & 0x10) == 0x10); + + registers.setSP(result); + + return 12;*/ default: Log.error("wtf!? how did we get here?!?!?"); break; } - return register.getCycles() * (type == ALU16Type.ADD ? 1 : 2); + throw new IllegalArgumentException("Invalid type"); } public enum ALU16Type { diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/ALUOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/ALUOpcode.java index 9f079e7..4cf9cb8 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/ALUOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/ALUOpcode.java @@ -31,13 +31,14 @@ public class ALUOpcode implements Opcode { break; case ADC: // NOTE: Tetris does not use this opcode. - int value = registerValue + (registers.getFlags().get(Flags.CARRY) ? 1 : 0); + int carry = (registers.getFlags().get(Flags.CARRY) ? 1 : 0); + int value = registerValue; - result = registers.getA() + value; + result = registers.getA() + value + carry; registers.getFlags().set(Flags.ZERO, (result & 0xFF) == 0); - registers.getFlags().set(Flags.NEGATIVE, false); - registers.getFlags().set(Flags.HALF_CARRY, (registers.getA() & 0xF) + (value & 0xF) > 0xF); + registers.getFlags().set(Flags.NEGATIVE, false); // Cinoop sets this to true? + registers.getFlags().set(Flags.HALF_CARRY, (registers.getA() & 0xF) + (registerValue & 0xF) + carry > 0xF); registers.getFlags().set(Flags.CARRY, (result & 0xFF00) > 0); break; @@ -65,15 +66,16 @@ public class ALUOpcode implements Opcode { break; case SBC: // NOTE: Tetris does not use this opcode. - value = registerValue + (registers.getFlags().get(Flags.CARRY) ? 1 : 0); + carry = (registers.getFlags().get(Flags.CARRY) ? 1 : 0); + value = registerValue; - registers.getFlags().set(Flags.ZERO, value == registers.getA()); + result = registers.getA() - value - carry; + + registers.getFlags().set(Flags.ZERO, (result & 0xFF) == 0); registers.getFlags().set(Flags.NEGATIVE, true); - registers.getFlags().set(Flags.HALF_CARRY, (value & 0xF) > (registers.getA() & 0xF)); - registers.getFlags().set(Flags.CARRY, value > registers.getA()); - - result = registers.getA() - value; - + registers.getFlags().set(Flags.HALF_CARRY, (registers.getA() & 0xF) - (value & 0xF) - carry < 0); + registers.getFlags().set(Flags.CARRY, result < 0); + break; case SUB: registers.getFlags().set(Flags.ZERO, registerValue == registers.getA()); @@ -99,7 +101,7 @@ public class ALUOpcode implements Opcode { registers.getFlags().set(Flags.HALF_CARRY, (result & 0x10) != 0); register.write(result, registers, mmu); - break; + return register.getCycles() * 2; case DEC: result = registerValue - 1; @@ -108,7 +110,7 @@ public class ALUOpcode implements Opcode { registers.getFlags().set(Flags.HALF_CARRY, (registerValue & 0x0F) == 0x0F); register.write(result, registers, mmu); - break; + return register.getCycles() * 2; default: Log.error("wtf!? how did we get here?!?!?"); break; @@ -117,7 +119,7 @@ public class ALUOpcode implements Opcode { if (type != ALUType.INC && type != ALUType.DEC && type != ALUType.CP) registers.setA(result); - return 0; + return register.getCycles(); } public enum ALUType { diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/AddSPI8Opcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/AddSPI8Opcode.java new file mode 100644 index 0000000..6d4676a --- /dev/null +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/AddSPI8Opcode.java @@ -0,0 +1,25 @@ +package playingcoffee.core.opcode; + +import playingcoffee.core.MMU; +import playingcoffee.core.cpu.Flags; +import playingcoffee.core.cpu.Registers; + +public class AddSPI8Opcode implements Opcode { + + @Override + public int run(Registers registers, MMU mmu) { + int value = Argument.I8.read(registers, mmu); + int result = value + registers.getSP(); + + registers.getFlags().set(Flags.ZERO | Flags.NEGATIVE, false); + registers.getFlags().set(Flags.HALF_CARRY, ((registers.getSP() ^ value ^ result) & 0x10) == 0x10); + registers.getFlags().set(Flags.CARRY, ((registers.getSP() ^ value ^ result) & 0x100) == 0x100); + + registers.setSP(result); + + return 12; + } + + + +} diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/Argument.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/Argument.java index 6250bad..ce5585c 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/Argument.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/Argument.java @@ -1,6 +1,7 @@ package playingcoffee.core.opcode; import playingcoffee.core.MMU; +import playingcoffee.core.cpu.Flags; import playingcoffee.core.cpu.Registers; import playingcoffee.log.Log; @@ -299,7 +300,7 @@ public enum Argument { registers.incPC(); - return (mmu.read(address) << 8) | mmu.read(address); + return (mmu.read(address + 1) << 8) | mmu.read(address); } @Override @@ -312,9 +313,31 @@ public enum Argument { registers.incPC(); - mmu.write(value >> 8, address); - mmu.write(value, address + 1); + mmu.write(value >> 8, address + 1); + mmu.write(value, address); } + }, SP_I8(8) { + + @Override + public int read(Registers registers, MMU mmu) { + int relativeAddress = (byte) mmu.read(registers.getPC()); + + registers.incPC(); + + int returnValue = registers.getSP() + relativeAddress; + + registers.getFlags().set(Flags.ZERO | Flags.NEGATIVE, false); + registers.getFlags().set(Flags.HALF_CARRY, ((registers.getSP() ^ relativeAddress ^ returnValue) & 0x10) == 0x10); + registers.getFlags().set(Flags.CARRY, ((registers.getSP() ^ relativeAddress ^ returnValue) & 0x100) == 0x100); + + return returnValue; + } + + @Override + public void write(int value, Registers registers, MMU mmu) { + Log.error("Why are you writing to this argument?"); + } + }; private String name; diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/BCDOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/BCDOpcode.java index 6dc768c..9cfd3e7 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/BCDOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/BCDOpcode.java @@ -6,11 +6,13 @@ import playingcoffee.core.cpu.Registers; public class BCDOpcode implements Opcode { + // NOTE: Tetris does not use this opcode. + @Override public int run(Registers registers, MMU mmu) { // TODO: Learn what this opcode actually does. - int s = registers.getA(); + /*int s = registers.getA(); if (registers.getFlags().get(Flags.NEGATIVE)) { if (registers.getFlags().get(Flags.HALF_CARRY)) s = (s - 0x06) & 0xFF; @@ -24,7 +26,23 @@ public class BCDOpcode implements Opcode { registers.getFlags().set(Flags.ZERO, registers.getA() == 0); registers.getFlags().set(Flags.HALF_CARRY, false); - registers.getFlags().set(Flags.CARRY, s >= 0x100); + registers.getFlags().set(Flags.CARRY, s >= 0x100);*/ + + if (registers.getFlags().get(Flags.NEGATIVE)) { + if (registers.getFlags().get(Flags.CARRY)) registers.setA(registers.getA() - 0x60); + if (registers.getFlags().get(Flags.HALF_CARRY)) registers.setA(registers.getA() - 0x6); + } else { + if (registers.getFlags().get(Flags.CARRY) || registers.getA() > 0x99) { + registers.setA(registers.getA() + 0x60); + registers.getFlags().set(Flags.CARRY, true); + } + if (registers.getFlags().get(Flags.HALF_CARRY) || (registers.getA() & 0x0F) > 0x09) { + registers.setA(registers.getA() + 0x06); + } + } + + registers.getFlags().set(Flags.ZERO, registers.getA() == 0); + registers.getFlags().set(Flags.HALF_CARRY, false); return 0; } diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/CallOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/CallOpcode.java index d28dc0f..b8a97dc 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/CallOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/CallOpcode.java @@ -3,7 +3,6 @@ package playingcoffee.core.opcode; import playingcoffee.core.MMU; import playingcoffee.core.cpu.Flags; import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; public class CallOpcode implements Opcode { @@ -28,7 +27,7 @@ public class CallOpcode implements Opcode { if (canExecute(registers)) { mmu.pushStack(registers.getPC(), registers); - Log.info("Pushing 0x%4x to the stack.", registers.getPC()); + //Log.info("Pushing 0x%4x to the stack.", registers.getPC()); registers.setPC(addressToJump); @@ -51,7 +50,7 @@ public class CallOpcode implements Opcode { case Flags.CARRY: flag = 'C'; break; } - return "CALL " + (not ? "" : "N") + flag + ", " + address.getName(); + return "CALL " + (not ? "N" : "") + flag + ", " + address.getName(); } } diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/InterruptOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/InterruptOpcode.java index 9c398f6..3d48ab4 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/InterruptOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/InterruptOpcode.java @@ -1,8 +1,8 @@ package playingcoffee.core.opcode; -import playingcoffee.core.InterruptManager; import playingcoffee.core.MMU; import playingcoffee.core.cpu.Registers; +import playingcoffee.interrupt.InterruptManager; public class InterruptOpcode implements Opcode { diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/JumpOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/JumpOpcode.java index 5444f41..59629f0 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/JumpOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/JumpOpcode.java @@ -45,6 +45,6 @@ public class JumpOpcode implements Opcode { case Flags.CARRY: flag = 'C'; break; } - return "JP " + (not ? "" : "N") + flag + ", " + address.getName(); + return "JP " + (not ? "N" : "") + flag + ", " + address.getName(); } } diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/JumpRelativeOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/JumpRelativeOpcode.java index 3a804a8..aae2db9 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/JumpRelativeOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/JumpRelativeOpcode.java @@ -46,6 +46,6 @@ public class JumpRelativeOpcode implements Opcode { case Flags.CARRY: flag = 'C'; break; } - return "JR " + (not ? "" : "N") + flag + ", " + address.getName(); + return "JR " + (not ? "N" : "") + flag + ", " + address.getName(); } } diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/PopOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/PopOpcode.java index d4fe93f..4ea2c89 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/PopOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/PopOpcode.java @@ -2,7 +2,6 @@ package playingcoffee.core.opcode; import playingcoffee.core.MMU; import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; public class PopOpcode implements Opcode { @@ -18,7 +17,7 @@ public class PopOpcode implements Opcode { register.write(value, registers, mmu); - Log.info("Popping 0x%4x from the stack.", value); + //Log.info("Popping 0x%4x from the stack.", value); return 8; } diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/PushOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/PushOpcode.java index 5e65d5a..fbd31d7 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/PushOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/PushOpcode.java @@ -2,7 +2,6 @@ package playingcoffee.core.opcode; import playingcoffee.core.MMU; import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; public class PushOpcode implements Opcode { @@ -18,7 +17,7 @@ public class PushOpcode implements Opcode { mmu.pushStack(value, registers); - Log.info("Pushing 0x%4x to the stack.", value); + //Log.info("Pushing 0x%4x to the stack.", value); return 8; } diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/ReturnOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/ReturnOpcode.java index c729800..165323a 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/ReturnOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/ReturnOpcode.java @@ -1,10 +1,9 @@ package playingcoffee.core.opcode; -import playingcoffee.core.InterruptManager; import playingcoffee.core.MMU; import playingcoffee.core.cpu.Flags; import playingcoffee.core.cpu.Registers; -import playingcoffee.log.Log; +import playingcoffee.interrupt.InterruptManager; public class ReturnOpcode implements Opcode { @@ -26,10 +25,21 @@ public class ReturnOpcode implements Opcode { } @Override - public int run(Registers registers, MMU mmu) { + public int run(Registers registers, MMU mmu) { + if (conditionFlag == 0) { + int addressToJump = mmu.popStack(registers); + registers.setPC(addressToJump); + + if (fromInterupt) { + interruptManager.enable(); + } + + return 12; + } + 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); diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/RotateAOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/RotateAOpcode.java index b786019..a203321 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/RotateAOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/RotateAOpcode.java @@ -22,7 +22,7 @@ public class RotateAOpcode implements Opcode { if (direction == LEFT) { if (withCarry) { // NOTE: Tetris does not use this opcode. int value = registers.getA(); - int result = (value << 1) | ((value >> 7) & 1); + int result = (value << 1) | ((value & 0x80) >> 7); registers.getFlags().set(Flags.ZERO | Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0); @@ -48,7 +48,7 @@ public class RotateAOpcode implements Opcode { registers.setA(result); } else { // NOTE: Tetris does not use this opcode. 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) ? 0x80 : 0)); registers.getFlags().set(Flags.ZERO | Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.CARRY, (value & 1) != 0); diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/StopOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/StopOpcode.java index 7fa9804..b9b50ca 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/StopOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/StopOpcode.java @@ -6,6 +6,8 @@ import playingcoffee.core.cpu.Registers; public class StopOpcode implements Opcode { + // NOTE: Tetris does not use this opcode. + private CPU cpu; public StopOpcode(CPU cpu) { diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/prefixed/RotateOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/prefixed/RotateOpcode.java index 27f7572..33710e6 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/prefixed/RotateOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/prefixed/RotateOpcode.java @@ -33,7 +33,7 @@ public class RotateOpcode implements Opcode { register.write(result, registers, mmu);*/ - if (withCarry) { + if (withCarry) { // NOTE: Tetris does not use this opcode. int value = register.read(registers, mmu); int result = (value << 1) | ((value >> 7) & 1); @@ -54,14 +54,34 @@ public class RotateOpcode implements Opcode { } } 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); registers.getFlags().set(Flags.ZERO, result == 0); registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.CARRY, (value & 1) != 0); - register.write(result, registers, mmu); + register.write(result, registers, mmu);*/ + + if (withCarry) { // NOTE: Tetris does not use this opcode. + int value = register.read(registers, mmu); + int result = (value >> 1) | ((value & 0x1) << 7); + + registers.getFlags().set(Flags.ZERO, result == 0); + registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); + registers.getFlags().set(Flags.CARRY, (value & 0x1) != 0); // NOTE: Cinoop has result & 0x1 instead. + + register.write(result, registers, mmu); + } else { // NOTE: Tetris does not use this opcode. + int value = register.read(registers, mmu); + int result = (value >> 1) | (registers.getFlags().get(Flags.CARRY) ? 0x80 : 0); + + registers.getFlags().set(Flags.ZERO, result == 0); + registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); + registers.getFlags().set(Flags.CARRY, (value & 0x1) != 0); // NOTE: Cinoop has result & 0x1 instead. + + register.write(result, registers, mmu); + } } return register.getCycles(); diff --git a/playing-coffee/src/main/java/playingcoffee/core/opcode/prefixed/ShiftOpcode.java b/playing-coffee/src/main/java/playingcoffee/core/opcode/prefixed/ShiftOpcode.java index c8a3e27..5d61648 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/opcode/prefixed/ShiftOpcode.java +++ b/playing-coffee/src/main/java/playingcoffee/core/opcode/prefixed/ShiftOpcode.java @@ -20,14 +20,12 @@ public class ShiftOpcode implements Opcode { SLA, SRA, SRL } - // NOTE: Tetris does not use these opcodes. - @Override public int run(Registers registers, MMU mmu) { - int value, result; + int value, result = 0; switch (type) { - case SLA: + case SLA: value = register.read(registers, mmu); result = value << 1; @@ -35,7 +33,7 @@ public class ShiftOpcode implements Opcode { registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.CARRY, (value & 0x80) != 0); break; - case SRA: + case SRA: // NOTE: Tetris does not use this opcode. value = register.read(registers, mmu); result = (value >> 1) | (value & 0x80); @@ -43,9 +41,9 @@ public class ShiftOpcode implements Opcode { registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); registers.getFlags().set(Flags.CARRY, (value & 0x1) != 0); break; - case SRL: + case SRL: // NOTE: Tetris does not use this opcode. value = register.read(registers, mmu); - result = (value >> 1) | ((value << 7) & 0x80); + result = (value >> 1); registers.getFlags().set(Flags.ZERO, result == 0); registers.getFlags().set(Flags.NEGATIVE | Flags.HALF_CARRY, false); @@ -53,6 +51,8 @@ public class ShiftOpcode implements Opcode { break; } + register.write(result, registers, mmu); + return register.getCycles() * 2; } diff --git a/playing-coffee/src/main/java/playingcoffee/core/InterruptListener.java b/playing-coffee/src/main/java/playingcoffee/interrupt/InterruptListener.java similarity index 71% rename from playing-coffee/src/main/java/playingcoffee/core/InterruptListener.java rename to playing-coffee/src/main/java/playingcoffee/interrupt/InterruptListener.java index 088c107..819d0de 100644 --- a/playing-coffee/src/main/java/playingcoffee/core/InterruptListener.java +++ b/playing-coffee/src/main/java/playingcoffee/interrupt/InterruptListener.java @@ -1,4 +1,4 @@ -package playingcoffee.core; +package playingcoffee.interrupt; public interface InterruptListener { diff --git a/playing-coffee - Copy/src/main/java/playingcoffee/core/InterruptManager.java b/playing-coffee/src/main/java/playingcoffee/interrupt/InterruptManager.java similarity index 79% rename from playing-coffee - Copy/src/main/java/playingcoffee/core/InterruptManager.java rename to playing-coffee/src/main/java/playingcoffee/interrupt/InterruptManager.java index 5bd5d61..cce18e6 100644 --- a/playing-coffee - Copy/src/main/java/playingcoffee/core/InterruptManager.java +++ b/playing-coffee/src/main/java/playingcoffee/interrupt/InterruptManager.java @@ -1,11 +1,14 @@ -package playingcoffee.core; +package playingcoffee.interrupt; import java.util.ArrayList; import java.util.List; +import playingcoffee.core.MemorySpace; + public class InterruptManager implements MemorySpace { private boolean enabled; + private int scheduleEnable; private int interruptEnable; private int interruptFlag; @@ -26,8 +29,8 @@ public class InterruptManager implements MemorySpace { listeners.add(listener); } - public void enable() { enabled = true; } - public void disable() { enabled = false; } + public void enable() { scheduleEnable = 4; } + public void disable() { scheduleEnable = -4; } public boolean isEnabled() { return enabled; } @@ -36,6 +39,15 @@ public class InterruptManager implements MemorySpace { } public void clock() { + if (scheduleEnable > 0) { + scheduleEnable--; + if (scheduleEnable == 0) enabled = true; + } + if (scheduleEnable < 0) { + scheduleEnable++; + if (scheduleEnable == 0) enabled = false; + } + if (enabled) { int toOccur = interruptFlag & interruptEnable; diff --git a/playing-coffee/src/main/java/playingcoffee/interrupt/Timer.java b/playing-coffee/src/main/java/playingcoffee/interrupt/Timer.java new file mode 100644 index 0000000..15428e0 --- /dev/null +++ b/playing-coffee/src/main/java/playingcoffee/interrupt/Timer.java @@ -0,0 +1,76 @@ +package playingcoffee.interrupt; + +import playingcoffee.core.MemorySpace; + +public class Timer implements MemorySpace { + + private final InterruptManager interruptManager; + + private int dividerRegister; + private int timerCounter; + private int timerModulo; + private int timerControl; + + private int dividerClockCount; + private int timerClockCount; + + public Timer(final InterruptManager interruptManager) { + this.interruptManager = interruptManager; + } + + public void clock() { + if (dividerClockCount % 256 == 0) { + dividerRegister = (dividerRegister + 1) & 0xFF; + } + + dividerClockCount++; + + if ((timerControl & 0x4) != 0) { + int timerMod = 0; + + switch (timerControl & 0x3) { + case 0x00: timerMod = 1024; break; + case 0x01: timerMod = 16; break; + case 0x02: timerMod = 64; break; + case 0x03: timerMod = 256; break; + } + + if (timerClockCount % timerMod == 0) { + timerCounter++; + if (timerCounter > 0xFF) { + timerCounter = timerModulo; + interruptManager.requestInterrupt(InterruptManager.TIMER); + } + } + timerClockCount++; + } + } + + @Override + public int read(int address) { + switch (address) { + case 0xFF04: return dividerRegister; + case 0xFF05: return timerCounter; + case 0xFF06: return timerModulo; + case 0xFF07: return timerControl; + } + + return 0; + } + + @Override + public void write(int value, int address) { + switch (address) { + case 0xFF04: dividerRegister = 0; return; + case 0xFF05: timerCounter = value; return; + case 0xFF06: timerModulo = value; return; + case 0xFF07: timerControl = value; return; + } + } + + @Override + public boolean inMemorySpace(int address) { + return address >= 0xFF04 && address <= 0xFF07; + } + +} diff --git a/playing-coffee/src/main/java/playingcoffee/ppu/FIFOPixel.java b/playing-coffee/src/main/java/playingcoffee/ppu/FIFOPixel.java new file mode 100644 index 0000000..d6ab39d --- /dev/null +++ b/playing-coffee/src/main/java/playingcoffee/ppu/FIFOPixel.java @@ -0,0 +1,87 @@ +package playingcoffee.ppu; + +public class FIFOPixel { + + private int color; + private int palette; + private int spritePriority; + private int backgroundPriority; + + public FIFOPixel() { + this(0, 0, 0, 0); + } + + public FIFOPixel(int color, int palette, int spritePriority, int backgroundPriority) { + this.color = color; + this.palette = palette; + this.spritePriority = spritePriority; + this.backgroundPriority = backgroundPriority; + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } + + public int getPalette() { + return palette; + } + + public void setPalette(int palette) { + this.palette = palette; + } + + public int getSpritePriority() { + return spritePriority; + } + + public void setSpritePriority(int spritePriority) { + this.spritePriority = spritePriority; + } + + public int getBackgroundPriority() { + return backgroundPriority; + } + + public void setBackgroundPriority(int backgroundPriority) { + this.backgroundPriority = backgroundPriority; + } + + + + /*private int colorIndex; + private int source; + + public static final int BACKGROUND = 0; + public static final int SPRITE0 = 1; + public static final int SPRITE1 = 2; + + public FIFOPixel() { + this(0, 0); + } + + public FIFOPixel(int colorIndex, int source) { + this.colorIndex = colorIndex; + this.source = source; + } + + public int getColorIndex() { + return colorIndex; + } + + public void setColorIndex(int colorIndex) { + this.colorIndex = colorIndex; + } + + public int getSource() { + return source; + } + + public void setSource(int source) { + this.source = source; + }*/ + +} diff --git a/playing-coffee/src/main/java/playingcoffee/ppu/FIFOPixelFetcher.java b/playing-coffee/src/main/java/playingcoffee/ppu/FIFOPixelFetcher.java new file mode 100644 index 0000000..fcbcd40 --- /dev/null +++ b/playing-coffee/src/main/java/playingcoffee/ppu/FIFOPixelFetcher.java @@ -0,0 +1,57 @@ +package playingcoffee.ppu; + +public class FIFOPixelFetcher { + + private int mode; + + public static final int GET_TILE = 0; + public static final int GET_TILE_LOW = 1; + public static final int GET_TILE_HIGH = 2; + public static final int SLEEP = 3; + public static final int PUSH = 4; + + private final PixelFIFO pixelFIFO; + + private int tile; + private int high, low; + + public FIFOPixelFetcher(final PixelFIFO pixelFIFO) { + this.pixelFIFO = pixelFIFO; + + mode = GET_TILE; + } + + // To be called just before PIXEL_TRANSFER. + public void prepare() { + mode = GET_TILE; + + tile = high = low = 0; + } + + public void clock(VRAM vram) { + switch (mode) { + case GET_TILE: { + if (tile == 0) { + + } + break; + } + case GET_TILE_LOW: { + + break; + } + case GET_TILE_HIGH: { + + break; + } + case SLEEP: { + + break; + } + case PUSH: { + + break; + } + } + } +} diff --git a/playing-coffee/src/main/java/playingcoffee/ppu/OAM.java b/playing-coffee/src/main/java/playingcoffee/ppu/OAM.java index 8ef0dcd..b219a9e 100644 --- a/playing-coffee/src/main/java/playingcoffee/ppu/OAM.java +++ b/playing-coffee/src/main/java/playingcoffee/ppu/OAM.java @@ -9,14 +9,17 @@ public class OAM implements MemorySpace { public OAM() { entries = new OAMEntry[40]; + + for (int i = 0; i < entries.length; i++) + entries[i] = new OAMEntry(); } public int read(int address) { int entry = (address - 0xFE00) / 4; switch (address % 4) { - case 0: return entries[entry].x; - case 1: return entries[entry].y; + case 0: return entries[entry].y; + case 1: return entries[entry].x; case 2: return entries[entry].tileNumber; case 3: return entries[entry].flags; } @@ -29,10 +32,10 @@ public class OAM implements MemorySpace { int entry = (address - 0xFE00) / 4; switch (address % 4) { - case 0: entries[entry].x = value; - case 1: entries[entry].y = value; - case 2: entries[entry].tileNumber = value; - case 3: entries[entry].flags = value; + case 0: entries[entry].y = value; return; + case 1: entries[entry].x = value; return; + case 2: entries[entry].tileNumber = value; return; + case 3: entries[entry].flags = value; return; } Log.error("how in pete's holy christmas tree did we get here?"); diff --git a/playing-coffee/src/main/java/playingcoffee/ppu/PPU.java b/playing-coffee/src/main/java/playingcoffee/ppu/PPU.java index 9a913c8..e997c4e 100644 --- a/playing-coffee/src/main/java/playingcoffee/ppu/PPU.java +++ b/playing-coffee/src/main/java/playingcoffee/ppu/PPU.java @@ -1,15 +1,17 @@ package playingcoffee.ppu; -import playingcoffee.core.InterruptManager; import playingcoffee.core.MMU; +import playingcoffee.interrupt.InterruptManager; +import playingcoffee.ppu.OAM.OAMEntry; public class PPU { - private final MMU mmu; private final InterruptManager interruptManager; + final MMU mmu; private PPURegisters registers; private VRAM vram; + private OAM oam; private int clockCount = 0; @@ -20,77 +22,137 @@ public class PPU { 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(this); + oam = new OAM(); framebuffer = new int[160 * 144]; this.mmu.connectMemorySpace(registers); this.mmu.connectMemorySpace(vram); + this.mmu.connectMemorySpace(oam); } public void onLCDDisable() { clockCount = 0; } - public void OAMSeach() { - registers.setLCDCMode(OAM_SEARCH); - } + public void OAMSeach() {} public void pixelTransfer() { - registers.setLCDCMode(PIXEL_TRANSFER); + int scanline = registers.lcdcYCoord; + int lineX = clockCount % 114 - 80; } - public void HBlank() { - registers.setLCDCMode(HBLANK); - } + public void HBlank() {} - public void VBlank() { - registers.setLCDCMode(VBLANK); - } + public void VBlank() {} public void clock() { - registers.lcdcYCoord = clockCount / 114; + registers.lcdcYCoord = clockCount / 456; - if (clockCount == 144 * 114) renderToFramebuffer(); - if (clockCount == 114 * 144) { + if (clockCount == 456 * 144) { interruptManager.requestInterrupt(InterruptManager.VBLANK); + renderToFramebuffer(); + + registers.setLCDCMode(VBLANK); + } + + if (clockCount % 456 == 80 && registers.getLCDCMode() != VBLANK) registers.setLCDCMode(PIXEL_TRANSFER); + + if (clockCount % 456 == 248 && registers.getLCDCMode() != VBLANK) { + registers.setLCDCMode(HBLANK); + } + if (clockCount % 456 == 0 && registers.getLCDCMode() != VBLANK) { + registers.setLCDCMode(OAM_SEARCH); } - - if (clockCount < 114 * 144) { - if (clockCount % 114 < 20) OAMSeach(); - else if (clockCount % 114 < 43) pixelTransfer(); - else HBlank(); - - } else { - VBlank(); + switch (registers.getLCDCMode()) { + case OAM_SEARCH: OAMSeach(); break; + case PIXEL_TRANSFER: pixelTransfer(); break; + case HBLANK: HBlank(); break; + case VBLANK: VBlank(); break; } clockCount++; - if (clockCount == 17556) { + if (clockCount == 456 * (144 + 10)) { + registers.setLCDCMode(OAM_SEARCH); clockCount = 0; } + + if (registers.lcdcYCoord == registers.lyCompare) { + registers.lcdcStatus |= 0x4; + } else { + registers.lcdcStatus &= ~0x4; + } } 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) { + private void putTile(int address, int screenX, int screenY, boolean window) { + int palette = mmu.read(0xFF47); + 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); + value = (palette >> (value * 2)) & 0x3; - putPixel(color, screenX + n, screenY + y); + int color = 0xFFFFFF - ((value * 64) | ((value * 64) << 8) | ((value * 64) << 16)); + + if (window) + putPixel(color, screenX + n, screenY + y); + else + putPixel(color, (screenX + n) & 255, (screenY + y) & 255); + } + } + } + + private void putSprite(int address, int screenX, int screenY, int paletteIndex, boolean flipX, boolean flipY) { + int palette = mmu.read(0xFF48 + paletteIndex); + + 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); + + if (value != 0) { + + value = (palette >> (value * 2)) & 0x3; + + int color = 0xFFFFFF - ((value * 64) | ((value * 64) << 8) | ((value * 64) << 16)); + + putPixel(color, screenX + (flipX ? (7 - n) : n), screenY + (flipY ? (7 - y) : y)); + } + } + } + + if ((registers.lcdControl & 0x4) != 0) { // 8x16 Mode + address += 16; + + 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); + + if (value != 0) { + + value = (palette >> (value * 2)) & 0x3; + + int color = 0xFFFFFF - ((value * 64) | ((value * 64) << 8) | ((value * 64) << 16)); + + putPixel(color, screenX + (flipX ? (7 - n) : n), screenY + (flipY ? (7 - y) : y) + 8); + } + } } } } @@ -98,6 +160,7 @@ public class PPU { private void renderToFramebuffer() { boolean backgroundTileDataSelect = (registers.lcdControl & 0x10) != 0; int[] backgroundMap = (registers.lcdControl & 0x8) != 0 ? vram.background1 : vram.background0; + int[] windowMap = (registers.lcdControl & 0x8) == 0 ? vram.background1 : vram.background0; for (int tileY = 0; tileY < 32; tileY++) { for (int tileX = 0; tileX < 32; tileX++) { @@ -110,9 +173,42 @@ public class PPU { tileAddress = 0x1000 + tileIndex * 16; } - putTile(tileAddress, tileX * 8 - registers.scrollX, tileY * 8 - registers.scrollY); + putTile(tileAddress, tileX * 8 - registers.scrollX, tileY * 8 - registers.scrollY, false); } } + + // Render Window + if ((registers.lcdControl & 0x20) != 0) { + for (int tileY = 0; tileY < 32; tileY++) { + for (int tileX = 0; tileX < 32; tileX++) { + int tileIndex = windowMap[tileX + tileY * 32]; + + int tileAddress = tileIndex * 16; + + if (!backgroundTileDataSelect) { + if (tileIndex >= 128) tileIndex -= 256; + tileAddress = 0x1000 + tileIndex * 16; + } + + putTile(tileAddress, tileX * 8 + registers.windowX, tileY * 8 + registers.windowY, true); + } + } + } + + // Render sprites (Objects) + for (int i = 0; i < 40; i++) { + OAMEntry entry = oam.entries[i]; + + int address = entry.tileNumber * 16; + + int palette = (entry.flags & 0x10) >> 4; + + //boolean behindBG = (entry.flags & 0x80) != 0; + boolean flipX = (entry.flags & 0x20) != 0; + boolean flipY = (entry.flags & 0x40) != 0; + + putSprite(address, entry.x - 8, entry.y - 16, palette, flipX, flipY); + } } public PPURegisters getRegisters() { diff --git a/playing-coffee/src/main/java/playingcoffee/ppu/PPURegisters.java b/playing-coffee/src/main/java/playingcoffee/ppu/PPURegisters.java index 851c154..9c877ad 100644 --- a/playing-coffee/src/main/java/playingcoffee/ppu/PPURegisters.java +++ b/playing-coffee/src/main/java/playingcoffee/ppu/PPURegisters.java @@ -14,7 +14,6 @@ public class PPURegisters implements MemorySpace { public int objPalette0, objPalette1; // 0xFF48 - 0xFF49 public int windowY, windowX; // 0xFF4A - 0xFF4B - @SuppressWarnings("unused") private final PPU ppu; public PPURegisters(PPU ppu) { @@ -37,7 +36,7 @@ public class PPURegisters implements MemorySpace { case 0xFF43: return scrollX; case 0xFF44: return lcdcYCoord; case 0xFF45: return lyCompare; - case 0xFF46: return dmaTransferStart; // TODO: Do DMA (I have no idea how to do it though...) + case 0xFF46: return dmaTransferStart; case 0xFF47: return bgPalette; case 0xFF48: return objPalette0; case 0xFF49: return objPalette1; @@ -56,7 +55,13 @@ public class PPURegisters implements MemorySpace { case 0xFF43: scrollX = value; return; case 0xFF44: 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; // TODO: Redo the DMA transfer + + for (int i = 0; i < 0x100; i++) { + ppu.mmu.write(ppu.mmu.read((value << 8) + i), 0xFE00 + i); + } + return; case 0xFF47: bgPalette = value; return; case 0xFF48: objPalette0 = value; return; case 0xFF49: objPalette1 = value; return; diff --git a/playing-coffee/src/main/java/playingcoffee/ppu/PixelFIFO.java b/playing-coffee/src/main/java/playingcoffee/ppu/PixelFIFO.java new file mode 100644 index 0000000..1bb0344 --- /dev/null +++ b/playing-coffee/src/main/java/playingcoffee/ppu/PixelFIFO.java @@ -0,0 +1,22 @@ +package playingcoffee.ppu; + +import java.util.LinkedList; +import java.util.Queue; + +public class PixelFIFO { + + Queue fifo; + + public PixelFIFO() { + fifo = new LinkedList(); + } + + public boolean push(FIFOPixel[] tileData) { + if (fifo.size() > 8) return false; + + for (FIFOPixel pixel : tileData) fifo.add(pixel); + + return true; + } + +} diff --git a/playing-coffee/src/main/java/playingcoffee/ppu/VRAM.java b/playing-coffee/src/main/java/playingcoffee/ppu/VRAM.java index c1c18a9..10d3aca 100644 --- a/playing-coffee/src/main/java/playingcoffee/ppu/VRAM.java +++ b/playing-coffee/src/main/java/playingcoffee/ppu/VRAM.java @@ -9,6 +9,7 @@ public class VRAM implements MemorySpace { public int[] background0; public int[] background1; + @SuppressWarnings("unused") private final PPU ppu; public VRAM(final PPU ppu) { @@ -22,7 +23,7 @@ public class VRAM implements MemorySpace { @Override public int read(int address) { - if (ppu.getRegisters().getLCDCMode() == PPU.PIXEL_TRANSFER) return 0xFF; +// 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)]; @@ -33,11 +34,12 @@ public class VRAM implements MemorySpace { @Override public void write(int value, int address) { - if (ppu.getRegisters().getLCDCMode() == PPU.PIXEL_TRANSFER) return; +// if (ppu.getRegisters().getLCDCMode() == PPU.PIXEL_TRANSFER) return; + + if (address >= 0x9C00 && address <= 0x9FFF) background1[address % (32 * 32)] = value; + if (address >= 0x9800 && address <= 0x9BFF) background0[address % (32 * 32)] = value; 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 diff --git a/playing-coffee/src/test/java/playingcoffee/test/GameBoyTest.java b/playing-coffee/src/test/java/playingcoffee/test/GameBoyTest.java index f80a563..9ed6cd3 100644 --- a/playing-coffee/src/test/java/playingcoffee/test/GameBoyTest.java +++ b/playing-coffee/src/test/java/playingcoffee/test/GameBoyTest.java @@ -7,6 +7,7 @@ import java.io.IOException; import org.junit.Test; import playingcoffee.core.cpu.Flags; +import playingcoffee.core.cpu.Registers; public class GameBoyTest { @@ -45,4 +46,22 @@ public class GameBoyTest { assertEquals(flags.get(), Flags.CARRY); } + public void testRegisters() { + Registers registers = new Registers(); + + registers.setAF(0x1284); + assertEquals(0x1284, registers.getAF()); + + registers.setHL(0x4295); + assertEquals(0x42, registers.getH()); + assertEquals(0x95, registers.getL()); + + assertEquals(0x4295, registers.getHL()); + + registers.setSP(0xFF89); + registers.setHL(registers.getSP()); + + assertEquals(registers.getSP(), registers.getHL()); + + } }