Commit: d90bbcf09881e640716b8d9218927571b4677350 Parent: 95625944513ea0f3fc1dd0e7262a932a75e01417 Author: Vi Grey Date: 2021-08-10 08:28 UTC Summary: Add Dan Kraminsky's NES Hacker Portrait DanKaminsky/LICENSE | 24 ++ DanKaminsky/Makefile | 35 +++ DanKaminsky/README.md | 91 ++++++ DanKaminsky/SHA256SUMS.txt | 25 ++ DanKaminsky/bin/DanKaminsky.nes | Bin 0 -> 40976 bytes DanKaminsky/src/DanKaminsky.asm | 55 ++++ DanKaminsky/src/brainfu.asm | 1199 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DanKaminsky/src/controllers.asm | 57 ++++ DanKaminsky/src/controllers/basic_keyboard.asm | 477 ++++++++++++++++++++++++++++++++ DanKaminsky/src/controllers/standard.asm | 258 +++++++++++++++++ DanKaminsky/src/defs.asm | 65 +++++ DanKaminsky/src/draw.asm | 87 ++++++ DanKaminsky/src/frames.asm | 35 +++ DanKaminsky/src/graphics/brainfu-finished.nam | Bin 0 -> 64 bytes DanKaminsky/src/graphics/brainfu-insert-top.nam | Bin 0 -> 33 bytes DanKaminsky/src/graphics/brainfu-insert.nam | Bin 0 -> 64 bytes DanKaminsky/src/graphics/brainfu.nam | Bin 0 -> 1024 bytes DanKaminsky/src/graphics/palettes.pal | 1 + DanKaminsky/src/graphics/portrait.nam | Bin 0 -> 1024 bytes DanKaminsky/src/graphics/tileset.chr | Bin 0 -> 8192 bytes DanKaminsky/src/io.asm | 77 ++++++ DanKaminsky/src/pdf/letter.pdf | 39 +++ DanKaminsky/src/portrait.asm | 151 ++++++++++ DanKaminsky/src/prg.asm | 152 ++++++++++ DanKaminsky/src/ram.asm | 111 ++++++++ 25 files changed, 2939 insertions(+) diff --git a/DanKaminsky/LICENSE b/DanKaminsky/LICENSE new file mode 100755 index 0000000..c178bf0 --- /dev/null +++ b/DanKaminsky/LICENSE @@ -0,0 +1,24 @@ +Copyright (C) 2021, Vi Grey +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/DanKaminsky/Makefile b/DanKaminsky/Makefile new file mode 100644 index 0000000..5924ac1 --- /dev/null +++ b/DanKaminsky/Makefile @@ -0,0 +1,35 @@ +# Copyright (C) 2021, Vi Grey +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +PKG_NAME := DanKaminsky +CURRENTDIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) + +all: + mkdir -p $(CURRENTDIR)bin/build; \ + cd $(CURRENTDIR)src; \ + asm $(PKG_NAME).asm ../bin/build/$(PKG_NAME).nes; \ + +clean: + rm -rf -- $(CURRENTDIR)bin/build; \ diff --git a/DanKaminsky/README.md b/DanKaminsky/README.md new file mode 100755 index 0000000..1c45e89 --- /dev/null +++ b/DanKaminsky/README.md @@ -0,0 +1,91 @@ +# Hacker Portrait for NES - Dan Kaminsky + +An NES ROM portrait of Dan Kaminsky + +**_"NES Hacker Portrait - Dan Kaminsky" was created by Vi Grey and is licensed under the BSD 2-Clause License._** + +### Description: +An NES ROM in the Hacker Portrait for NES series. This portrait is of Dan Kaminsky. + +------ +## **RUNNING THE NES ROM ON AN EMULATOR** + +This NES ROM will run on essentially any NES emulator that can run Super Mario Bros., as this ROM uses the same ROM Mapper type as Super Mario Bros. + + +------ +## **BUILDING THE NES ROM SOURCE CODE** + +### Build Platforms: +- \*BSD +- Linux +- macOS + +### NES ROM Build Dependencies: +- **asm6** (You'll probably have to build asm6 from source. **Make sure the asm6 binary is named `asm` and that the binary is executable and accessible in your PATH**. The source code can be found at http://3dscapture.com/NES/asm6.zip) +- **gmake** (make) + +### Build NES ROM: +From a terminal, go to the the main directory of this project (the directory this README.md file exists in). You can then build the NES ROM with the following command. + +```sh +make +``` + +The resulting NES ROM will be located at **bin/build/DanKaminsky.nes** + +### Clean Build Environment: +If you used `make` to build the NES ROM, you can run the following command to clean up the build environment. +```sh +make clean +``` + +------ +## **EXTRAS** +#### PDF File (Letter): +The NES ROM file at **bin/DanKaminsky.nes** (or if you built the NES ROM yourself, **bin/build/DanKamisnky.nes**) will also be a functioning PDF file. You may need to rename the file from **DanKaminsky.nes** to **DanKaminsky.pdf**. You can also find the PDF file in **src/pdf/letter.pdf** if you wish to read it there rather. + +If you received the care package from Dan in 2019, you will recognize the words on the letter. + +#### Brainfu-- Interpreter +Inputing the Konami Code on the portrait screen (Up Up Down Down Left Right Left Right B A) will unlock a Brainfu-- Interpreter. + +If you received the care package from Dan in 2019, you will hopefully know why the brainfu-- interpreter was added. + +#### Family BASIC Keyboard Support +Along with supporting the standard NES controller, this ROM also supports the Family BASIC Keyboard, which released in Japan for the Famicom. + +------ +## **Extra Words** +I really wanted to make sure this ROM was a ZIP file that contained itself, but I was just not able to get that to work. I know Dan would have really liked that, but due to how FCEUX 2.3.0 handles NES+ZIP polyglot files, I was unable to get the ZIP file compressed enough to fit inside of the NES ROM. + +We miss you Dan. You sparked so much curiosity in so many people. + +------ +## **LICENSE** +``` +Copyright (C) 2021, Vi Grey +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS \`\`AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. +``` diff --git a/DanKaminsky/SHA256SUMS.txt b/DanKaminsky/SHA256SUMS.txt new file mode 100644 index 0000000..6fb2495 --- /dev/null +++ b/DanKaminsky/SHA256SUMS.txt @@ -0,0 +1,25 @@ +98fd2ed2d34395564aeff942fff23badf4fda2594bdd80047570cbce01ea543d LICENSE +d465a16caedf987aacf2c895011c98e02a7f28a90fc7339287a10b0913e04787 Makefile +8765fe418cba2d520fcd1e5fdc3ed1154e7fe52b3384dd2ea15e657b1c02b510 README.md +ff5abdff50fa6a21c6358811ca952a3df3ef8e34df79d358cbbe776633bb72cb bin/DanKaminsky.nes +e2595a3054f39ee011b41084d53dae7f328d2708ba4668da60920e3759ee9c14 src/DanKaminsky.asm +e8d2db057452e2d79e1411d3ef3ef300b77fe5fefc12619a8a5db636192b9289 src/brainfu.asm +689400358b5ba621055a2219a4809bc4849d106908e31de4be1faa1f003660c6 src/controllers.asm +fae71c96e05ce4f8188dca34efec38a93255237ced884b9c49f6fcaf4fc05755 src/defs.asm +c4839d7d993fcc9207bce8aeba25672374f884bd560b6886aeffcd8b29c06690 src/draw.asm +6b460d07a297f558363f71b14f9f7d5a6713c8bc72d00d74512b28f600b7d5fe src/frames.asm +8dbffa1d239baf054bf69e2a3612704e74e98554971fa42626f51107c90beaf2 src/io.asm +6a96feb9406e6412415d4d6d2efe5e2c095e03575ec8a1789234ce6044fd3679 src/portrait.asm +c5c83963ca3c23f520923681b0f5bb7ebe8dfd70bec025823be3ecc5beac73e1 src/prg.asm +5582fda2d233b65f7f1ac6535e58877196b28d60792167acb806544a33e5ce01 src/ram.asm +689400358b5ba621055a2219a4809bc4849d106908e31de4be1faa1f003660c6 src/controllers.asm +795c02ed8323bf298877f0f740ce3145d31db89431f195f41f1432a02f679c84 src/controllers/basic_keyboard.asm +14ae4d83ccdb1ca5eff7471cac539e51b1e1b417f31310c02cea8b697f449098 src/controllers/standard.asm +ac73adb819d6c8cf38a95755490e5cca492a535644b74ad9e3763822198e3304 src/graphics/brainfu-finished.nam +cbef3b802cb097c53e778b024a1b4e01610e7cc89526ee5f3e0c570c18c56ff3 src/graphics/brainfu-insert-top.nam +d8f1d1f1cf2bdb4395acd4a70425be4663c17482adef6863a5d734113f1a6297 src/graphics/brainfu-insert.nam +8ea300505294737fd9ce7e6bc58470420ff5b66c5c5a8b295e06ae602ecb76c1 src/graphics/brainfu.nam +3a27e981fc4d882598baf4514eca1b2ebd25c153e992ee23cc6f8c2d8d03011f src/graphics/palettes.pal +544f229a69c14586f90bd5c73e28e2af37b0d627b832f880c4cb3bb07200c5ed src/graphics/portrait.nam +1b22a4becab4ba859df350408ad0f2ad4ba3aa7c5ebaf8dea6616df896bcc397 src/graphics/tileset.chr +f28e6e1be8a3bc8508cfc821933ffb32ff08ef75cce56b9b9e498a9f440578fb src/pdf/letter.pdf diff --git a/DanKaminsky/bin/DanKaminsky.nes b/DanKaminsky/bin/DanKaminsky.nes new file mode 100644 index 0000000..40eaea6 Binary files /dev/null and b/DanKaminsky/bin/DanKaminsky.nes differ diff --git a/DanKaminsky/src/DanKaminsky.asm b/DanKaminsky/src/DanKaminsky.asm new file mode 100644 index 0000000..31cd036 --- /dev/null +++ b/DanKaminsky/src/DanKaminsky.asm @@ -0,0 +1,55 @@ +; Copyright (C) 2021, Vi Grey +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +; SUCH DAMAGE. + + .db "NES", $1A ; 0-3 + .db $02 ; 4 + .db $01 ; 5 + .db %00000000 ; 6 + .db %00001000 ; 7 + .db %00000000 ; 8 + .db %00000000 ; 9 + .db %00000000 ; 10 + .db %00000000 ; 11 + .db %00000010 ; 12 + .db %00000000 ; 13 + .db %00000000 ; 14 + .db %00000000 ; 15 + +.include "ram.asm" +.include "defs.asm" + +.base $8000 + .incbin "pdf/letter.pdf" + .pad $8A00, $FF + +.include "prg.asm" + + .pad CALLBACK, #$FF + .dw NMI + .dw RESET + .dw 0 + +.base $0000 + .incbin "graphics/tileset.chr" diff --git a/DanKaminsky/src/brainfu.asm b/DanKaminsky/src/brainfu.asm new file mode 100644 index 0000000..1351198 --- /dev/null +++ b/DanKaminsky/src/brainfu.asm @@ -0,0 +1,1199 @@ +; Copyright (C) 2021, Vi Grey +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +; SUCH DAMAGE. + +;;;;; +; +; Instruction Pointer Code +; +;;;;;; + +; Clear Instructions +ClearInstructions: + jsr SetInstructionPointerStart + ldy #$00 + lda #$00 +ClearInstructionsLoop: + sta (instructionPointer), Y + iny + bne ClearInstructionsLoop + inc (instructionPointer + 1) + ldx (instructionPointer + 1) + cpx #$06 + bcc ClearInstructionsLoop + lda #$02 + sta (instructionPointer + 1) +ClearInstructionsDone: + rts + +; Set instructionPointer to Beginning ($0200) +SetInstructionPointerStart: + lda #$00 + sta instructionPointer + lda #$02 + sta (instructionPointer + 1) + rts + +; Set instructionPointer to End ($0600) +SetInstructionPointerEnd: + lda #$00 + sta instructionPointer + lda #$06 + sta (instructionPointer + 1) + rts + +; Increase little-endian 16 bit instructionPointer value by 1 +IncInstructionPointer: + lda instructionPointer + clc + adc #$01 + sta instructionPointer + lda (instructionPointer + 1) + adc #$00 + sta (instructionPointer + 1) + lda processing + bne IncInstructionPointerDone + jsr IncInstructionRowCol + jsr SetInstructionAddr +IncInstructionPointerDone: + rts + +; Decrease little-endian 16 bit instructionPointer value by 1 +DecInstructionPointer: + lda instructionPointer + sec + sbc #$01 + sta instructionPointer + lda (instructionPointer + 1) + sbc #$00 + sta (instructionPointer + 1) + lda processing + bne DecInstructionPointerDoneNotProcessing + jsr DecInstructionRowCol + jsr SetInstructionAddr +DecInstructionPointerDoneNotProcessing: + rts + +DecInstructionRowCol: + lda #$01 + sta needDraw + dec instructionCol + bpl DecInstructionRowColDone + lda #27 + sta instructionCol + lda (instructionPointer + 1) + cmp #$04 + bcs DecInstructionRowColOverflow + cmp #$03 + bne DecInstructionRowColSkipCheckInstructionPointer + lda instructionPointer + cmp #$F8 + bcc DecInstructionRowColSkipCheckInstructionPointer +DecInstructionRowColOverflow: + jsr RedrawInstructions + rts +DecInstructionRowColSkipCheckInstructionPointer: + dec instructionRow + bpl DecInstructionRowColDone + lda #$00 + sta instructionRow + sta instructionCol +DecInstructionRowColDone: + rts + +IncInstructionRowCol: + lda (instructionPointer + 1) + cmp #$06 + bcc IncInstructionRowColContinue + lda instructionPointer + bne IncInstructionRowColDone +IncInstructionRowColContinue: + lda #$01 + sta needDraw + inc instructionCol + lda instructionCol + cmp #28 + bcc IncInstructionRowColDone + lda #$00 + sta instructionCol + inc instructionRow + lda instructionRow + cmp #19 + bcc IncInstructionRowColDone + lda #18 + sta instructionRow + jsr RedrawInstructions +IncInstructionRowColDone: + rts + +; Check instructionPointer to make sure it is between $0200 and +; $0600 (inclusive). Set A to 1 if valid, 0 if out of bounds +CheckInstructionPointer: + lda #$00 + ldy (instructionPointer + 1) + cpy #$02 + bcc CheckInstructionPointerDone + cpy #$06 + bcc CheckInstructionPointerContinue + bne CheckInstructionPointerDone + ldy instructionPointer + bne CheckInstructionPointerDone +CheckInstructionPointerContinue: + lda #$01 +CheckInstructionPointerDone: + rts + + +;;;;; +; +; Memory Pointer Code +; +;;;;;; + +; Clear Memory +ClearBrainfMemory: + jsr SetMemoryPointerStart + ldy #$00 + lda #$00 +ClearBrainfMemoryLoop: + sta (memoryPointer), Y + iny + bne ClearBrainfMemoryLoop + inc (memoryPointer + 1) + ldx (memoryPointer + 1) + cpx #$08 + bcc ClearBrainfMemoryLoop + lda #$06 + sta (memoryPointer + 1) +ClearBrainfMemoryDone: + rts + +; Set memoryPointer to Beginning ($0600) +SetMemoryPointerStart: + lda #$00 + sta memoryPointer + lda #$06 + sta (memoryPointer + 1) + rts + +; Increase little-endian 16 bit memoryPointer value by 1 +IncMemoryPointer: + lda memoryPointer + clc + adc #$01 + sta memoryPointer + lda (memoryPointer + 1) + adc #$00 + sta (memoryPointer + 1) + rts + +; Decrease little-endian 16 bit memoryPointer value by 1 +DecMemoryPointer: + lda memoryPointer + sec + sbc #$01 + sta memoryPointer + lda (memoryPointer + 1) + sbc #$00 + sta (memoryPointer + 1) + rts + +; Check memoryPointer to make sure it is between $0600 and +; $0800 (inclusive). Set A to 1 if valid, 0 if out of bounds +CheckMemoryPointer: + lda #$00 + ldy (memoryPointer + 1) + cpy #$06 + bcc CheckMemoryPointerDone + cpy #$08 + bcs CheckMemoryPointerDone +CheckMemoryPointerContinue: + lda #$01 +CheckMemoryPointerDone: + rts + +;;;;; +; +; Brainfu Logic Handling +; +;;;;; + +; Insert value in A register to instructionPointer, then increment +; instructionPointer +InsertInstruction: + pha + jsr CheckInstructionPointer + cmp #$00 + beq InsertInstructionDone + lda (instructionPointer + 1) + cmp #$06 + bcs InsertInstructionDone + pla + ldy #$00 + sta (instructionPointer), Y + sta instructionVal + lda #$01 + sta instructionInsert + jsr IncInstructionPointer + rts +InsertInstructionDone: + pla + rts + +ClearCurrentInstruction: + jsr CheckInstructionPointer + cmp #$00 + beq ClearCurrentInstructionDone + lda (instructionPointer + 1) + cmp #$06 + bcs ClearCurrentInstructionDone + lda #$00 + tay + sta (instructionPointer), Y + lda instructionRow + cmp #18 + bne ClearCurrentInstructionNotSkip + lda instructionCol + cmp #27 + bne ClearCurrentInstructionNotSkip + rts +ClearCurrentInstructionNotSkip: + sty instructionVal + lda #$01 + sta instructionInsert +ClearCurrentInstructionDone: + rts + +; Increment the loop counter by 1 (when you encounter ]) +IncLoopCount: + lda loopCount + clc + adc #$01 + sta loopCount + lda (loopCount + 1) + adc #$00 + sta (loopCount + 1) + rts + +; Subtract the loop count by 1 (when you encounter [) +DecLoopCount: + lda loopCount + sec + sbc #$01 + sta loopCount + lda (loopCount + 1) + sbc #$00 + sta (loopCount + 1) + rts + +StartBrainfuScreen: + jsr WaitFrame + jsr BlankPalette + jsr WaitFrame + jsr Blank + jsr ClearBrainfMemory + jsr ClearInstructions + jsr DrawBrainfuScreen + jsr SetBrainfuPalette + jsr DrawCursor + lda #$00 + sta processing + jsr ResetScroll + rts + +DrawBrainfuScreen: + jsr SetInstructionPointerStart + jsr SetMemoryPointerStart + jsr DrawBrainfuNametable + lda #$01 + sta backgroundNametable + sta spriteNametable + sta needDraw + sta screen + lda #$00 + sta instructionCol + sta instructionRow + sta spritesEnabled + sta updateDisabled + jsr SetInstructionAddr + rts + +DrawBrainfuNametable: + lda #<(BrainfuNametable) + sta addr + lda #>(BrainfuNametable) + sta (addr + 1) + ldy #$00 + ldx #$04 + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + sty PPU_ADDR +DrawBrainfuNametableLoop: + lda (addr), Y + sta PPU_DATA + iny + bne DrawBrainfuNametableLoop + inc (addr + 1) + dex + bne DrawBrainfuNametableLoop + rts + +SetBrainfuPalette: + lda PPU_STATUS + lda #$3F + sta PPU_ADDR + lda #$00 + sta PPU_ADDR + lda #$0F + ldy #$30 + ldx #$08 +SetBrainfuPaletteLoop: + sta PPU_DATA + sty PPU_DATA + sty PPU_DATA + sty PPU_DATA + dex + bne SetBrainfuPaletteLoop + rts + +SetInstructionAddr: + lda instructionAddr + sta instructionAddrLast + lda (instructionAddr + 1) + sta (instructionAddrLast + 1) + lda instructionRow + and #%00000111 + lsr + ror + ror + ror + clc + adc #$C2 + sta instructionAddr + lda #$00 + adc #$20 + sta (instructionAddr + 1) + lda instructionAddr + clc + adc instructionCol + sta instructionAddr + lda (instructionAddr + 1) + adc #$00 + sta (instructionAddr + 1) + lda instructionRow + and #%00011000 + lsr + lsr + lsr + clc + adc (instructionAddr + 1) + sta (instructionAddr + 1) + rts + +DrawCursor: + lda instructionInsert + beq DrawCursorNotInstruction + lda PPU_STATUS + lda (instructionAddrLast + 1) + sta PPU_ADDR + lda instructionAddrLast + sta PPU_ADDR + lda instructionVal + sta PPU_DATA + lda #$00 + sta instructionInsert +DrawCursorNotInstruction: + lda PPU_STATUS + lda (instructionAddr + 1) + sta PPU_ADDR + lda instructionAddr + sta PPU_ADDR + lda frames + and #%00010000 + beq DrawCursorContinue + lda #$E0 + ldx (instructionPointer + 1) + cpx #$06 + bcc DrawCursorContinue + lda #$E1 +DrawCursorContinue: + sta PPU_DATA + rts + +ForceDrawCursor: + lda frames + and #%00001111 + bne ForceDrawCursorDone + lda #$01 + sta needDraw +ForceDrawCursorDone: + rts + +RedrawInstructions: + jsr WaitFrame + jsr BlankPalette + jsr WaitFrame + jsr Blank + lda PPU_STATUS + lda instructionPointer + sec + sbc #$F8 + sta addr + lda (instructionPointer + 1) + sbc #$01 + sta (addr + 1) + lda instructionCol + beq RedrawInstructionsCol0 + lda addr + sec + sbc #27 + sta addr + lda (addr + 1) + sbc #$00 + sta (addr + 1) +RedrawInstructionsCol0: + lda #$20 + sta (instructionAddrTmp + 1) + sta PPU_ADDR + lda #$C2 + sta instructionAddrTmp + sta PPU_ADDR + ldy #$00 + ldx #28 +RedrawInstructionsLoop: + lda (addr), Y + sta PPU_DATA + lda addr + clc + adc #$01 + sta addr + lda (addr + 1) + adc #$00 + sta (addr + 1) + dex + bne RedrawInstructionsLoopSkipResetX + ldx #28 + lda PPU_STATUS + lda instructionAddrTmp + clc + adc #$20 + sta instructionAddrTmp + lda (instructionAddrTmp + 1) + adc #$00 + sta (instructionAddrTmp + 1) + sta PPU_ADDR + lda instructionAddrTmp + sta PPU_ADDR +RedrawInstructionsLoopSkipResetX: + lda addr + cmp instructionPointer + bne RedrawInstructionsLoop + lda (addr + 1) + cmp (instructionPointer + 1) + bne RedrawInstructionsLoop + lda instructionCol + bne RedrawInstructionsDone +RedrawInstructionsBlankLine: + ldy #28 + lda #$00 +RedrawInstructionsBlankLineLoop: + sta PPU_DATA + dey + bne RedrawInstructionsBlankLineLoop +RedrawInstructionsDone: + lda instructionCol + beq RedrawInstructionsDoneCol0 + lda #$00 + sta instructionInsert +RedrawInstructionsDoneCol0: + jsr SetBrainfuPalette + lda #$01 + sta needDraw + lda #$00 + sta updateDisabled + jsr ResetScroll + rts + + +;;;;; +; +; Brainfu Program Code +; +;;;;; + +ContinueInstructions: + jsr WaitFrame + jsr BlankPalette + jsr WaitFrame + jsr Blank + lda #$00 + sta errorType + lda #$01 + sta processing + jsr ResumeFromPrintAddrCol + jmp HandleInstructionsLoopContinue + +HandleInstructions: + jsr WaitFrame + jsr BlankPalette + jsr WaitFrame + jsr Blank + lda #$00 + sta errorType + lda #$01 + sta processing + jsr DrawBrainfuScreen + jsr ClearBrainfMemory + jsr SetInstructionPointerStart + jsr SetMemoryPointerStart + jsr InitializePrintAddr +HandleInstructionsLoop: + ldy #$00 + lda (instructionPointer), Y + cmp #$2B + bne HandleInstructionsLoopNotPlus + jsr HandlePlus + jmp HandleInstructionsLoopContinue +HandleInstructionsLoopNotPlus: + cmp #$2D + bne HandleInstructionsLoopNotMinus + jsr HandleMinus + jmp HandleInstructionsLoopContinue +HandleInstructionsLoopNotMinus: + cmp #$2E + bne HandleInstructionsLoopNotPeriod + jsr HandlePeriod + jmp HandleInstructionsLoopContinue +HandleInstructionsLoopNotPeriod: + cmp #$2C + bne HandleInstructionsLoopNotComma + jmp HandleComma +HandleInstructionsLoopNotComma: + cmp #$3C + bne HandleInstructionsLoopNotLeftAngle + jsr HandleLeftAngle + lda errorType + beq HandleInstructionsLeftAngleContinue + jmp HandleMemoryPointerError +HandleInstructionsLeftAngleContinue: + jmp HandleInstructionsLoopContinue +HandleInstructionsLoopNotLeftAngle: + cmp #$3E + bne HandleInstructionsLoopNotRightAngle + jsr HandleRightAngle + lda errorType + beq HandleInstructionsRightAngleContinue + jmp HandleMemoryPointerError +HandleInstructionsRightAngleContinue: + jmp HandleInstructionsLoopContinue +HandleInstructionsLoopNotRightAngle: + cmp #$5B + bne HandleInstructionsLoopNotLeftSquare + jsr HandleLeftSquare + lda errorType + beq HandleInstructionsLeftSquareContinue + jmp HandleInstructionPointerError +HandleInstructionsLeftSquareContinue: + jmp HandleInstructionsLoopContinue +HandleInstructionsLoopNotLeftSquare: + cmp #$5D + bne HandleInstructionsLoopNotRightSquare + jsr HandleRightSquare + lda errorType + beq HandleInstructionsRightSquareContinue + jmp HandleInstructionPointerError +HandleInstructionsRightSquareContinue: + jmp HandleInstructionsLoopContinue +HandleInstructionsLoopNotRightSquare: + jmp HandleInstructionsDone +HandleInstructionsLoopContinue: + jsr IncInstructionPointer + lda (instructionPointer + 1) + cmp #$06 + bcc HandleInstructionsLoop +HandleInstructionsDone: + jsr ClearInstructions + jsr SetInstructionPointerStart + jsr DrawBrainfuFinished + jsr ResetScroll + jsr WaitFrame + jsr SetBrainfuPalette + jsr ResetScroll + lda #$01 + sta needDraw + lda #$00 + sta processing + sta updateDisabled + rts + +HandlePlus: + ldy #$00 + lda (memoryPointer), Y + tax + inx + txa + sta (memoryPointer), Y + rts + +HandleMinus: + ldy #$00 + lda (memoryPointer), Y + tax + dex + txa + sta (memoryPointer), Y + rts + +HandlePeriod: + jsr PrintCharacter + rts + +HandleComma: + lda #SCREEN_BRAINFU_INSERT + sta screen + lda #$00 + sta insertPointer + lda #$00 + sta updateDisabled + jsr DrawInsert + rts + +HandleLeftAngle: + jsr DecMemoryPointer + jsr CheckMemoryPointer + cmp #$01 + beq HandleLeftAngleDone + lda #$FF + sta errorType +HandleLeftAngleDone: + rts + +HandleRightAngle: + jsr IncMemoryPointer + jsr CheckMemoryPointer + cmp #$01 + beq HandleRightAngleDone + lda #$01 + sta errorType +HandleRightAngleDone: + rts + +HandleLeftSquare: + ldy #$00 + sty loopCount + sty (loopCount + 1) + lda (memoryPointer), Y + bne HandleLeftSquareDone +HandleLeftSquareLoop: + jsr IncInstructionPointer + jsr CheckInstructionPointer + cmp #$01 + beq HandleLeftSquareLoopValidInstructionPointer + lda #$01 + sta errorType + rts +HandleLeftSquareLoopValidInstructionPointer: + lda (instructionPointer + 1) + cmp #$06 + bne HandleLeftSquareLoopContinue + lda #$01 + sta errorType + rts +HandleLeftSquareLoopContinue: + ldy #$00 + lda (instructionPointer), Y + cmp #$5B + bne HandleLeftSquareLoopNotLeftSquare + jsr IncLoopCount + jmp HandleLeftSquareLoop +HandleLeftSquareLoopNotLeftSquare: + cmp #$5D + bne HandleLeftSquareLoop + lda loopCount + ora (loopCount + 1) + bne HandleLeftSquareLoopNotMatchingRightSquare + rts +HandleLeftSquareLoopNotMatchingRightSquare: + jsr DecLoopCount + jmp HandleLeftSquareLoop +HandleLeftSquareDone: + rts + +HandleRightSquare: + ldy #$00 + sty loopCount + sty (loopCount + 1) +HandleRightSquareLoop: + jsr DecInstructionPointer + jsr CheckInstructionPointer + cmp #$01 + beq HandleRightSquareLoopContinue + lda #$FF + sta errorType + rts +HandleRightSquareLoopContinue: + ldy #$00 + lda (instructionPointer), Y + cmp #$5D + bne HandleRightSquareLoopNotRightSquare + jsr IncLoopCount + jmp HandleRightSquareLoop +HandleRightSquareLoopNotRightSquare: + cmp #$5B + bne HandleRightSquareLoop + lda loopCount + ora (loopCount + 1) + bne HandleRightSquareLoopNotMatchingLeftSquare + jsr DecInstructionPointer + rts +HandleRightSquareLoopNotMatchingLeftSquare: + jsr DecLoopCount + jmp HandleRightSquareLoop + +HandleMemoryPointerError: + jsr ClearInstructions + jsr SetInstructionPointerStart + jsr DrawBrainfuScreen + jsr DrawBrainfuError + jsr DrawBrainfuMemoryPointerError + lda errorType + bmi HandleMemoryPointerErrorUnderflow + jsr Draw513 + jmp HandleMemoryPointerErrorDone +HandleMemoryPointerErrorUnderflow: + jsr DrawMinus1 +HandleMemoryPointerErrorDone: + jsr ResetScroll + jsr WaitFrame + jsr SetBrainfuPalette + jsr ResetScroll + lda #$01 + sta needDraw + lda #$00 + sta processing + sta updateDisabled + rts + +HandleInstructionPointerError: + jsr ClearInstructions + jsr SetInstructionPointerStart + jsr DrawBrainfuScreen + jsr DrawBrainfuError + lda errorType + bmi HandleInstructionPointerErrorUnderflow + jsr DrawBrainfuInstructionPointerNoRightError + jmp HandleInstructionPointerErrorDone +HandleInstructionPointerErrorUnderflow: + jsr DrawBrainfuInstructionPointerNoLeftError +HandleInstructionPointerErrorDone: + jsr ResetScroll + jsr WaitFrame + jsr SetBrainfuPalette + jsr ResetScroll + lda #$01 + sta needDraw + lda #$00 + sta processing + sta updateDisabled + rts + +DrawMinus1: + ldx #$00 +DrawMinus1Loop: + lda MinusOneError, X + sta PPU_DATA + inx + cpx #$04 + bne DrawMinus1Loop + rts + +Draw513: + ldx #$00 +Draw513Loop: + lda FiveThirteenError, X + sta PPU_DATA + inx + cpx #$05 + bne Draw513Loop + rts + +DrawBrainfuError: + lda #SCREEN_BRAINFU_OTHER + sta screen + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$A2 + sta PPU_ADDR + ldx #$00 +DrawBrainfuErrorLoop: + lda ErrorText, X + sta PPU_DATA + inx + cpx #$05 + bne DrawBrainfuErrorLoop + jsr DrawBrainfuContinue + rts + +DrawBrainfuInsertTop: + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$A0 + sta PPU_ADDR + ldx #$00 +DrawBrainfuInsertTopLoop: + lda BrainfuInsertTop, X + sta PPU_DATA + inx + cpx #$20 + bne DrawBrainfuInsertTopLoop + rts + +DrawBrainfuInsertBottom: + lda PPU_STATUS + lda #$23 + sta PPU_ADDR + lda #$40 + sta PPU_ADDR + ldx #$00 +DrawBrainfuInsertBottomLoop: + lda BrainfuInsert, X + sta PPU_DATA + inx + cpx #$40 + bne DrawBrainfuInsertBottomLoop + rts + +DrawBrainfuMemoryPointerError: + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$C2 + sta PPU_ADDR + ldx #$00 +DrawBrainfuMemoryPointerErrorLoop: + lda MemoryPointerError, X + sta PPU_DATA + inx + cpx #$20 + bne DrawBrainfuMemoryPointerErrorLoop + rts + +DrawBrainfuInstructionPointerNoLeftError: + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$C2 + sta PPU_ADDR + ldx #$00 +DrawBrainfuInstructionPointerNoLeftErrorLoop: + lda InstructionPointerNoMatchingLeftError, X + sta PPU_DATA + inx + cpx #25 + bne DrawBrainfuInstructionPointerNoLeftErrorLoop + rts + +DrawBrainfuInstructionPointerNoRightError: + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$C2 + sta PPU_ADDR + ldx #$00 +DrawBrainfuInstructionPointerNoRightErrorLoop: + lda InstructionPointerNoMatchingRightError, X + sta PPU_DATA + inx + cpx #25 + bne DrawBrainfuInstructionPointerNoRightErrorLoop + rts + +DrawBrainfuFinished: + lda #SCREEN_BRAINFU_OTHER + sta screen + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$A2 + sta PPU_ADDR + ldx #$00 +DrawBrainfuFinishedLoop: + lda FinishedText, X + sta PPU_DATA + inx + cpx #$0F + bne DrawBrainfuFinishedLoop + jsr DrawBrainfuContinue + rts + +DrawBrainfuContinue: + lda PPU_STATUS + lda #$23 + sta PPU_ADDR + lda #$40 + sta PPU_ADDR + ldx #$00 +DrawBrainfuContinueLoop: + lda BrainfuFinished, X + sta PPU_DATA + inx + cpx #$40 + bne DrawBrainfuContinueLoop + rts + +FinishedText: + .byte "FINISHED", $00, $00, $00, $00, $00, $00, $00 + +ErrorText: + .byte "ERROR" + +MemoryPointerError: + .byte "MEMORY POINTER OUT OF BOUNDS" + .byte $00, $00, $00, $00 + +MinusOneError: + .byte "(-1)" + +FiveThirteenError: + .byte "(513)" + +InstructionPointerNoMatchingLeftError: + .byte "NO MATCHING [ INSTRUCTION" + +InstructionPointerNoMatchingRightError: + .byte "NO MATCHING ] INSTRUCTION" + + +;;;;; +; +; Brainfu Print Handling (period) +; +;;;;; + +ResumeFromPrintAddrCol: + lda PPU_STATUS + lda printAddr + clc + adc printCol + tax + lda (printAddr + 1) + adc #$00 + sta PPU_ADDR + stx PPU_ADDR + rts + +InitializePrintAddr: + lda PPU_STATUS + lda #$C2 + sta printAddr + lda #$20 + sta (printAddr + 1) + sta PPU_ADDR + lda printAddr + sta PPU_ADDR + lda #$00 + sta printCol + sta printRow + rts + +IncPrintAddrRow: + lda PPU_STATUS + lda printAddr + clc + adc #$20 + sta printAddr + lda (printAddr + 1) + adc #$00 + sta (printAddr + 1) + sta PPU_ADDR + lda printAddr + sta PPU_ADDR + rts + +IncPrintCol: + inc printCol + lda printCol + cmp #28 + bne IncPrintColDone + lda #$00 + sta printCol + inc printRow + jsr IncPrintAddrRow +IncPrintColDone: + rts + +PrintCharacter: + lda printRow + cmp #19 + bcs PrintCharacterDone + ldy #$00 + lda (memoryPointer), Y + cmp #$0D + bne PrintCharacterNotCarriageReturn + jsr PrintCarriageReturn + rts +PrintCharacterNotCarriageReturn: + cmp #$0A + bne PrintCharacterNotNewline + jsr PrintNewline + rts +PrintCharacterNotNewline: + cmp #$7F + bcc PrintCharacterNotBroken + lda #$7F + jsr PrintChar + rts +PrintCharacterNotBroken: + cmp #$20 + bcc PrintCharacterNotCharacter + jsr PrintChar + rts +PrintCharacterNotCharacter: +PrintCharacterDone: + rts + +PrintCarriageReturn: + lda #$00 + sta printCol + lda PPU_STATUS + lda (printAddr + 1) + sta PPU_ADDR + lda printAddr + sta PPU_ADDR + rts + +PrintNewline: + lda #$00 + sta printCol + inc printRow + jsr IncPrintAddrRow + rts + +PrintChar: + sta PPU_DATA + jsr IncPrintCol + rts + +DrawInsert: + jsr DrawBrainfuInsertTop + jsr DrawBrainfuInsertBottom + jsr DrawInsertByte + jsr ResetScroll + jsr WaitFrame + jsr SetBrainfuPalette + jsr ResetScroll + lda #$01 + sta needDraw + lda #$00 + sta processing + sta updateDisabled + rts + +DrawInsertByte: + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$A9 + sta PPU_ADDR + ldx #$00 + ldy #$00 +DrawInsertByteLoop: + txa + tay + lda #$00 + sec +DrawInsertByteShiftLoop: + ror + dey + bpl DrawInsertByteShiftLoop + ldy #$00 + and (memoryPointer), Y + beq DrawInsertByteLoopZeroValue + lda #$31 + jmp DrawInsertByteLoopContinue +DrawInsertByteLoopZeroValue: + lda #$30 +DrawInsertByteLoopContinue: + cpx insertPointer + bne DrawInsertByteLoopEnd + clc + adc #$C0 +DrawInsertByteLoopEnd: + sta PPU_DATA + inx + cpx #$08 + bne DrawInsertByteLoop + rts + +BrainfuInsertFlipBit: + ldx insertPointer + lda #$00 + sec + tay +BrainfuInsertFlipBitLoop: + ror + dex + bpl BrainfuInsertFlipBitLoop + eor (memoryPointer), Y + sta (memoryPointer), Y + lda #$01 + sta needDraw + rts + +BrainfuInsertMoveCursorLeft: + dec insertPointer + bpl BrainfuInsertMoveCursorLeftDone + inc insertPointer +BrainfuInsertMoveCursorLeftDone: + lda #$01 + sta needDraw + rts + +BrainfuInsertMoveCursorRight: + inc insertPointer + lda insertPointer + cmp #$08 + bcc BrainfuInsertMoveCursorRightDone + lda #$07 + sta insertPointer +BrainfuInsertMoveCursorRightDone: + lda #$01 + sta needDraw + rts + + +BrainfuNametable: + .incbin "graphics/brainfu.nam" + +BrainfuInsertTop: + .incbin "graphics/brainfu-insert-top.nam" + +BrainfuInsert: + .incbin "graphics/brainfu-insert.nam" + +BrainfuFinished: + .incbin "graphics/brainfu-finished.nam" diff --git a/DanKaminsky/src/controllers.asm b/DanKaminsky/src/controllers.asm new file mode 100644 index 0000000..b848dbc --- /dev/null +++ b/DanKaminsky/src/controllers.asm @@ -0,0 +1,57 @@ +; Copyright (C) 2021, Vi Grey +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +; SUCH DAMAGE. + +; controllerGlobalFlags +; 7 bit 0 +; ---- ---- +; | +; +- Famicom BASIC Keyboard Detected Flag + + +ResetControllerTypes: + lda #$00 + ldy #$03 +ResetControllerTypesLoop: + sta controller1Type, Y + dey + bpl ResetControllerTypesLoop + rts + +;;;;;;;;;; +;; +;; NES Standard Controller +;; +;;;;;;;;;; + +.include "controllers/standard.asm" + +;;;;;;;;;; +;; +;; Famicom BASIC Keyboard +;; +;;;;;;;;;; + +.include "controllers/basic_keyboard.asm" + diff --git a/DanKaminsky/src/controllers/basic_keyboard.asm b/DanKaminsky/src/controllers/basic_keyboard.asm new file mode 100644 index 0000000..7a006dd --- /dev/null +++ b/DanKaminsky/src/controllers/basic_keyboard.asm @@ -0,0 +1,477 @@ +; Copyright (C) 2021, Vi Grey +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +; SUCH DAMAGE. + +KEY_UP = $01 +KEY_DOWN = $02 +KEY_RIGHT = $03 +KEY_LEFT = $04 +KEY_DEL = $08 +KEY_RETURN = $0A +KEY_CLR_HOME = $0B +KEY_STOP = $0C +KEY_INS = $0D +KEY_GRPH = $0E +KEY_KANA = $0F +KEY_SHIFT = $10 +KEY_F1 = $11 +KEY_F2 = $12 +KEY_F3 = $13 +KEY_F4 = $14 +KEY_F5 = $15 +KEY_F6 = $16 +KEY_F7 = $17 +KEY_F8 = $18 +KEY_CTR = $1A +KEY_ESC = $1B + +DetectKeyboard: + lda (io2D1 + 2) + and #%00100000 + beq DetectKeyboardDone + and (io2D2 + 2) + and (io2D3 + 2) + and (io2D4 + 2) + and #%00100000 + beq DetectKeyboardDone + lda #$00 + sta IO_1 + lda IO_2 + and #%00011110 + bne DetectKeyboardDone + jsr SetKeyboardFlag + rts +DetectKeyboardDone: + jsr ClearKeyboardFlag + rts + +ClearKeyboardFlag: + lda #%11111111 + eor #CONTROLLER_BASIC_KEYBOARD_USED + and controllerGlobalFlags + sta controllerGlobalFlags + rts + +SetKeyboardFlag: + lda controllerGlobalFlags + ora #CONTROLLER_BASIC_KEYBOARD_USED + sta controllerGlobalFlags + rts + +GetKeysPressed: + lda controllerGlobalFlags + and #(CONTROLLER_BASIC_KEYBOARD_USED) + cmp #(CONTROLLER_BASIC_KEYBOARD_USED) + beq GetKeysPressedKeyboardExists + jsr ClearKeysPressed + rts +GetKeysPressedKeyboardExists: + jsr SetKeysPressedToKeysPressedLastFrame + jsr ClearKeysPressed + jsr CheckKeysPressed + rts + +CheckKeysPressed: + ldx #$00 + ldy #$00 + sty currentKeyOffset + sty keysPressedOffset +CheckKeysPressedLoop: + lda io2D1, X + sta currentKeyCheck +CheckKeysPressedLoopByteContinue: + asl currentKeyCheck + bcs CheckKeysPressedLoopByteKeyNotPressed + lda keysPressedOffset + cmp #$05 + bcc CheckKeysPressedLoopByteKeyIsPressed + rts +CheckKeysPressedLoopByteKeyIsPressed: + txa + pha + ldx currentKeyOffset + lda KeyboardLowercase, X + cmp #KEY_SHIFT + bne CheckKeysPressedLoopByteKeyIsPressedNotShift + lda #$01 + sta shiftPressed + jmp CheckKeysPressedLoopByteKeyIsPressedContinue +CheckKeysPressedLoopByteKeyIsPressedNotShift: + lda currentKeyOffset + ldx keysPressedOffset + sta keysPressed, X + inc keysPressedOffset +CheckKeysPressedLoopByteKeyIsPressedContinue: + pla + tax +CheckKeysPressedLoopByteKeyNotPressed: + inc currentKeyOffset + iny + cpy #$02 + bne CheckKeysPressedLoopByteNotLastByte + txa + and #%00000011 + cmp #$02 + bne CheckKeysPressedLoopByteNotLastByte + inx + jmp CheckKeysPressedLoopByteEnd +CheckKeysPressedLoopByteNotLastByte: + cpy #$08 + bne CheckKeysPressedLoopByteContinue +CheckKeysPressedLoopByteEnd: + ; end of byte + ldy #$00 + inx + cpx #$10 + bcc CheckKeysPressedLoop + rts + +ClearKeysPressed: + ldx #$04 + lda #$FF +ClearKeysPressedLoop: + sta keysPressed, X + dex + bpl ClearKeysPressedLoop + lda #$00 + sta shiftPressed + rts + +SetKeysPressedToKeysPressedLastFrame: + ldx #$04 +SetKeysPressedToKeysPressedLastFrameLoop: + lda keysPressed, X + sta keysPressedLastFrame, X + dex + bpl SetKeysPressedToKeysPressedLastFrameLoop + rts + +KeyboardLowercase: + .byte KEY_F8, KEY_KANA, KEY_F7, "_", KEY_F6, ".", KEY_F5, "m", KEY_F4, "b", KEY_F3, "f", KEY_F2, "x", KEY_F1, KEY_SHIFT, KEY_CLR_HOME, KEY_DOWN + .byte KEY_RETURN, KEY_SHIFT, "@/o,inyvtcwz", KEY_ESC, KEY_GRPH, KEY_UP, " " + .byte "[", $5C, ":-lpu9g7r5seq1", KEY_RIGHT, KEY_DEL + .byte "]", KEY_STOP, ";^k0j8h6d4a3", KEY_CTR, "2", KEY_LEFT, KEY_INS +KeyboardUppercase: + .byte KEY_F8, KEY_KANA, KEY_F7, "_", KEY_F6, ">", KEY_F5, "M", KEY_F4, "B", KEY_F3, "F", KEY_F2, "X", KEY_F1, KEY_SHIFT, KEY_CLR_HOME, KEY_DOWN + .byte KEY_RETURN, KEY_SHIFT, "@?O>endobj +2 0 obj<>endobj +3 0 obj<>/F1<>>>>>/Contents 4 0 R>>endobj +4 0 obj<>stream +BT/F0 14 Tf 62 726 Td(The following is a letter Dan Kaminsky wrote to be printed and included with the)' ET +BT/F0 14 Tf 62 706 Td (Brainfu NES care packages he commissioned me to create and send out as gifts. Some)' ET +BT/F0 14 Tf 62 686 Td(of you may have received that care package and recognize the following letter.)' ET +BT/F0 14 Tf 62 646 Td(Dan had such a giant heart. He noticed me when I thought I was too low down to be)' ET +BT/F0 14 Tf 62 626 Td(worth noticing. He was so excited to make people happy.)'ET +BT/F0 14 Tf 62 586 Td(Dan has helped so many flames of curiosity grow. May each of us remember to pass)' ET +BT/F0 14 Tf 62 566 Td(that forward so more people will continue to be inspired to create, to think, to explore.)' ET +BT/F0 14 Tf 62 526 Td(And now Dan's letter.)' ET +BT/F0 14 Tf 62 502 Td(______________________________________________________________________)' ET +BT/F1 14 Tf 82 466 Td(Please find enclosed, to borrow a phrase, one moment of perfect beauty. I did not)' ET +BT/F1 14 Tf 62 446 Td(create it, but I did inspire it - from a random reference in a talk, through the hacker)' ET +BT/F1 14 Tf 62 426 Td(artist presently known as Vi Grey, to what's in the box before you.)' ET +BT/F1 14 Tf 82 386 Td(We never know who or what we'll inspire with our work. We rarely find out. It's a)' ET +BT/F1 14 Tf 62 366 Td(problem!)' ET +BT/F1 14 Tf 82 326 Td(So, thank you for all you've done, inspiring others to be our better and more)' ET +BT/F1 14 Tf 62 306 Td(awesome selves. We get the home we build. It may not always be easy, but you help)' ET +BT/F1 14 Tf 62 286 Td(build a brighter world. You have certainly brightened mine.)' ET +BT/F1 14 Tf 82 246 Td(Be well and play on! I look forward to the wonder you bring to the coming year.)' ET +BT/F1 14 Tf 282 186 Td(Your Friend In Mad Science and Glorious Hax,)' ET +BT/F1 14 Tf 466 166 Td(Dan Kaminsky)' ET +endstream +endobj +xref +0 5 +0000000000 65535 f +0000000017 00000 n +0000000060 00000 n +0000000133 00000 n +0000000317 00000 n +trailer<> +startxref +2283 +%%EOF diff --git a/DanKaminsky/src/portrait.asm b/DanKaminsky/src/portrait.asm new file mode 100644 index 0000000..2719e13 --- /dev/null +++ b/DanKaminsky/src/portrait.asm @@ -0,0 +1,151 @@ +; Copyright (C) 2021, Vi Grey +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +; SUCH DAMAGE. + +DrawPortrait: + jsr SetPalettes + jsr DrawPortraitNametable + jsr SetExtraSprites + lda #$01 + sta spritesEnabled + sta spriteNametable + sta needDraw + lda #$00 + sta backgroundNametable + sta updateDisabled + lda #SCREEN_PORTRAIT + sta screen + jsr ResetScroll + rts + +DrawPortraitNametable: + lda #<(PortraitNametable) + sta addr + lda #>(PortraitNametable) + sta (addr + 1) + ldy #$00 + ldx #$04 + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + sty PPU_ADDR +DrawPortraitNametableLoop: + lda (addr), Y + sta PPU_DATA + iny + bne DrawPortraitNametableLoop + inc (addr + 1) + dex + bne DrawPortraitNametableLoop + rts + +SetPalettes: + lda PPU_STATUS + lda #$3F + sta PPU_ADDR + lda #$00 + sta PPU_ADDR + ldx #$00 +SetPalettesLoop: + lda Palettes, X + sta PPU_DATA + inx + cpx #$20 + bne SetPalettesLoop + rts + +SetExtraSprites: + lda #$CF + sta #$204 + sta #$208 + sta #$20C + sta #$210 + sta #$214 + sta #$218 + lda #$BF + sta #$21C + sta #$224 + lda #$AF + sta #$220 + ldx #$03 + stx #$205 + inx + inx + stx #$209 + inx + inx + stx #$20D + inx + inx + stx #$211 + inx + inx + stx #$215 + inx + inx + stx #$219 + inx + inx + stx #$21D + inx + inx + stx #$221 + inx + inx + stx #$225 + lda #$00 + sta $206 + sta $20A + sta $20E + lda #$01 + sta $212 + sta $216 + lda #$02 + sta $21A + sta $21E + sta $222 + sta $226 + lda #$78 + sta $207 + lda #$80 + sta $20B + lda #$88 + sta $20F + lda #$90 + sta $213 + lda #$98 + sta $217 + lda #$A0 + sta $21B + sta $21F + lda #$A8 + sta $223 + sta $227 + rts + +PortraitNametable: + .incbin "graphics/portrait.nam" + +Palettes: + .incbin "graphics/palettes.pal" diff --git a/DanKaminsky/src/prg.asm b/DanKaminsky/src/prg.asm new file mode 100644 index 0000000..17ff395 --- /dev/null +++ b/DanKaminsky/src/prg.asm @@ -0,0 +1,152 @@ +; Copyright (C) 2021, Vi Grey +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +; SUCH DAMAGE. + +RESET: + sei + cld + ldx #$40 + stx APU_FRAME_COUNTER + ldx #$FF + txs + inx + lda #%00000110 + sta PPU_MASK + lda #%00000000 + sta PPU_CTRL + stx $4010 + ldy #$00 + +VBlankWait: + ldx #$02 +VBlankWaitLoop: + lda PPU_STATUS + bpl VBlankWaitLoop + dex + bne VBlankWaitLoop + +InitializeCPURAM: + ldx #$00 +InitializeCPURAMLoop: + lda #$00 + sta $0000, X + sta $0100, X + sta $0300, X + sta $0400, X + sta $0500, X + sta $0600, X + sta $0700, X + lda #$FE + sta $200, X + inx + bne InitializeCPURAMLoop + jsr DrawPortrait + +Forever: + jmp Forever + +NMI: + pha + txa + pha + tya + pha + lda #$00 + sta PPU_OAM_ADDR + lda #$02 + sta OAM_DMA + inc frames + lda needDraw + beq NMISkipDraw + lda screen + cmp #SCREEN_BRAINFU_MAIN + bne NMISkipBrainfuMain + jsr DrawCursor + jmp NMIDraw +NMISkipBrainfuMain: + cmp #SCREEN_BRAINFU_INSERT + bne NMISkipBrainfuInsert + jsr DrawInsertByte +NMISkipBrainfuInsert: +NMIDraw: + lda PPU_STATUS + jsr Draw + jsr ResetScroll + dec needDraw +NMISkipDraw: + lda updateDisabled + bne NMISkipUpdate + jsr Update +NMISkipUpdate: +NMIDone: + pla + tay + pla + tax + pla + rti + +Update: + jsr ResetControllerTypes + jsr PollIOInput + jsr InputsToControllers + jsr DetectKeyboard + jsr GetKeysPressed + jsr KeysPressedToKeyName + jsr KeysPressedNewHandler + jsr KeysPressedNewNameHandler + lda screen + cmp #SCREEN_PORTRAIT + bne UpdateNotScreenPortrait + jsr CheckKCode + jsr CheckKCodeKeyboard + rts +UpdateNotScreenPortrait: + cmp #SCREEN_BRAINFU_MAIN + bne UpdateNotScreenBrainfuMain + jsr ForceDrawCursor + jsr HandleKeyboardPressThisFrame + jsr HandleControllerPressThisFrame + rts +UpdateNotScreenBrainfuMain: + cmp #SCREEN_BRAINFU_OTHER + bne UpdateNotScreenBrainfuOther + jsr HandleBrainfuOtherReturn + jsr HandleBrainfuOtherStart + rts +UpdateNotScreenBrainfuOther: + cmp #SCREEN_BRAINFU_INSERT + bne UpdateNotScreenBrainfuInsert + jsr HandleBrainfuInsertKeyboard + jsr HandleBrainfuInsertController + rts +UpdateNotScreenBrainfuInsert: + rts + +.include "draw.asm" +.include "portrait.asm" +.include "io.asm" +.include "controllers.asm" +.include "brainfu.asm" +.include "frames.asm" diff --git a/DanKaminsky/src/ram.asm b/DanKaminsky/src/ram.asm new file mode 100644 index 0000000..8232323 --- /dev/null +++ b/DanKaminsky/src/ram.asm @@ -0,0 +1,111 @@ +; Copyright (C) 2021, Vi Grey +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +; ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +; SUCH DAMAGE. + +.enum $0000 + printAddr dsb 2 + printRow dsb 1 + printCol dsb 1 + instructionAddr dsb 2 + instructionAddrLast dsb 2 + instructionAddrTmp dsb 2 + controller1 dsb 1 + controller1LastFrame dsb 1 + needDraw dsb 1 + updateDisabled dsb 1 + disallowA dsb 1 + frames dsb 1 + backgroundNametable dsb 1 + spriteNametable dsb 1 + spritesEnabled dsb 1 + kcode dsb 1 + addr dsb 2 + instructionRow dsb 1 + instructionCol dsb 1 + screen dsb 1 + instructionInsert dsb 1 + instructionVal dsb 1 + processing dsb 1 + errorType dsb 1 + delTimer dsb 1 + selTimer dsb 1 + delPressed dsb 1 + delPressedLastFrame dsb 1 +.ende + +.enum $0030 + instructionPointer dsb 2 + loopCount dsb 2 + memoryPointer dsb 2 + plusHappened dsb 1 + returnPressed dsb 1 + instructionHappened dsb 1 + confirmHappened dsb 1 + insertHappened dsb 1 + insertPointer dsb 1 +.ende + +.enum $0040 + ; I/O Device 1 - $4016 + io1D0 dsb IO_POLL_LENGTH + io1D1 dsb IO_POLL_LENGTH + io1D2 dsb IO_POLL_LENGTH + io1D3 dsb IO_POLL_LENGTH + io1D4 dsb IO_POLL_LENGTH + ; I/O Device 2 - $4017 + io2D0 dsb IO_POLL_LENGTH + io2D1 dsb IO_POLL_LENGTH + io2D2 dsb IO_POLL_LENGTH + io2D3 dsb IO_POLL_LENGTH + io2D4 dsb IO_POLL_LENGTH + + controllers dsb 4 + controllersLastFrame dsb 4 + + controllerGlobalFlags dsb 1 + controller1Type dsb 1 + controller2Type dsb 1 + controller3Type dsb 1 + controller4Type dsb 1 + + keysPressed dsb 5 + keysPressedLastFrame dsb 5 + keysPressedOffset dsb 1 + shiftPressed dsb 1 + currentKeyCheck dsb 1 + currentKeyOffset dsb 1 + + keysPressedName dsb 5 + keysPressedNameLastFrame dsb 5 + keyPointer dsb 1 +.ende + +.enum $00A0 + keysPressedNew dsb 5 + keysPressedNewName dsb 5 +.ende + +.enum $0200 + instructions dsb 1024 +.ende