Commit: e749ad3e23ee142e62d7923c514d86410aa89896 Author: Vi Grey Date: 2022-06-05 07:39 UTC Summary: Initial commit CHANGELOG.txt | 107 ++++++ LICENSE | 13 + Makefile | 39 ++ README.md | 14 + bin/demo/a-knights-tour-20200903_0.nes | Bin 0 -> 40976 bytes bin/demo/a-knights-tour-20200905_0.nes | Bin 0 -> 40976 bytes bin/demo/a-knights-tour-20200907_0.nes | Bin 0 -> 40976 bytes bin/demo/a-knights-tour-20200910_0.nes | Bin 0 -> 65577 bytes bin/demo/a-knights-tour-20200911_0.nes | Bin 0 -> 66195 bytes bin/demo/a-knights-tour-20201124_0.nes | Bin 0 -> 70557 bytes bin/demo/a-knights-tour-20201125_0.nes | Bin 0 -> 1025047 bytes bin/demo/a-knights-tour-20201125_1.nes | Bin 0 -> 1025399 bytes bin/demo/a-knights-tour-20201130_0.nes | Bin 0 -> 1026965 bytes bin/demo/a-knights-tour-20201130_1.nes | Bin 0 -> 1027011 bytes current.txt | 1 + proto-date | Bin 0 -> 1709931 bytes proto-date.go | 111 ++++++ src/a-knights-tour.asm | 24 ++ src/board.asm | 1525 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/controller.asm | 322 +++++++++++++++++ src/defs.asm | 90 +++++ src/draw.asm | 97 +++++ src/frames.asm | 26 ++ src/graphics.asm | 219 ++++++++++++ src/graphics/options.atr | Bin 0 -> 64 bytes src/graphics/options.nam | Bin 0 -> 960 bytes src/graphics/tileset.chr | Bin 0 -> 8192 bytes src/graphics/title.atr | Bin 0 -> 64 bytes src/graphics/title.nam | Bin 0 -> 1024 bytes src/knight.asm | 146 ++++++++ src/math.asm | 20 ++ src/mouse.asm | 324 +++++++++++++++++ src/options.asm | 427 ++++++++++++++++++++++ src/position.asm | 787 +++++++++++++++++++++++++++++++++++++++++ src/powerpad.asm | 100 ++++++ src/prg.asm | 191 ++++++++++ src/ram.asm | 126 +++++++ src/reset.asm | 49 +++ src/rng.asm | 42 +++ src/score.asm | 166 +++++++++ src/scorecode.asm | 13 + src/screen.asm | 51 +++ src/time.asm | 135 +++++++ src/title.asm | 384 ++++++++++++++++++++ src/update.asm | 117 ++++++ 45 files changed, 5666 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000..c6817a0 --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,107 @@ +# Changelog + + +## [0.0.9] - 2020-11-30_1 +### Added +- 1 to CHR ROM so year 2021 can be drawn if need be + +### Fixed +- Replace 0x1d, 0x1e, and 0x1f in title.nam with 0x00 + + +## [0.0.8] - 2020-11-30_0 +### Added +- Clearing a board adds time to timer in Score Mode + +### Changed +- Score and Top Score to 4 digits instead of 2 in Score Mode +- Timer decrements instead of increments in Score Mode + +### Fixed +- Set version number to 0 in current.txt if new date in proto-date program + + +## [0.0.7] - 2020-11-25_1 +### Added +- Implement End Position option, which chooses a random end tile position that is the opposite color of the starting knight position + +### Changed +- Place _V at the end of dates in CHANGELOG.txt to match YYYYMMDD_V format of ROMs in bin/demo and PROTO content of the title screens in CHR ROM +- Refactor option value in memory toggle code +- Refactor option ON/OFF draw code +- Refactor option ON/OFF toggle controller code + + +## [0.0.6] - 2020-11-25_0 +### Added +- Add proto-date.go, proto-date, and current.txt file to automate the PROTO content on the title screen in CHR ROM, updating YYYYMMDD_V with correct date and version +- Add setup rule to Makefile, which is used to automatically update the PROTO YYYYMMDD_V content of the title screen in CHR ROM. +- Add save rule to Makefile, which copies bin/a-knights-tour.nes to bin/demo/a-knights-tour-YYYYMMDD_V.nes + +### Changed +- Re-order Makefile rules to make them more correct to order used in command line +- Assume dates for CHANGELOG.txt and the PROTO YYYYMMDD_V content of the title screen in CHR ROM are based on UTC time. + +### Fixed +- Change FIXED to Fixed on [0.0.5] + + +## [0.0.5] - 2020-11-24_0 +### Fixed +- Decouple main code from NMI +- Initialize Can Fall option at POWER ON +- Keep Invisible Guides option on RESET +- Blank screen by blacking out entire palette during screen change +- Remove version from PROTO content on title screen in CHR ROM, keeping only PROTO-YYYYMMDD_V + + +## [0.0.4] - 2020-09-11_0 +### Added +- Implement Can Fall option, which allows the user to choose to go to a broken tile, which ends the game +- Implement Invisible Guides option, which makes the dotted lines and all corners of the 8 guide positions invisible + + +## [0.0.3] - 2020-09-10_0 +### Added +- Add SNES Mouse support for title screen +- Add Options Menu +- Add SNES Mouse support for Options Menu +- Implement Left Handed option +- Implement Invisible Cracks option +- Make Left Handed option work for Standard Controller, SNES Mouse, and Power Pad +- Add Polyglot (ZIP) File Functionality. Make first 40KB + 16B of file NES ROM data and rest of data valid ZIP file data that contains the source code for the ROM. +- Add zip argument for Makefile to make NES+ZIP polyglot file + +### Fixed +- Change [0.0.4] to [0.0.2] for 2020-09-07 build. + + +## [0.0.2] - 2020-09-07_0 +### Added +- Title screen +- Ability to start score mode from title screen +- Standard Controller, Power Pad, and SNES Mouse controller support for starting score mode only (movement in title screen not yet implemented) + +### Fixed +- Fix bug where corners may be off the center while the knight is animating (Bug reappeared and was possibly not properly patched initially) +- Fix bug where plugging in SNES mouse after the board is started will cause an infinite click glitch +- 0.0.1 date from 2020-09-04 to 2020-09-05 + + +## [0.0.1] - 2020-09-05_0 +### Added +- Power Pad support - 4 = A, 2/3 = Up, 10/11 = Down, 5 = Left, 8 = Right +- Random Number Generator (RNG) +- Seed RNG entropy with button inputs +- Use RNG to randomize knight starting position when making a new board +- Use RNG to randomize which position is selected on the board when making a new board + +### Fixed +- Fix bug where top score remaining even if that board round is not finished and game is reset +- Fix bug where corners may be off the center while the knight is animating +- Fix bug where dotted lines appear 1 frame after board is drawn for 1 frame when the controller is set to SNES Mouse + + +## [0.0.0] - 2020-09-03_0 +### Added +- Initial Release diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..045870b --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright (C) 2020-2022, Vi Grey +All rights reserved. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dd0e4f6 --- /dev/null +++ b/Makefile @@ -0,0 +1,39 @@ +# Copyright (C) 2020, Vi Grey +# All rights reserved. + +PKG_NAME := a-knights-tour +CURRENTDIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) + +all: + mkdir -p $(CURRENTDIR)bin; \ + cd $(CURRENTDIR)src; \ + asm $(PKG_NAME).asm ../bin/$(PKG_NAME).nes; \ + +clean: + rm -f -- $(CURRENTDIR)bin/$(PKG_NAME).nes*; \ + rm -rf -- $(CURRENTDIR)bin/build; \ + +setup: + $(CURRENTDIR)proto-date; \ + +zip: + mkdir -p $(CURRENTDIR)bin; \ + mkdir -p $(CURRENTDIR)bin/build; \ + rm -f -- $(CURRENTDIR)bin/$(PKG_NAME).nes*; \ + rm -f -- $(CURRENTDIR)bin/build/*; \ + rm -rf -- /tmp/$(PKG_NAME); \ + cp -r $(CURRENTDIR) /tmp/$(PKG_NAME); \ + cp -r /tmp/$(PKG_NAME) $(CURRENTDIR)bin/build/./; \ + rm -rf -- $(CURRENTDIR)bin/build/$(PKG_NAME)/bin/demo; \ + cd $(CURRENTDIR)bin/build; \ + zip -r $(PKG_NAME).zip $(PKG_NAME); \ + cd $(CURRENTDIR)src; \ + asm $(PKG_NAME).asm ../bin/build/$(PKG_NAME).nes; \ + cd $(CURRENTDIR)bin/build; \ + cat $(PKG_NAME).nes > $(PKG_NAME)-build.nes; \ + cat $(PKG_NAME).zip >> $(PKG_NAME)-build.nes; \ + zip -F $(PKG_NAME)-build.nes --out $(PKG_NAME)-final.zip; \ + cp $(PKG_NAME)-final.zip ../$(PKG_NAME).nes; \ + +save: + cp $(CURRENTDIR)bin/$(PKG_NAME).nes $(CURRENTDIR)bin/demo/$(PKG_NAME)-$$(head -c 10 $(CURRENTDIR)current.txt).nes; \ diff --git a/README.md b/README.md new file mode 100644 index 0000000..eb37fe7 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +I am placing this project here in case I don't work on it anymore. Previous builds are available in bin/demo + +You can build the ROM in the root directory (the directory this file is in) and using `make`. If you use `make zip`, the NES ROM will also be a ZIP file that contains the source code of the ROM, but also recent versions of FCEUX will not play that ROM file (older versions [I don't remember which version at this moment] should play it). Mesen should be able to play any of these ROMs. + +Do with this as you wish. I hate to admit it, but I'm abandoning this project and don't think I'll come back to it, due to other projects taking my time. + +The inspiration for this project was this youtube video by Nelson Dellis. https://www.youtube.com/watch?v=O1ZtjLDog7M. + + +The assembler I was using was 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** + +If I remember correctly, I have Standard NES controller, NES Power Pad, and SNES Mouse support built in already. + +My apologies for so few comments. diff --git a/bin/demo/a-knights-tour-20200903_0.nes b/bin/demo/a-knights-tour-20200903_0.nes new file mode 100644 index 0000000..2a71459 Binary files /dev/null and b/bin/demo/a-knights-tour-20200903_0.nes differ diff --git a/bin/demo/a-knights-tour-20200905_0.nes b/bin/demo/a-knights-tour-20200905_0.nes new file mode 100644 index 0000000..2098c91 Binary files /dev/null and b/bin/demo/a-knights-tour-20200905_0.nes differ diff --git a/bin/demo/a-knights-tour-20200907_0.nes b/bin/demo/a-knights-tour-20200907_0.nes new file mode 100644 index 0000000..f5a0f6d Binary files /dev/null and b/bin/demo/a-knights-tour-20200907_0.nes differ diff --git a/bin/demo/a-knights-tour-20200910_0.nes b/bin/demo/a-knights-tour-20200910_0.nes new file mode 100644 index 0000000..08b2461 Binary files /dev/null and b/bin/demo/a-knights-tour-20200910_0.nes differ diff --git a/bin/demo/a-knights-tour-20200911_0.nes b/bin/demo/a-knights-tour-20200911_0.nes new file mode 100644 index 0000000..caf173f Binary files /dev/null and b/bin/demo/a-knights-tour-20200911_0.nes differ diff --git a/bin/demo/a-knights-tour-20201124_0.nes b/bin/demo/a-knights-tour-20201124_0.nes new file mode 100644 index 0000000..6db3c8a Binary files /dev/null and b/bin/demo/a-knights-tour-20201124_0.nes differ diff --git a/bin/demo/a-knights-tour-20201125_0.nes b/bin/demo/a-knights-tour-20201125_0.nes new file mode 100644 index 0000000..d66961e Binary files /dev/null and b/bin/demo/a-knights-tour-20201125_0.nes differ diff --git a/bin/demo/a-knights-tour-20201125_1.nes b/bin/demo/a-knights-tour-20201125_1.nes new file mode 100644 index 0000000..19f90e9 Binary files /dev/null and b/bin/demo/a-knights-tour-20201125_1.nes differ diff --git a/bin/demo/a-knights-tour-20201130_0.nes b/bin/demo/a-knights-tour-20201130_0.nes new file mode 100644 index 0000000..9b9442f Binary files /dev/null and b/bin/demo/a-knights-tour-20201130_0.nes differ diff --git a/bin/demo/a-knights-tour-20201130_1.nes b/bin/demo/a-knights-tour-20201130_1.nes new file mode 100644 index 0000000..c990043 Binary files /dev/null and b/bin/demo/a-knights-tour-20201130_1.nes differ diff --git a/current.txt b/current.txt new file mode 100644 index 0000000..a54a798 --- /dev/null +++ b/current.txt @@ -0,0 +1 @@ +20201130_1 diff --git a/proto-date b/proto-date new file mode 100755 index 0000000..746e9dd Binary files /dev/null and b/proto-date differ diff --git a/proto-date.go b/proto-date.go new file mode 100644 index 0000000..7871058 --- /dev/null +++ b/proto-date.go @@ -0,0 +1,111 @@ +package main + +import ( + "bytes" + //"fmt" + "io/ioutil" + "strconv" + "time" +) + +var ( + px0 = [8]uint8{14, 10, 10, 10, 14, 0, 0, 0} + px1 = [8]uint8{4, 12, 4, 4, 14, 0, 0, 0} + px2 = [8]uint8{14, 2, 14, 8, 14, 0, 0, 0} + px3 = [8]uint8{14, 2, 14, 2, 14, 0, 0, 0} + px4 = [8]uint8{10, 10, 14, 2, 2, 0, 0, 0} + px5 = [8]uint8{14, 8, 14, 2, 14, 0, 0, 0} + px6 = [8]uint8{14, 8, 14, 10, 14, 0, 0, 0} + px7 = [8]uint8{14, 2, 2, 2, 2, 0, 0, 0} + px8 = [8]uint8{14, 10, 14, 10, 14, 0, 0, 0} + px9 = [8]uint8{14, 10, 14, 2, 2, 0, 0, 0} + pxu = [8]uint8{0, 0, 0, 0, 14, 0, 0, 0} + pxMap = map[byte][8]uint8{'0': px0, '1': px1, '2': px2, + '3': px3, '4': px4, '5': px5, '6': px6, '7': px7, + '8': px8, '9': px9, '_': pxu} + + versionData string + lastDateString string + curDateString string + protoValue string + chrValues []byte +) + +func openCurrentTxt() { + versionDataBytes, _ := ioutil.ReadFile("current.txt") + versionDataBytes = bytes.Replace(versionDataBytes, []byte("\r\n"), []byte{}, -1) + versionDataBytes = bytes.Replace(versionDataBytes, []byte("\n"), []byte{}, -1) + if len(versionDataBytes) > 9 { + lastDateString = string(versionDataBytes[:8]) + versionData = string(versionDataBytes[9:]) + } else { + lastDateString = "00000000" + versionData = "0" + } +} + +func getCurDateString() { + curTime := time.Now().UTC() + curDateString = curTime.Format("20060102") +} + +func compareLastCurDate() { + if lastDateString == curDateString { + versionDataInt, err := strconv.Atoi(versionData) + if err != nil { + versionData = "0" + } else { + versionData = strconv.Itoa(versionDataInt + 1) + } + } else { + versionData = "0" + } + protoValue = curDateString + "_" + versionData +} + +func writeToCurrentTxt() { + ioutil.WriteFile("current.txt", []byte(protoValue+"\n"), 0644) +} + +func makePixelArray() { + bytesVals := [][]uint8{} + tileVals := []uint8{0, 0, 0, 0, 0, 0, 0, 0} + for x, y := range []byte(protoValue) { + if x%2 == 0 { + for i := 0; i < 8; i++ { + tileVals[i] += pxMap[y][i] << 4 + } + if x == len([]byte(protoValue))-1 { + bytesVals = append(bytesVals, tileVals) + tileVals = []uint8{0, 0, 0, 0, 0, 0, 0, 0} + } + } else { + for i := 0; i < 8; i++ { + tileVals[i] += pxMap[y][i] + } + bytesVals = append(bytesVals, tileVals) + tileVals = []uint8{0, 0, 0, 0, 0, 0, 0, 0} + } + } + for _, m := range bytesVals { + chrValues = append(chrValues, append(m, m...)...) + } +} + +func rewriteTilesetCHR() { + tilesetData, _ := ioutil.ReadFile("src/graphics/tileset.chr") + if len(tilesetData) == 8192 && 0x1f60+len(chrValues) < 8192-6 { + tilesetDataTmp := append(tilesetData[:0x1f60], chrValues...) + tilesetDataTmp = append(tilesetDataTmp, tilesetData[0x1f60+len(chrValues):]...) + ioutil.WriteFile("src/graphics/tileset.chr", tilesetDataTmp, 0644) + } +} + +func main() { + openCurrentTxt() + getCurDateString() + compareLastCurDate() + writeToCurrentTxt() + makePixelArray() + rewriteTilesetCHR() +} diff --git a/src/a-knights-tour.asm b/src/a-knights-tour.asm new file mode 100644 index 0000000..0119a8d --- /dev/null +++ b/src/a-knights-tour.asm @@ -0,0 +1,24 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + + .db "NES", $1A + .db $02 + .db $01 + .db $00 + .db $00 + .db 0, 0, 0, 0, 0, 0, 0, 0 + +.include "ram.asm" +.include "defs.asm" + +.base $8000 + +.include "prg.asm" + + .pad CALLBACK, #$FF + .dw NMI + .dw RESET + .dw 0 + +.base $0000 + .incbin "graphics/tileset.chr" diff --git a/src/board.asm b/src/board.asm new file mode 100644 index 0000000..088d6ca --- /dev/null +++ b/src/board.asm @@ -0,0 +1,1525 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +ResetTimeScore: + ; Set score to 0 + lda #$00 + sta score + sta (score + 1) + sta (score + 2) + sta (score + 3) + ; Set time to 0 + lda #$01 + sta time + lda #$02 + sta (time + 1) + lda #$00 + sta (time + 2) + sta timeFrame + rts + +StartBoardScreen: + ; Turn screen completely black for 1 frame to avoid flicker/tear + jsr BlankScreen + ; Turn screen and NMI off + jsr Blank + ; Set screen to SCREEN_BOARD + lda #SCREEN_BOARD + sta screen + ; Set sprite table to pattern table 01 + lda #$01 + sta spriteTable + ; Set background table to pattern table 00 + lda #$00 + sta backgroundTable + ; reset Current Board Score + sta currentBoardScore + sta (currentBoardScore + 1) + ; TODO - Consider a situation where started is not needed + sta started + ; Clear broken 64 bit flags + sta broken + sta (broken + 1) + sta (broken + 2) + sta (broken + 3) + sta (broken + 4) + sta (broken + 5) + sta (broken + 6) + sta (broken + 7) + ; Clear end variable, as is not end + sta end + ; Reset positionFrame to zero for animation + sta positionFrame + ; Set all 64 positions on chess board to 1 for availablility + lda #$FF + sta availablePositions + ; Initialize controller1 last frame to say all buttons pressed + sta controller1D0LastFrame + sta (controller1D0LastFrame + 1) + ; Run LFSR to get new random number + jsr LFSR + ; Set knight position based on random number MOD 64 + lda lfsr + and #%00111111 + sta knightPosition + sta knightPositionNew + ; Run LFSR to get new random number + jsr LFSR + ; Set end position based on random number MOD 64 + lda lfsr + + and #%00111110 + sta endPosition + ; Get knightPosition last bit to make sure endPosition is opposite color + eor knightPosition + and #%00001000 + eor #%00001000 + lsr + lsr + lsr + eor knightPosition + and #%00000001 + ora endPosition + sta endPosition + ; Run LFSR to get new random number + jsr LFSR + ; Set selector init position based on random number MOD 8 + lda lfsr + and #%00000111 + sta position + ; Check if controller is a SNES mouse + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + bne StartBoardScreenNotSNESMouse + ; Check if controller is a SNES mouse + lda snesMouseReady + beq StartBoardScreenNotSNESMouse + ; Draw cursor if SNES mouse is ready + jsr DrawCursor +StartBoardScreenNotSNESMouse: + jsr GetAvailablePositions + jsr CheckDisallowedPositions + ; + jsr ResetPPURAM + jsr SetBoardPalette + jsr DrawChessBoard + jsr DrawKnight + jsr DrawEndPosition + jsr AdjustPosition + jsr DrawCorners + jsr DisableDottedLines + jsr ManageInvisibleGuides + + jsr DrawBoardTopBar + ;jsr UpdateDone + lda #$01 + sta needDraw + ; Re-enable NMI + jsr ResetScroll + rts + + + +DrawBoardTopBar: + jsr DrawScore + jsr DrawTopScore + jsr DrawTimer + rts + +BoardEveryFrame: + jsr DrawScore + jsr DrawTopScore + jsr DrawTimer + lda drawCrack + beq BoardEveryFrameNotDrawCrack + ; Draw crack if drawCrack flag is set to 1 + jsr DrawCrack +BoardEveryFrameNotDrawCrack: + ; End of Board screen code + rts + +SetBoardPalette: + lda PPU_STATUS + lda #$3F + sta PPU_ADDR + lda #$00 + sta PPU_ADDR + ldx #$04 +SetBoardPaletteBackgroundLoop: + lda #$0F + sta PPU_DATA + sta PPU_DATA + sta PPU_DATA + lda #$30 + sta PPU_DATA + dex + bne SetBoardPaletteBackgroundLoop + lda #$0F + sta PPU_DATA + sta PPU_DATA + sta PPU_DATA + lda #$30 + sta PPU_DATA + ldx #$03 +SetBoardPaletteSpriteLoop: + lda #$0F + sta PPU_DATA + lda #$11 + sta PPU_DATA + lda #$21 + sta PPU_DATA + lda #$30 + sta PPU_DATA + dex + bne SetBoardPaletteSpriteLoop + rts + +DrawChessBoard: + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$E7 + sta PPU_ADDR + ldx #$80 + stx PPU_DATA + ldy #$10 + inx +DrawChessBoardTopEdge: + stx PPU_DATA + dey + bne DrawChessBoardTopEdge + inx + stx PPU_DATA + ldy #"8" +;ROW 1a + lda PPU_STATUS + lda #$21 + sta PPU_ADDR + lda #$07 + sta PPU_ADDR + lda #$90 + sta PPU_DATA + ldx #$01 + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 1b + lda PPU_STATUS + lda #$21 + sta PPU_ADDR + lda #$26 + sta PPU_ADDR + sty PPU_DATA + dey + lda #$90 + sta PPU_DATA + ldx #$01 + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 2a + lda PPU_STATUS + lda #$21 + sta PPU_ADDR + lda #$47 + sta PPU_ADDR + lda #$90 + sta PPU_DATA + ldx #$00 + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 2b + lda PPU_STATUS + lda #$21 + sta PPU_ADDR + lda #$66 + sta PPU_ADDR + sty PPU_DATA + dey + lda #$90 + sta PPU_DATA + ldx #$00 + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 3a + lda PPU_STATUS + lda #$21 + sta PPU_ADDR + lda #$87 + sta PPU_ADDR + lda #$90 + sta PPU_DATA + ldx #$01 + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 3b + lda PPU_STATUS + lda #$21 + sta PPU_ADDR + lda #$A6 + sta PPU_ADDR + sty PPU_DATA + dey + lda #$90 + sta PPU_DATA + ldx #$01 + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 4a + lda PPU_STATUS + lda #$21 + sta PPU_ADDR + lda #$C7 + sta PPU_ADDR + lda #$90 + sta PPU_DATA + ldx #$00 + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 4b + lda PPU_STATUS + lda #$21 + sta PPU_ADDR + lda #$E6 + sta PPU_ADDR + sty PPU_DATA + dey + lda #$90 + sta PPU_DATA + ldx #$00 + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 5a + lda PPU_STATUS + lda #$22 + sta PPU_ADDR + lda #$07 + sta PPU_ADDR + lda #$90 + sta PPU_DATA + ldx #$01 + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 5b + lda PPU_STATUS + lda #$22 + sta PPU_ADDR + lda #$26 + sta PPU_ADDR + sty PPU_DATA + dey + lda #$90 + sta PPU_DATA + ldx #$01 + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 6a + lda PPU_STATUS + lda #$22 + sta PPU_ADDR + lda #$47 + sta PPU_ADDR + lda #$90 + sta PPU_DATA + ldx #$00 + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 6b + lda PPU_STATUS + lda #$22 + sta PPU_ADDR + lda #$66 + sta PPU_ADDR + sty PPU_DATA + dey + lda #$90 + sta PPU_DATA + ldx #$00 + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 7a + lda PPU_STATUS + lda #$22 + sta PPU_ADDR + lda #$87 + sta PPU_ADDR + lda #$90 + sta PPU_DATA + ldx #$01 + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 7b + lda PPU_STATUS + lda #$22 + sta PPU_ADDR + lda #$A6 + sta PPU_ADDR + sty PPU_DATA + dey + lda #$90 + sta PPU_DATA + ldx #$01 + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 8a + lda PPU_STATUS + lda #$22 + sta PPU_ADDR + lda #$C7 + sta PPU_ADDR + lda #$90 + sta PPU_DATA + ldx #$00 + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;ROW 8b + lda PPU_STATUS + lda #$22 + sta PPU_ADDR + lda #$E6 + sta PPU_ADDR + sty PPU_DATA + dey + lda #$90 + sta PPU_DATA + ldx #$00 + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + dex + stx PPU_DATA + stx PPU_DATA + inx + stx PPU_DATA + stx PPU_DATA + lda #$92 + sta PPU_DATA +;Bottom Row + lda PPU_STATUS + lda #$23 + sta PPU_ADDR + lda #$07 + sta PPU_ADDR + ldx #$A0 + stx PPU_DATA + ldy #$10 + inx +DrawChessBoardBottomEdge: + stx PPU_DATA + dey + bne DrawChessBoardBottomEdge + inx + stx PPU_DATA + lda PPU_STATUS + lda #$23 + sta PPU_ADDR + lda #$28 + sta PPU_ADDR + lda #$00 + ldx #"A" + stx PPU_DATA + sta PPU_DATA + inx + stx PPU_DATA + sta PPU_DATA + inx + stx PPU_DATA + sta PPU_DATA + inx + stx PPU_DATA + sta PPU_DATA + inx + stx PPU_DATA + sta PPU_DATA + inx + stx PPU_DATA + sta PPU_DATA + inx + stx PPU_DATA + sta PPU_DATA + inx + stx PPU_DATA + sta PPU_DATA + rts + +DrawKnight: + lda knightPosition + and #%00111000 + asl + clc + adc #$3F + sta KNIGHT_TL + lda #$01 + sta (KNIGHT_TL + 1) + lda #$00 + sta (KNIGHT_TL + 2) + lda knightPosition + and #%00000111 + asl + asl + asl + asl + clc + adc #$40 + sta (KNIGHT_TL + 3) + + lda KNIGHT_TL + sta KNIGHT_TR + lda (KNIGHT_TL + 1) + clc + adc #$01 + sta (KNIGHT_TR + 1) + lda (KNIGHT_TL + 2) + sta (KNIGHT_TR + 2) + lda (KNIGHT_TL + 3) + clc + adc #$08 + sta (KNIGHT_TR + 3) + + lda KNIGHT_TL + clc + adc #$08 + sta KNIGHT_BL + lda (KNIGHT_TL + 1) + clc + adc #$10 + sta (KNIGHT_BL + 1) + lda (KNIGHT_TL + 2) + sta (KNIGHT_BL + 2) + lda (KNIGHT_TL + 3) + sta (KNIGHT_BL + 3) + + lda KNIGHT_TL + clc + adc #$08 + sta KNIGHT_BR + lda (KNIGHT_TL + 1) + clc + adc #$11 + sta (KNIGHT_BR + 1) + lda (KNIGHT_TL + 2) + sta (KNIGHT_BR + 2) + lda (KNIGHT_TL + 3) + clc + adc #$08 + sta (KNIGHT_BR + 3) + + rts + + +DrawCorners: +DrawCornersPosition0: + lda #$00 + jsr CheckAPositionAvailable + bne DrawCornersPosition0Continue + lda #$FE + sta (POSITION_0) + sta (POSITION_0 + 4) + sta (POSITION_0 + 8) + sta (POSITION_0 + 12) + jmp DrawCornersPosition1 +DrawCornersPosition0Continue: +; Position 0 + lda KNIGHT_TL + sec + sbc #$20 + sta POSITION_0 + lda #$03 + sta (POSITION_0 + 1) + lda #$00000001 + sta (POSITION_0 + 2) + lda (KNIGHT_TL + 3) + sec + sbc #$10 + sta (POSITION_0 + 3) + + lda POSITION_0 + sta (POSITION_0 + 4) + lda (POSITION_0 + 1) + sta (POSITION_0 + 5) + lda (POSITION_0 + 2) + eor #%01000000 + sta (POSITION_0 + 6) + lda (POSITION_0 + 3) + clc + adc #$08 + sta (POSITION_0 + 7) + + lda POSITION_0 + clc + adc #$08 + sta (POSITION_0 + 8) + lda (POSITION_0 + 1) + sta (POSITION_0 + 9) + lda (POSITION_0 + 2) + eor #%10000000 + sta (POSITION_0 + 10) + lda (POSITION_0 + 3) + sta (POSITION_0 + 11) + + lda POSITION_0 + clc + adc #$08 + sta (POSITION_0 + 12) + lda (POSITION_0 + 1) + sta (POSITION_0 + 13) + lda (POSITION_0 + 2) + eor #%11000000 + sta (POSITION_0 + 14) + lda (POSITION_0 + 3) + clc + adc #$08 + sta (POSITION_0 + 15) + +DrawCornersPosition1: + lda #$01 + jsr CheckAPositionAvailable + bne DrawCornersPosition1Continue + lda #$FE + sta (POSITION_1) + sta (POSITION_1 + 4) + sta (POSITION_1 + 8) + sta (POSITION_1 + 12) + jmp DrawCornersPosition2 +DrawCornersPosition1Continue: +; Position 1 + lda KNIGHT_TL + sec + sbc #$20 + sta POSITION_1 + lda #$03 + sta (POSITION_1 + 1) + lda #$00000001 + sta (POSITION_1 + 2) + lda (KNIGHT_TL + 3) + clc + adc #$10 + sta (POSITION_1 + 3) + + lda POSITION_1 + sta (POSITION_1 + 4) + lda (POSITION_1 + 1) + sta (POSITION_1 + 5) + lda (POSITION_1 + 2) + eor #%01000000 + sta (POSITION_1 + 6) + lda (POSITION_1 + 3) + clc + adc #$08 + sta (POSITION_1 + 7) + + lda POSITION_1 + clc + adc #$08 + sta (POSITION_1 + 8) + lda (POSITION_1 + 1) + sta (POSITION_1 + 9) + lda (POSITION_1 + 2) + eor #%10000000 + sta (POSITION_1 + 10) + lda (POSITION_1 + 3) + sta (POSITION_1 + 11) + + lda POSITION_1 + clc + adc #$08 + sta (POSITION_1 + 12) + lda (POSITION_1 + 1) + sta (POSITION_1 + 13) + lda (POSITION_1 + 2) + eor #%11000000 + sta (POSITION_1 + 14) + lda (POSITION_1 + 3) + clc + adc #$08 + sta (POSITION_1 + 15) + +DrawCornersPosition2: + lda #$02 + jsr CheckAPositionAvailable + bne DrawCornersPosition2Continue + lda #$FE + sta (POSITION_2) + sta (POSITION_2 + 4) + sta (POSITION_2 + 8) + sta (POSITION_2 + 12) + jmp DrawCornersPosition3 +DrawCornersPosition2Continue: +; Position 2 + lda KNIGHT_TL + sec + sbc #$10 + sta POSITION_2 + lda #$03 + sta (POSITION_2 + 1) + lda #$00000001 + sta (POSITION_2 + 2) + lda (KNIGHT_TL + 3) + clc + adc #$20 + sta (POSITION_2 + 3) + + lda POSITION_2 + sta (POSITION_2 + 4) + lda (POSITION_2 + 1) + sta (POSITION_2 + 5) + lda (POSITION_2 + 2) + eor #%01000000 + sta (POSITION_2 + 6) + lda (POSITION_2 + 3) + clc + adc #$08 + sta (POSITION_2 + 7) + + lda POSITION_2 + clc + adc #$08 + sta (POSITION_2 + 8) + lda (POSITION_2 + 1) + sta (POSITION_2 + 9) + lda (POSITION_2 + 2) + eor #%10000000 + sta (POSITION_2 + 10) + lda (POSITION_2 + 3) + sta (POSITION_2 + 11) + + lda POSITION_2 + clc + adc #$08 + sta (POSITION_2 + 12) + lda (POSITION_2 + 1) + sta (POSITION_2 + 13) + lda (POSITION_2 + 2) + eor #%11000000 + sta (POSITION_2 + 14) + lda (POSITION_2 + 3) + clc + adc #$08 + sta (POSITION_2 + 15) + +DrawCornersPosition3: + lda #$03 + jsr CheckAPositionAvailable + bne DrawCornersPosition3Continue + lda #$FE + sta (POSITION_3) + sta (POSITION_3 + 4) + sta (POSITION_3 + 8) + sta (POSITION_3 + 12) + jmp DrawCornersPosition4 +DrawCornersPosition3Continue: +; Position 3 + lda KNIGHT_TL + clc + adc #$10 + sta POSITION_3 + lda #$03 + sta (POSITION_3 + 1) + lda #$00000001 + sta (POSITION_3 + 2) + lda (KNIGHT_TL + 3) + clc + adc #$20 + sta (POSITION_3 + 3) + + lda POSITION_3 + sta (POSITION_3 + 4) + lda (POSITION_3 + 1) + sta (POSITION_3 + 5) + lda (POSITION_3 + 2) + eor #%01000000 + sta (POSITION_3 + 6) + lda (POSITION_3 + 3) + clc + adc #$08 + sta (POSITION_3 + 7) + + lda POSITION_3 + clc + adc #$08 + sta (POSITION_3 + 8) + lda (POSITION_3 + 1) + sta (POSITION_3 + 9) + lda (POSITION_3 + 2) + eor #%10000000 + sta (POSITION_3 + 10) + lda (POSITION_3 + 3) + sta (POSITION_3 + 11) + + lda POSITION_3 + clc + adc #$08 + sta (POSITION_3 + 12) + lda (POSITION_3 + 1) + sta (POSITION_3 + 13) + lda (POSITION_3 + 2) + eor #%11000000 + sta (POSITION_3 + 14) + lda (POSITION_3 + 3) + clc + adc #$08 + sta (POSITION_3 + 15) + +DrawCornersPosition4: + lda #$04 + jsr CheckAPositionAvailable + bne DrawCornersPosition4Continue + lda #$FE + sta (POSITION_4) + sta (POSITION_4 + 4) + sta (POSITION_4 + 8) + sta (POSITION_4 + 12) + jmp DrawCornersPosition5 +DrawCornersPosition4Continue: +; Position 4 + lda KNIGHT_TL + clc + adc #$20 + sta POSITION_4 + lda #$03 + sta (POSITION_4 + 1) + lda #$00000001 + sta (POSITION_4 + 2) + lda (KNIGHT_TL + 3) + clc + adc #$10 + sta (POSITION_4 + 3) + + lda POSITION_4 + sta (POSITION_4 + 4) + lda (POSITION_4 + 1) + sta (POSITION_4 + 5) + lda (POSITION_4 + 2) + eor #%01000000 + sta (POSITION_4 + 6) + lda (POSITION_4 + 3) + clc + adc #$08 + sta (POSITION_4 + 7) + + lda POSITION_4 + clc + adc #$08 + sta (POSITION_4 + 8) + lda (POSITION_4 + 1) + sta (POSITION_4 + 9) + lda (POSITION_4 + 2) + eor #%10000000 + sta (POSITION_4 + 10) + lda (POSITION_4 + 3) + sta (POSITION_4 + 11) + + lda POSITION_4 + clc + adc #$08 + sta (POSITION_4 + 12) + lda (POSITION_4 + 1) + sta (POSITION_4 + 13) + lda (POSITION_4 + 2) + eor #%11000000 + sta (POSITION_4 + 14) + lda (POSITION_4 + 3) + clc + adc #$08 + sta (POSITION_4 + 15) + +DrawCornersPosition5: + lda #$05 + jsr CheckAPositionAvailable + bne DrawCornersPosition5Continue + lda #$FE + sta (POSITION_5) + sta (POSITION_5 + 4) + sta (POSITION_5 + 8) + sta (POSITION_5 + 12) + jmp DrawCornersPosition6 +DrawCornersPosition5Continue: +; Position 5 + lda KNIGHT_TL + clc + adc #$20 + sta POSITION_5 + lda #$03 + sta (POSITION_5 + 1) + lda #$00000001 + sta (POSITION_5 + 2) + lda (KNIGHT_TL + 3) + sec + sbc #$10 + sta (POSITION_5 + 3) + + lda POSITION_5 + sta (POSITION_5 + 4) + lda (POSITION_5 + 1) + sta (POSITION_5 + 5) + lda (POSITION_5 + 2) + eor #%01000000 + sta (POSITION_5 + 6) + lda (POSITION_5 + 3) + clc + adc #$08 + sta (POSITION_5 + 7) + + lda POSITION_5 + clc + adc #$08 + sta (POSITION_5 + 8) + lda (POSITION_5 + 1) + sta (POSITION_5 + 9) + lda (POSITION_5 + 2) + eor #%10000000 + sta (POSITION_5 + 10) + lda (POSITION_5 + 3) + sta (POSITION_5 + 11) + + lda POSITION_5 + clc + adc #$08 + sta (POSITION_5 + 12) + lda (POSITION_5 + 1) + sta (POSITION_5 + 13) + lda (POSITION_5 + 2) + eor #%11000000 + sta (POSITION_5 + 14) + lda (POSITION_5 + 3) + clc + adc #$08 + sta (POSITION_5 + 15) + +DrawCornersPosition6: + lda #$06 + jsr CheckAPositionAvailable + bne DrawCornersPosition6Continue + lda #$FE + sta (POSITION_6) + sta (POSITION_6 + 4) + sta (POSITION_6 + 8) + sta (POSITION_6 + 12) + jmp DrawCornersPosition7 +DrawCornersPosition6Continue: +; Position 6 + lda KNIGHT_TL + clc + adc #$10 + sta POSITION_6 + lda #$03 + sta (POSITION_6 + 1) + lda #$00000001 + sta (POSITION_6 + 2) + lda (KNIGHT_TL + 3) + sec + sbc #$20 + sta (POSITION_6 + 3) + + lda POSITION_6 + sta (POSITION_6 + 4) + lda (POSITION_6 + 1) + sta (POSITION_6 + 5) + lda (POSITION_6 + 2) + eor #%01000000 + sta (POSITION_6 + 6) + lda (POSITION_6 + 3) + clc + adc #$08 + sta (POSITION_6 + 7) + + lda POSITION_6 + clc + adc #$08 + sta (POSITION_6 + 8) + lda (POSITION_6 + 1) + sta (POSITION_6 + 9) + lda (POSITION_6 + 2) + eor #%10000000 + sta (POSITION_6 + 10) + lda (POSITION_6 + 3) + sta (POSITION_6 + 11) + + lda POSITION_6 + clc + adc #$08 + sta (POSITION_6 + 12) + lda (POSITION_6 + 1) + sta (POSITION_6 + 13) + lda (POSITION_6 + 2) + eor #%11000000 + sta (POSITION_6 + 14) + lda (POSITION_6 + 3) + clc + adc #$08 + sta (POSITION_6 + 15) + +DrawCornersPosition7: + lda #$07 + jsr CheckAPositionAvailable + bne DrawCornersPosition7Continue + lda #$FE + sta (POSITION_7) + sta (POSITION_7 + 4) + sta (POSITION_7 + 8) + sta (POSITION_7 + 12) + rts +DrawCornersPosition7Continue: +; Position 7 + lda KNIGHT_TL + sec + sbc #$10 + sta POSITION_7 + lda #$03 + sta (POSITION_7 + 1) + lda #$00000001 + sta (POSITION_7 + 2) + lda (KNIGHT_TL + 3) + sec + sbc #$20 + sta (POSITION_7 + 3) + + lda POSITION_7 + sta (POSITION_7 + 4) + lda (POSITION_7 + 1) + sta (POSITION_7 + 5) + lda (POSITION_7 + 2) + eor #%01000000 + sta (POSITION_7 + 6) + lda (POSITION_7 + 3) + clc + adc #$08 + sta (POSITION_7 + 7) + + lda POSITION_7 + clc + adc #$08 + sta (POSITION_7 + 8) + lda (POSITION_7 + 1) + sta (POSITION_7 + 9) + lda (POSITION_7 + 2) + eor #%10000000 + sta (POSITION_7 + 10) + lda (POSITION_7 + 3) + sta (POSITION_7 + 11) + + lda POSITION_7 + clc + adc #$08 + sta (POSITION_7 + 12) + lda (POSITION_7 + 1) + sta (POSITION_7 + 13) + lda (POSITION_7 + 2) + eor #%11000000 + sta (POSITION_7 + 14) + lda (POSITION_7 + 3) + clc + adc #$08 + sta (POSITION_7 + 15) + rts + +DrawCrack: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + + lda crackAddr + sta graphics, X + inx + lda (crackAddr + 1) + sta graphics, X + inx + + ldy crackColor + tya + sta graphics, X + inx + iny + tya + sta graphics, X + inx + + lda crackColor + clc + adc #$10 + sta crackColor + + lda #$00 + sta graphics, X + inx + lda #$00 + sta graphics, X + inx + + ldy crackColor + tya + sta graphics, X + inx + iny + tya + sta graphics, X + inx + stx graphicsPointer + lda #$00 + sta drawCrack + rts + +DrawEndPosition: + lda endPositionOption + bne DrawEndPositionContinue + rts +DrawEndPositionContinue: + ; tmp starts at 21 08 + ; #%00[111] - row (ppu row * 40) [111] - Position on row + ; + lda #$21 + sta tmp + lda #$08 + sta (tmp + 1) + lda endPosition + and #%00111000 + lsr + lsr + lsr + tay +DrawEndPositionIncTmpRowLoop: + cpy #$00 + beq DrawEndPositionIncTmpRowLoopDone + lda #$40 + jsr IncTmpBytesByABigEndian + dey + jmp DrawEndPositionIncTmpRowLoop +DrawEndPositionIncTmpRowLoopDone: + lda endPosition + and #%00000111 + asl + clc + adc (tmp + 1) + sta (tmp + 1) + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + lda tmp + sta graphics, X + inx + lda (tmp + 1) + sta graphics, X + inx + + ; endPosition & 00001000 = row + ; endPosition & 00000001 = color offset row + + lda endPosition + and #%00001000 + lsr + lsr + lsr + eor endPosition + and #%00000001 + eor #%00000001 + asl + clc + adc #$87 + tay + sta graphics, X + inx + iny + tya + sta graphics, X + inx + clc + adc #$0F + tay + lda #$00 + sta graphics, X + inx + sta graphics, X + inx + tya + sta graphics, X + inx + iny + tya + sta graphics, X + inx + stx graphicsPointer + rts + +CheckBoardFinished: + lda currentBoardScore + cmp #$06 + bne CurrentBoardFinishedNotWin + lda (currentBoardScore + 1) + cmp #$03 + bne CurrentBoardFinishedNotWin + lda #$00 + sta timeInc + sta (timeInc + 2) + lda #$03 + sta (timeInc + 1) + jsr IncTimerByTimeInc + rts +CurrentBoardFinishedNotWin: + jsr SetTopScoreTmpToTopScore + jsr ResetTimeScore + rts diff --git a/src/controller.asm b/src/controller.asm new file mode 100644 index 0000000..88d083f --- /dev/null +++ b/src/controller.asm @@ -0,0 +1,322 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +PollController: + lda controllerType + sta controllerTypeLastFrame + lda controller1D0 + sta controller1D0LastFrame + lda (controller1D0 + 1) + sta (controller1D0LastFrame + 1) + lda (controller1D0 + 2) + sta (controller1D0LastFrame + 2) + lda (controller1D0 + 3) + sta (controller1D0LastFrame + 3) + lda controller1D3 + lda controller1D4 +PollControllerLatch: + lda #$01 + sta CONTROLLER1 + jsr SetMouseSensitivity + lda #$00 + sta CONTROLLER1 + ldy #$08 + ldx #$00 +PollController1Loop: + lda CONTROLLER1 ; 4 + sta tmp + lsr ; 2 + rol controller1D0, X ; 7 + cpx #$00 ; 2 + bne PollController1LoopNotFirstByte ; 3 + lsr + lsr + lsr + rol controller1D3 + lsr + rol controller1D4 + lda tmp +PollController1LoopNotFirstByte: + dey ; 2 + bne PollController1Loop ; 3 + ldy #$08 ; 2 + inx ; 2 + cpx #$04 ; 2 + bne PollController1Loop ; 3 + jsr IdentifyController + jsr CheckPowerPad + rts + +CheckController: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + beq CheckControllerMouse + jsr CheckUp + jsr CheckDown + jsr CheckLeft + jsr CheckRight + jsr CheckA + rts +CheckControllerMouse: + jsr CheckLeftClick + rts + +ModifyController: + lda controller1D0 + and controller1D0LastFrame + eor controller1D0 + sta controller1D0Final + + lda (controller1D0 + 1) + and (controller1D0LastFrame + 1) + eor (controller1D0 + 1) + and #%11000000 + sta (controller1D0Final + 1) + + lda leftHanded + bne AdjustLeftHanded + rts +AdjustLeftHanded: + lda controllerType + cmp #CONTROLLER_POWER_PAD + bne AdjustLeftHandedNotPowerPad + lda controller1D0Final + and #%00101010 + lsr + sta tmp + lda controller1D0Final + and #%00010101 + asl + ora tmp + sta tmp + lda controller1D0Final + and #%11000000 + ora tmp + sta controller1D0Final +AdjustLeftHandedNotPowerPad: + lda controller1D0Final + and #%10101010 + lsr + sta tmp + lda controller1D0Final + and #%01010101 + asl + ora tmp + sta controller1D0Final + lda (controller1D0Final + 1) + and #%10000000 + lsr + sta tmp + lda (controller1D0Final + 1) + and #%01000000 + asl + ora tmp + sta tmp + lda (controller1D0Final + 1) + and #%00000001 + ora tmp + sta (controller1D0Final + 1) + + rts + +CheckUp: + lda controller1D0Final + and #BUTTON_UP + beq CheckUpDone + lda position + sta positionTmp + sta positionMoveOffset + dec positionMoveOffset + jsr MovePosition + cmp position + beq CheckUpDone + sta position + lda #$00 + sta positionFrame + lda #$01 + sta redrawSprites +CheckUpDone: + rts + +CheckDown: + lda controller1D0Final + and #BUTTON_DOWN + beq CheckDownDone + lda position + sta positionTmp + sta positionMoveOffset + inc positionMoveOffset + inc positionMoveOffset + inc positionMoveOffset + jsr MovePosition + cmp position + beq CheckDownDone + sta position + lda #$00 + sta positionFrame + lda #$01 + sta redrawSprites +CheckDownDone: + rts + +CheckLeft: + lda controller1D0Final + and #BUTTON_LEFT + beq CheckLeftDone + lda position + sta positionTmp + sta positionMoveOffset + inc positionMoveOffset + jsr MovePosition + cmp position + beq CheckLeftDone + sta position + lda #$00 + sta positionFrame + lda #$01 + sta redrawSprites +CheckLeftDone: + rts + +CheckRight: + lda controller1D0Final + and #BUTTON_RIGHT + beq CheckRightDone + lda position + sta positionTmp + sta positionMoveOffset + dec positionMoveOffset + dec positionMoveOffset + dec positionMoveOffset + jsr MovePosition + cmp position + beq CheckRightDone + sta position + lda #$00 + sta positionFrame + lda #$01 + sta redrawSprites +CheckRightDone: + rts + +CheckA: + lda controller1D0Final + and #BUTTON_A + bne CheckAContinue + rts +CheckAContinue: + lda position + bne CheckAPositionNot0 + lda knightPosition + sec + sbc #$11 + sta knightPositionNew + jmp CheckADraw +CheckAPositionNot0: + cmp #$01 + bne CheckAPositionNot1 + lda knightPosition + sec + sbc #$0F + sta knightPositionNew + jmp CheckADraw +CheckAPositionNot1: + cmp #$02 + bne CheckAPositionNot2 + lda knightPosition + sec + sbc #$06 + sta knightPositionNew + jmp CheckADraw +CheckAPositionNot2: + cmp #$03 + bne CheckAPositionNot3 + lda knightPosition + clc + adc #$0A + sta knightPositionNew + jmp CheckADraw +CheckAPositionNot3: + cmp #$04 + bne CheckAPositionNot4 + lda knightPosition + clc + adc #$11 + sta knightPositionNew + jmp CheckADraw +CheckAPositionNot4: + cmp #$05 + bne CheckAPositionNot5 + lda knightPosition + clc + adc #$0F + sta knightPositionNew + jmp CheckADraw +CheckAPositionNot5: + cmp #$06 + bne CheckAPositionNot6 + lda knightPosition + clc + adc #$06 + sta knightPositionNew + jmp CheckADraw +CheckAPositionNot6: + lda knightPosition + sec + sbc #$0A + sta knightPositionNew +CheckADraw: + lda knightPositionNew + jsr CheckAPositionBroken + beq CheckADrawNotBrokenPosition + lda #$01 + sta end + rts +CheckADrawNotBrokenPosition: + jsr UpdateDisallowedPositions + lda #$00 + sta knightFrame + lda positionFrame + and #%00001000 + beq CheckADrawContinue + lda positionFrame + and #%00010000 + ora #%00001111 + sta positionFrame + inc positionFrame + jsr UpdatePositionCorners +CheckADrawContinue: + lda #$01 + sta animateKnight + lda knightPosition + sta crackPosition + jsr CrackTile + jsr IncScore + jsr IncCurrentBoardScore + jsr UpdateTopScore +CheckADone: + rts + +IdentifyController: + lda (controller1D0 + 1) + and #%00001111 + cmp #%00000001 + bne IdentifyControllerNotSNESMouse + lda #CONTROLLER_SNES_MOUSE + sta controllerType + rts +IdentifyControllerNotSNESMouse: + lda #$00 + sta snesMouseReady + jsr EraseCursor + lda controller1D4 + and #%00001111 + cmp #%00001111 + bne IdentifyControllerNotPowerPad + lda #CONTROLLER_POWER_PAD + sta controllerType + rts +IdentifyControllerNotPowerPad: + lda #CONTROLLER_STANDARD + sta controllerType + rts diff --git a/src/defs.asm b/src/defs.asm new file mode 100644 index 0000000..c7bab3e --- /dev/null +++ b/src/defs.asm @@ -0,0 +1,90 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +CONTROLLER1 = $4016 +CONTROLLER2 = $4017 + +BUTTON_A = 1 << 7 +BUTTON_B = 1 << 6 +BUTTON_SELECT = 1 << 5 +BUTTON_START = 1 << 4 +BUTTON_UP = 1 << 3 +BUTTON_DOWN = 1 << 2 +BUTTON_LEFT = 1 << 1 +BUTTON_RIGHT = 1 << 0 + +RIGHT_CLICK = 1 << 7 +LEFT_CLICK = 1 << 6 + +POWER_PAD_1 = 1 << 6 +POWER_PAD_2 = 1 << 7 +POWER_PAD_3 = 1 << 6 +POWER_PAD_4 = 1 << 7 +POWER_PAD_5 = 1 << 5 +POWER_PAD_6 = 1 << 3 +POWER_PAD_7 = 1 << 0 +POWER_PAD_8 = 1 << 4 +POWER_PAD_9 = 1 << 4 +POWER_PAD_10 = 1 << 2 +POWER_PAD_11 = 1 << 1 +POWER_PAD_12 = 1 << 5 + +PPU_CTRL = $2000 +PPU_MASK = $2001 +PPU_STATUS = $2002 +PPU_OAM_ADDR = $2003 +PPU_OAM_DATA = $2004 +PPU_SCROLL = $2005 +PPU_ADDR = $2006 +PPU_DATA = $2007 + +OAM_DMA = $4014 +APU_FRAME_COUNTER = $4017 + +CALLBACK = $FFFA + +KNIGHT_TL = $204 +KNIGHT_TR = $208 +KNIGHT_BL = $20C +KNIGHT_BR = $210 + +POSITION_0 = $214 +POSITION_1 = $224 +POSITION_2 = $234 +POSITION_3 = $244 +POSITION_4 = $254 +POSITION_5 = $264 +POSITION_6 = $274 +POSITION_7 = $284 + +L_3 = $294 +L_1 = $298 +L_2 = $29C +L_0 = $2A0 +L_4 = $2A4 + +CURSOR = $200 + +CONTROLLER_STANDARD = 0 +CONTROLLER_SNES_MOUSE = 1 +CONTROLLER_POWER_PAD = 2 + +SCREEN_TITLE = 0 +SCREEN_BOARD = 1 +SCREEN_OPTIONS = 2 + +TITLE_OPTION_LEVEL_MODE = 0 +TITLE_OPTION_SCORE_MODE = 1 +TITLE_OPTION_OPTIONS = 2 + +OPTIONS_LEFT_HANDED = 0 +OPTIONS_CAN_FALL = 1 +OPTIONS_INVISIBLE_CRACKS = 2 +OPTIONS_INVISIBLE_GUIDES = 3 +OPTIONS_END_POSITION = 4 +;; SET OPTIONS_LAST TO LAST OPTION VALUE BEFORE DEFAULT +OPTIONS_LAST = OPTIONS_END_POSITION +;; +OPTIONS_DEFAULT = OPTIONS_LAST + 1 +OPTIONS_TITLE_SCREEN = OPTIONS_DEFAULT + 1 + diff --git a/src/draw.asm b/src/draw.asm new file mode 100644 index 0000000..e4124c0 --- /dev/null +++ b/src/draw.asm @@ -0,0 +1,97 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +ResetScroll: + lda #$00 + sta PPU_SCROLL + sta PPU_SCROLL + jsr EnableNMI + rts + +Draw: + lda #%00011110 + sta PPU_MASK + rts + +DisableNMI: + lda spriteTable + ror + ror tmp + lda backgroundTable + lsr + lda tmp + ror + ror + ror + ror + and #%00011000 + sta PPU_CTRL + rts + +EnableNMI: + lda spriteTable + lsr + ror tmp + lda backgroundTable + lsr + lda tmp + ror + ror + ror + ror + ora #%10000000 + and #%10011000 + sta PPU_CTRL + rts + +Blank: + lda #%00000110 + sta PPU_MASK + jsr DisableNMI + rts + + +ResetPPURAM: + lda #$20 + sta PPU_ADDR + lda #$00 + sta PPU_ADDR + ldy #$10 + ldx #$00 + txa +ResetPPURAMLoop: + sta PPU_DATA + dex + bne ResetPPURAMLoop + ldx #$00 + dey + bne ResetPPURAMLoop + rts + +DisableSprites: + ldx #$00 + lda #$FE +DisableSpritesLoop: + sta $200, X + inx + bne DisableSpritesLoop + rts + +BlankPalettes: + lda PPU_STATUS + lda #$3F + sta PPU_ADDR + lda #$00 + sta PPU_ADDR + ldx #$20 + lda #$0F +BlankPalettesLoop: + sta PPU_DATA + dex + bne BlankPalettesLoop + rts + +ErasePointer: + lda #$FE + sta #$2FC + rts diff --git a/src/frames.asm b/src/frames.asm new file mode 100644 index 0000000..9544618 --- /dev/null +++ b/src/frames.asm @@ -0,0 +1,26 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +WaitForNewFrame: + lda frames +WaitForNewFrameLoop: + cmp frames + beq WaitForNewFrameLoop + rts + +WaitForNewFrameDisableDraw: + ; TODO look into swapping order of needDraw set 0 and frame wait + jsr WaitForNewFrame + lda #$00 + sta needDraw + rts + +DecTimer: + lda frames + cmp fps + bne DecTimerDone + lda #$00 + sta frames + dec timer +DecTimerDone: + rts diff --git a/src/graphics.asm b/src/graphics.asm new file mode 100644 index 0000000..c744195 --- /dev/null +++ b/src/graphics.asm @@ -0,0 +1,219 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +CONTROL_MODE_FLAG = 1 << 7 + +; graphicsControlFlags +; 7 bit 0 +; ---- ---- +; | +; +--------- Control Mode (0: on, 1: off) + +.enum $300 + graphicsControlFlags dsb 1 + graphicsPointer dsb 1 + ppuAddr dsb 2 + ppuAddrLast dsb 2 + + graphics dsb 244 +.ende + + +; $00 = Control +; | +; +--$00 = New PPU Line +; | +; +--$01 = Repeat Start +; | | +; | +--$XX = Tag Byte +; | | +; | +--$LL = Repeat Length +; | +; +--$02 = Repeat End +; | | +; | +--$XX = Tag Byte +; | +; +--$80 = Literal Byte Next +; | | +; | +--$XX = Literal Byte +; | +; +--$FE = PPU_ADDR Start +; | +; +--$FF = Total End +; +; $00, $FE, PPU_ADDR_HI, PPU_ADDR_LO, [Content...], $00, $FF +; $00, $FE, PPU_ADDR2_HI, PPU_ADDR2_LO, [Content2...], $00, $FF, $FF + +ResetGraphics: + ldx #$00 + stx graphics + stx graphicsPointer + stx graphicsControlFlags + lda #$FF + inx + sta graphics, X + inx + sta graphics, X + rts + +PPUAddrIncLine: + lda (ppuAddr + 1) + clc + adc #$20 + sta (ppuAddr + 1) + lda ppuAddr + adc #$00 + sta ppuAddr + rts + +ReadGraphics: + lda PPU_STATUS + lda #$20 + ldx #$00 + sta PPU_ADDR + stx PPU_ADDR +ReadGraphicsLoop: + lda graphics, X + beq ReadGraphicsControlByte + sta PPU_DATA + inx + stx graphicsPointer + jmp ReadGraphicsLoop +ReadGraphicsControlByte: + inx + lda graphics, X + bne ReadGraphicsControlByteNot00 + jsr ReadGraphicsControl00Handle + jmp ReadGraphicsLoop +ReadGraphicsControlByteNot00: + cmp #$80 + bne ReadGraphicsControlByteNot80 + jsr ReadGraphicsControl80Handle + jmp ReadGraphicsLoop +ReadGraphicsControlByteNot80: + cmp #$FE + bne ReadGraphicsControlByteNotFE + jsr ReadGraphicsControlFEHandle + jmp ReadGraphicsLoop +ReadGraphicsControlByteNotFE: + cmp #$FF + bne ReadGraphicsControlByteNotFF + lda ppuAddr + sta ppuAddrLast + lda (ppuAddr + 1) + sta (ppuAddrLast + 1) + rts +ReadGraphicsControlByteNotFF: +ReadGraphicsControlByteInvalid: + jmp ReadGraphicsLoop + + +; New Line Handle +ReadGraphicsControl00Handle: + jsr PPUAddrIncLine + lda PPU_STATUS + lda ppuAddr + sta PPU_ADDR + lda (ppuAddr + 1) + sta PPU_ADDR + inx + stx graphicsPointer + rts + +; Literal Byte Handle +ReadGraphicsControl80Handle: + inx + lda graphics, X + sta PPU_DATA + inx + stx graphicsPointer + rts + +; End GraphicsSectionHandle +ReadGraphicsControlFEHandle: + lda PPU_STATUS + inx + lda graphics, X + sta ppuAddr + sta PPU_ADDR + inx + lda graphics, X + sta ppuAddr + 1 + sta PPU_ADDR + inx + stx graphicsPointer + rts + + + + + +ReadGraphicsControl01Handle: + rts +ReadGraphicsControl02Handle: + rts + +SetPPUAddrInGraphicsBuffer: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + lda ppuAddrLast + sta graphics, X + inx + lda (ppuAddrLast + 1) + sta graphics, X + inx + stx graphicsPointer + rts + +DecPPUAddr1Line: + lda (ppuAddr + 1) + sec + sbc #$20 + sta (ppuAddr + 1) + lda ppuAddr + sbc #$00 + sta ppuAddr + rts + +ReadThenResetGraphics: + jsr ReadGraphics + jsr ResetGraphics + rts + +BlankScreen: + jsr WaitForNewFrame + jsr BlankPalette + lda #$01 + sta needDraw + jsr WaitForNewFrameDisableDraw + jsr DisableSprites + rts + +BlankPalette: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + lda #$3F + sta graphics, X + inx + lda #$00 + sta graphics, X + inx + ldy #$20 + lda #$0F +BlankPaletteLoop: + sta graphics, X + inx + dey + bne BlankPaletteLoop + stx graphicsPointer + rts diff --git a/src/graphics/options.atr b/src/graphics/options.atr new file mode 100644 index 0000000..9017fd9 Binary files /dev/null and b/src/graphics/options.atr differ diff --git a/src/graphics/options.nam b/src/graphics/options.nam new file mode 100644 index 0000000..ff2277f Binary files /dev/null and b/src/graphics/options.nam differ diff --git a/src/graphics/tileset.chr b/src/graphics/tileset.chr new file mode 100644 index 0000000..fdf1693 Binary files /dev/null and b/src/graphics/tileset.chr differ diff --git a/src/graphics/title.atr b/src/graphics/title.atr new file mode 100644 index 0000000..9017fd9 Binary files /dev/null and b/src/graphics/title.atr differ diff --git a/src/graphics/title.nam b/src/graphics/title.nam new file mode 100644 index 0000000..af1f875 Binary files /dev/null and b/src/graphics/title.nam differ diff --git a/src/knight.asm b/src/knight.asm new file mode 100644 index 0000000..5c14ba0 --- /dev/null +++ b/src/knight.asm @@ -0,0 +1,146 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +AnimateKnightStep: + inc knightFrame + lda knightPositionNew + and #%00000111 + sta tmp + lda knightPosition + and #%00000111 + cmp tmp + bne AnimateKnightHorizontalContinue + jmp AnimateKnightVerticalStart +AnimateKnightHorizontalContinue: + bcs AnimateKnightHorizontalLeft + ; knightPosition mod 8 is less than knightPositionNew mod 8 + jmp AnimateKnightHorizontalRight +AnimateKnightHorizontalLeft: + ; knightPosition mod 8 is greater than knightPositionNew mod 8 + dec (KNIGHT_TL + 3) + dec (KNIGHT_TL + 3) + dec (KNIGHT_TL + 3) + dec (KNIGHT_TL + 3) + dec (KNIGHT_TR + 3) + dec (KNIGHT_TR + 3) + dec (KNIGHT_TR + 3) + dec (KNIGHT_TR + 3) + dec (KNIGHT_BL + 3) + dec (KNIGHT_BL + 3) + dec (KNIGHT_BL + 3) + dec (KNIGHT_BL + 3) + dec (KNIGHT_BR + 3) + dec (KNIGHT_BR + 3) + dec (KNIGHT_BR + 3) + dec (KNIGHT_BR + 3) + lda knightFrame + and #%00000011 + bne AnimateKnightHorizontalLeftDone + dec knightPosition +AnimateKnightHorizontalLeftDone: + jmp AnimateKnightStepDone +AnimateKnightHorizontalRight: + ; knightPosition mod 8 is less than knightPositionNew mod 8 + inc (KNIGHT_TL + 3) + inc (KNIGHT_TL + 3) + inc (KNIGHT_TL + 3) + inc (KNIGHT_TL + 3) + inc (KNIGHT_TR + 3) + inc (KNIGHT_TR + 3) + inc (KNIGHT_TR + 3) + inc (KNIGHT_TR + 3) + inc (KNIGHT_BL + 3) + inc (KNIGHT_BL + 3) + inc (KNIGHT_BL + 3) + inc (KNIGHT_BL + 3) + inc (KNIGHT_BR + 3) + inc (KNIGHT_BR + 3) + inc (KNIGHT_BR + 3) + inc (KNIGHT_BR + 3) + lda knightFrame + and #%00000011 + bne AnimateKnightHorizontalRightDone + inc knightPosition +AnimateKnightHorizontalRightDone: + jmp AnimateKnightStepDone +AnimateKnightVerticalStart: + lda knightPositionNew + and #%00111000 + sta tmp + lda knightPosition + and #%00111000 + cmp tmp + bne AnimateKnightVerticalContinue + jmp AnimateKnightVerticalDone +AnimateKnightVerticalContinue: + bcs AnimateKnightVerticalUp + ; knightPosition div 8 is less than knightPositionNew div 8 + jmp AnimateKnightVerticalDown +AnimateKnightVerticalUp: + ; knightPosition div 8 is greater than knightPositionNew div 8 + dec KNIGHT_TL + dec KNIGHT_TL + dec KNIGHT_TL + dec KNIGHT_TL + dec KNIGHT_TR + dec KNIGHT_TR + dec KNIGHT_TR + dec KNIGHT_TR + dec KNIGHT_BL + dec KNIGHT_BL + dec KNIGHT_BL + dec KNIGHT_BL + dec KNIGHT_BR + dec KNIGHT_BR + dec KNIGHT_BR + dec KNIGHT_BR + lda knightFrame + and #%00000011 + bne AnimateKnightVerticalUpDone + lda knightPosition + sec + sbc #$08 + sta knightPosition +AnimateKnightVerticalUpDone: + jmp AnimateKnightStepDone +AnimateKnightVerticalDown: + ; knightPosition div 8 is less than knightPositionNew div 8 + inc KNIGHT_TL + inc KNIGHT_TL + inc KNIGHT_TL + inc KNIGHT_TL + inc KNIGHT_TR + inc KNIGHT_TR + inc KNIGHT_TR + inc KNIGHT_TR + inc KNIGHT_BL + inc KNIGHT_BL + inc KNIGHT_BL + inc KNIGHT_BL + inc KNIGHT_BR + inc KNIGHT_BR + inc KNIGHT_BR + inc KNIGHT_BR + lda knightFrame + and #%00000011 + bne AnimateKnightVerticalDownDone + lda knightPosition + clc + adc #$08 + sta knightPosition +AnimateKnightVerticalDownDone: + jmp AnimateKnightStepDone +AnimateKnightVerticalDone: + lda #$00 + sta animateKnight + + jsr GetAvailablePositions + jsr CheckEndPosition + jsr CheckDisallowedPositions + jsr AdjustPosition + + + lda #$01 + sta redrawSprites +AnimateKnightStepDone: + rts diff --git a/src/math.asm b/src/math.asm new file mode 100644 index 0000000..020f412 --- /dev/null +++ b/src/math.asm @@ -0,0 +1,20 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +IncTmpBytesByABigEndian: + clc + adc (tmp + 1) + sta (tmp + 1) + lda tmp + adc #$00 + sta tmp + rts + +IncTmpBytesByALittleEndian: + clc + adc tmp + sta tmp + lda (tmp + 1) + adc #$00 + sta (tmp + 1) + rts diff --git a/src/mouse.asm b/src/mouse.asm new file mode 100644 index 0000000..f36e201 --- /dev/null +++ b/src/mouse.asm @@ -0,0 +1,324 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +SetMouseSensitivity: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + bne SetMouseSensitivityDone + lda snesMouseReady + bne SetMouseSensitivityDone + lda (controller1D0LastFrame + 1) + and #%00110000 + lsr + lsr + lsr + lsr + tax +SetMouseSensitivityLoop: + lda CONTROLLER1 + inx + cpx #$03 + bne SetMouseSensitivityLoop + lda #$01 + sta snesMouseReady + jsr DrawCursor +SetMouseSensitivityDone: + rts + +MoveCursor: + lda snesMouseReady + cmp #$01 + beq MoveCursorVertical + rts +MoveCursorVertical: + jsr CheckMouseVertical + cpy #$00 + beq MoveCursorDown +MoveCursorUp: + lda tmp + dec CURSOR + lda CURSOR + sec + sbc tmp + sta CURSOR + bcs MoveCursorHorizontal + lda #$00 + sta CURSOR + jmp MoveCursorHorizontal +MoveCursorDown: + dec CURSOR + lda CURSOR + clc + adc tmp + sta CURSOR + bcs MoveCursorDownReset + cmp #$ED + bcc MoveCursorHorizontal +MoveCursorDownReset: + lda #$ED + sta CURSOR +MoveCursorHorizontal: + jsr CheckMouseHorizontal + cpy #$00 + beq MoveCursorRight +MoveCursorLeft: + lda (CURSOR + 3) + sec + sbc tmp + sta (CURSOR + 3) + bcs MoveCursorDone + lda #$00 + sta (CURSOR + 3) + jmp MoveCursorDone +MoveCursorRight: + lda (CURSOR + 3) + clc + adc tmp + sta (CURSOR + 3) + bcc MoveCursorDone + lda #$FF + sta (CURSOR + 3) +MoveCursorDone: + inc CURSOR + rts + +CheckMouseVertical: + lda (controller1D0 + 2) + and #%10000000 + tay + lda (controller1D0 + 2) + and #%01111111 + sta tmp + rts + +CheckMouseHorizontal: + lda (controller1D0 + 3) + and #%10000000 + tay + lda (controller1D0 + 3) + and #%01111111 + sta tmp + rts + +DrawCursor: + lda #$77 + lda #$1B + sta CURSOR + lda #$10 + sta (CURSOR + 1) + lda #%00000000 + sta (CURSOR + 2) + lda #$E8 + sta (CURSOR + 3) + rts + +EraseCursor: + lda #$FE + sta CURSOR + rts + +DetermineCursorOverPosition: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + beq DetermineCursorOverPositionSNESCheck + rts +DetermineCursorOverPositionSNESCheck: + ldx #$00 + ldy #$00 +DetermineCursorOverPositionLoop: + lda (CURSOR), Y + sec + sbc (KNIGHT_TL), Y + bcc DetermineCursorOverPositionsCursorLess + cmp #$10 + bcs DetermineCursorOverPositionsCursorMore + jmp DetermineCursorOverPositionInvalid +DetermineCursorOverPositionsCursorLess: + lsr + lsr + lsr + lsr + eor #%11111111 + and #%00001111 + ora #%10000000 + sta tmp, X + jmp DetermineCursorOverPositionLoopLessMoreDone +DetermineCursorOverPositionsCursorMore: + sbc #$10 + lsr + lsr + lsr + lsr + and #%00001111 + sta tmp, X +DetermineCursorOverPositionLoopLessMoreDone: + lda tmp, X + and #%00001111 + cmp #$02 + bcc DetermineCursorOverPositionLoopDone + jmp DetermineCursorOverPositionInvalid +DetermineCursorOverPositionLoopDone: + iny + iny + iny + inx + cpx #$02 + bne DetermineCursorOverPositionLoop + jmp DetermineCursorOverPositionContinue +DetermineCursorOverPositionContinue: + lda tmp + and #%00000001 + tay + eor (tmp + 1) + and #%00000001 + bne DetermineCursorOverPositionContinueNotOverflow + jmp DetermineCursorOverPositionInvalid +DetermineCursorOverPositionContinueNotOverflow: + lda (tmp + 1) + lsr + ora tmp + and #%11000000 + clc + rol + rol + rol + tax + cpx #$04 + bcc DetermineCursorOverPositionGetPosition + jmp DetermineCursorOverPositionInvalid +DetermineCursorOverPositionGetPosition: + lda CursorOffsetToPosition, X + cpy #$01 + bne DetermineCursorOverPositionNotShift + lsr + lsr + lsr + lsr +DetermineCursorOverPositionNotShift: + and #%00000111 + sta tmp + jsr CheckAPositionAvailable + bne DetermineCursorOverPositionValid + jmp DetermineCursorOverPositionInvalid +DetermineCursorOverPositionValid: + lda cursorPosition + cmp #$08 + bne DetermineCursorOverPositionDone + lda #$00 + sta positionFrame +DetermineCursorOverPositionDone: + lda tmp + sta cursorPosition + sta position + rts +DetermineCursorOverPositionInvalid: + lda #$08 + sta cursorPosition + lda #$00 + sta positionFrame + rts + +CheckLeftClick: + lda (controller1D0Final + 1) + and #LEFT_CLICK + bne CheckLeftClickContinue + rts +CheckLeftClickContinue: + lda cursorPosition + bne CheckLeftClickPositionNot0 + lda knightPosition + sec + sbc #$11 + sta knightPositionNew + jmp CheckLeftClickDraw +CheckLeftClickPositionNot0: + cmp #$01 + bne CheckLeftClickPositionNot1 + lda knightPosition + sec + sbc #$0F + sta knightPositionNew + jmp CheckLeftClickDraw +CheckLeftClickPositionNot1: + cmp #$02 + bne CheckLeftClickPositionNot2 + lda knightPosition + sec + sbc #$06 + sta knightPositionNew + jmp CheckLeftClickDraw +CheckLeftClickPositionNot2: + cmp #$03 + bne CheckLeftClickPositionNot3 + lda knightPosition + clc + adc #$0A + sta knightPositionNew + jmp CheckLeftClickDraw +CheckLeftClickPositionNot3: + cmp #$04 + bne CheckLeftClickPositionNot4 + lda knightPosition + clc + adc #$11 + sta knightPositionNew + jmp CheckLeftClickDraw +CheckLeftClickPositionNot4: + cmp #$05 + bne CheckLeftClickPositionNot5 + lda knightPosition + clc + adc #$0F + sta knightPositionNew + jmp CheckLeftClickDraw +CheckLeftClickPositionNot5: + cmp #$06 + bne CheckLeftClickPositionNot6 + lda knightPosition + clc + adc #$06 + sta knightPositionNew + jmp CheckLeftClickDraw +CheckLeftClickPositionNot6: + cmp #$07 + beq CheckLeftClickPosition7 + rts +CheckLeftClickPosition7 + lda knightPosition + sec + sbc #$0A + sta knightPositionNew +CheckLeftClickDraw: + lda knightPositionNew + jsr CheckAPositionBroken + beq CheckLeftClickDrawNotBrokenPosition + lda #$01 + sta end + rts +CheckLeftClickDrawNotBrokenPosition: + jsr UpdateDisallowedPositions + lda #$00 + sta knightFrame + lda positionFrame + and #%00001000 + beq CheckLeftClickCornersNeutral + lda positionFrame + and #%00010000 + ora #%00001111 + sta positionFrame + inc positionFrame + jsr UpdatePositionCorners +CheckLeftClickCornersNeutral: + lda #$01 + sta animateKnight + lda knightPosition + sta crackPosition + jsr CrackTile + jsr IncScore + jsr IncCurrentBoardScore + jsr UpdateTopScore +CheckLeftClickDone: + rts + +CursorOffsetToPosition: + .byte $43, $56, $12, $07 diff --git a/src/options.asm b/src/options.asm new file mode 100644 index 0000000..841af70 --- /dev/null +++ b/src/options.asm @@ -0,0 +1,427 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +StartOptionsScreen: + ; Turn screen completely black for 1 frame to avoid flicker/tear + jsr BlankScreen + ; Turn screen and NMI off + jsr Blank + ; Set screen to SCREEN_OPTIONS + lda #SCREEN_OPTIONS + sta screen + ; Set sprite table to pattern table 01 + lda #$01 + sta spriteTable + ; Set background table to pattern table 00 + lda #$00 + sta backgroundTable + ; TODO - Consider a situation where started is not needed + sta started + ; TODO - Consider a situation where titleOption and pointer are the same + sta pointer + jsr DrawOptionsScreen + jsr SetTitleScreenPalette + ; Initialize controller1 last frame to say all buttons pressed + lda #$FF + sta controller1D0LastFrame + sta (controller1D0LastFrame + 1) + ; Check if controller is a SNES mouse + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + bne StartOptionsScreenNotSNESMouse + ; Check if controller is a SNES mouse + lda snesMouseReady + beq StartOptionsScreenNotSNESMouse + ; Draw cursor if SNES mouse is ready + jsr DrawCursor +StartOptionsScreenNotSNESMouse: + ; Place option pointer based on mouse cursor + jsr CursorOptionPointer + jsr ModifyOptionsPointer + ; Draw option pointer based on what pointer is set to + jsr DrawOptionsPointer + jsr CursorOptionPointer + ; Set newDraw for when new frame happens + jsr ReadThenResetGraphics + jsr DrawOptionsValues + jsr UpdateDone + lda #$01 + sta needDraw + ; Re-enable NMI + jsr ResetScroll + rts + +DrawOptionsScreen: + lda #<(OptionsScreen) + sta addr + lda #>(OptionsScreen) + sta (addr + 1) + ldx #$04 + ldy #$00 + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$00 + sta PPU_ADDR +DrawOptionsScreenLoop: + lda (addr), Y + sta PPU_DATA + iny + bne DrawOptionsScreenLoop + inc (addr + 1) + dex + bne DrawOptionsScreenLoop + rts + +DrawOptionsPointer: + lda pointer + cmp #OPTIONS_TITLE_SCREEN + 1 + bcc DrawOptionsPointerContinue + jsr ErasePointer + rts +DrawOptionsPointerContinue: + ldy #$28 + inc pointerFrames + lda pointer + asl + asl + tax + lda OptionsPointerHitBoxes, X + sta $2FC + lda #$13 + sta $2FD + lda #%00000000 + sta $2FE + lda pointerFrames + and #%00001000 + beq DrawOptionsPointerFinish + lda pointerFrames + and #%00010000 + bne DrawOptionsPointerNot3 + dey + jmp DrawOptionsPointerFinish +DrawOptionsPointerNot3: + iny +DrawOptionsPointerFinish: + sty $2FF + rts + +ModifyOptionsPointer: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + beq ModifyOptionsPointerDone + lda pointer + and #%10000000 + beq ModifyOptionsPointerNotNegative + lda #OPTIONS_TITLE_SCREEN + sta pointer + rts +ModifyOptionsPointerNotNegative: + lda pointer + cmp #OPTIONS_TITLE_SCREEN + 1 + bcc ModifyOptionsPointerDone + lda #$00 + sta pointer +ModifyOptionsPointerDone: + rts + +CheckControllerOptionsScreen: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + bne CheckControllerOptionsScreenNotSNESMouse + jsr CheckLeftClickOptions + rts +CheckControllerOptionsScreenNotSNESMouse: + jsr CheckAOptions + jsr CheckLeftRightOptions + jsr CheckUpOptionsScreen + jsr CheckDownOptionsScreen + rts + +CheckUpOptionsScreen: + lda controller1D0Final + and #BUTTON_UP + beq CheckUpOptionsScreenDone + dec pointer +CheckUpOptionsScreenDone: + rts + +CheckDownOptionsScreen: + lda controller1D0Final + and #BUTTON_DOWN + beq CheckDownOptionsScreenDone + inc pointer +CheckDownOptionsScreenDone: + rts + +CheckLeftRightOptions: + lda controller1D0Final + and #(BUTTON_LEFT + BUTTON_RIGHT) + beq CheckLeftRightOptionsScreenDone + eor #(BUTTON_LEFT + BUTTON_RIGHT) + beq CheckLeftRightOptionsScreenDone + lda pointer + cmp #OPTIONS_DEFAULT + bcs CheckLeftRightOptionsScreenNotPositionBeforeOptions + jsr ToggleOption + jsr DrawSingleOnOff + rts +CheckLeftRightOptionsScreenNotPositionBeforeOptions: +CheckLeftRightOptionsScreenDone: + rts + +CheckAOptions: + lda controller1D0Final + and #BUTTON_A + beq CheckAOptionsScreenDone + lda pointer + cmp #OPTIONS_DEFAULT + bcs CheckAOptionsScreenNotPositionBeforeOptions + jsr ToggleOption + jsr DrawSingleOnOff + rts +CheckAOptionsScreenNotPositionBeforeOptions: + bne CheckAOptionsScreenNotPositionDefaultOptions + jsr DefaultOptions + jsr DrawOptionsValues + rts +CheckAOptionsScreenNotPositionDefaultOptions: + cmp #OPTIONS_TITLE_SCREEN + bne CheckAOptionsScreenNotPositionTitleScreen + jsr StartTitleScreen + rts +CheckAOptionsScreenNotPositionTitleScreen: +CheckAOptionsScreenDone: + rts + +CheckLeftClickOptions: + lda (controller1D0Final + 1) + and #LEFT_CLICK + beq CheckLeftClickOptionsScreenDone + lda pointer + cmp #OPTIONS_DEFAULT + bcs CheckLeftClickOptionsScreenNotPositionBeforeOptions + jsr ToggleOption + jsr DrawSingleOnOff + rts +CheckLeftClickOptionsScreenNotPositionBeforeOptions: + bne CheckLeftClickOptionsScreenNotPositionDefaultOptions + jsr DefaultOptions + jsr DrawOptionsValues + rts +CheckLeftClickOptionsScreenNotPositionDefaultOptions: + cmp #OPTIONS_TITLE_SCREEN + bne CheckLeftClickOptionsScreenNotPositionTitleScreen + jsr StartTitleScreen + rts +CheckLeftClickOptionsScreenNotPositionTitleScreen: +CheckLeftClickOptionsScreenDone: + rts + +ToggleOption: + ldy pointer + lda OptionsVariables, Y + eor #%00000001 + and #%00000001 + sta OptionsVariables, Y + rts + +DrawOptionsValues: + lda pointer + pha + lda #$00 + sta pointer +DrawOptionsValuesLoop: + jsr DrawSingleOnOff + inc pointer + lda pointer + cmp #OPTIONS_DEFAULT + bcc DrawOptionsValuesLoop + pla + sta pointer + rts + +DrawOn: + lda #"O" + sta graphics, X + inx + lda #"N" + sta graphics, X + inx + lda #$00 + sta graphics, X + inx + lda #$80 + sta graphics, X + inx + lda #$00 + sta graphics, X + inx + rts + +DrawOff: + lda #"O" + sta graphics, X + inx + lda #"F" + sta graphics, X + inx + sta graphics, X + inx + rts + +DefaultOptions: + lda #$00 + sta leftHanded + sta canFall + sta invisibleCracks + sta invisibleGuides + sta endPositionOption + rts + +CursorOptionPointer: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + beq CursorOptionPointerContinue + rts +CursorOptionPointerContinue: + ldy #$00 + ldx #$00 +CursorOptionPointerYPositionLoop: + lda CURSOR + cmp OptionsPointerHitBoxes, X + bcs CursorOptionPointerCheckRange8 + ldy #OPTIONS_TITLE_SCREEN + 1 + sty pointer + rts +CursorOptionPointerCheckRange8: + lda OptionsPointerHitBoxes, X + inx + inx + inx + inx + clc + adc #$08 + sta tmp + lda CURSOR + cmp tmp + bcs CursorOptionPointerYPositionNotCorrect + sty pointer + jsr CursorOptionPointerHorizontal + rts +CursorOptionPointerYPositionNotCorrect: + iny + cpy #OPTIONS_TITLE_SCREEN + 1 + bne CursorOptionPointerYPositionLoop + sty pointer + rts + +CursorOptionPointerHorizontal: + lda pointer + asl + asl + tax + inx + lda OptionsPointerHitBoxes, X + sta tmp + lda (CURSOR + 3) + cmp tmp + bcs CursorOptionPointerHorizontalNotTooLeft + ldy #OPTIONS_TITLE_SCREEN + 1 + sty pointer + rts +CursorOptionPointerHorizontalNotTooLeft: + inx + lda OptionsPointerHitBoxes, X + asl + asl + asl + clc + adc tmp + sta tmp + lda (CURSOR + 3) + cmp tmp + bcc CursorOptionPointerHoriziontalNotTooFarRight + ldy #OPTIONS_TITLE_SCREEN + 1 + sty pointer +CursorOptionPointerHoriziontalNotTooFarRight: + rts + +ManageInvisibleGuides: + lda invisibleGuides + bne ManageInvisibleGuidesContinue + rts +ManageInvisibleGuidesContinue: + lda #$00 + ldx #$01 + ldy #$20 +ManageInvisibleGuidesLoop: + sta POSITION_0, X + inx + inx + inx + inx + dey + bne ManageInvisibleGuidesLoop + ldx #$01 + ldy #$05 +ManageInvisibleLLoop: + sta L_3, X + inx + inx + inx + inx + dey + bne ManageInvisibleLLoop + rts + +DrawSingleOnOff: + ldy pointer + lda #$20 + sta tmp + lda #$B8 + sta (tmp + 1) +DrawSingleOnOffPointerAddLoop: + cpy #$00 + beq DrawSingleOnOffPointerAddLoopDone + dey + lda #$40 + jsr IncTmpBytesByABigEndian + jmp DrawSingleOnOffPointerAddLoop +DrawSingleOnOffPointerAddLoopDone: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + lda tmp + sta graphics, X + inx + lda (tmp + 1) + sta graphics, X + inx + ldy pointer + lda OptionsVariables, Y + bne DrawSingleOn + jsr DrawOff + jmp DrawSingleOnOffDone +DrawSingleOn: + jsr DrawOn +DrawSingleOnOffDone: + stx graphicsPointer + rts + +OptionsPointerHitBoxes: + .byte $27, $38, $14, $00 + .byte $37, $38, $14, $00 + .byte $47, $38, $14, $00 + .byte $57, $38, $14, $00 + .byte $67, $38, $14, $00 + .byte $AF, $38, $0F, $00 + .byte $BF, $38, $0C, $00 + +OptionsScreen: + .incbin "graphics/options.nam" + .incbin "graphics/options.atr" diff --git a/src/position.asm b/src/position.asm new file mode 100644 index 0000000..0ca0648 --- /dev/null +++ b/src/position.asm @@ -0,0 +1,787 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +UpdatePositionCorners: + lda animateKnight + bne UpdatePositionCornersInanimate + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + bne UpdatePositionCornersSNESMouseChecked + lda cursorPosition + cmp #$08 + bne UpdatePositionCornersSNESMouseChecked + jsr DrawCorners + lda #$00 + sta positionFrame + rts +UpdatePositionCornersInanimate: + ldy #$00 + jmp UpdatePositionCornersIncDecContinue +UpdatePositionCornersSNESMouseChecked: + lda position + asl + asl + asl + asl + tax + lda positionFrame + and #%00000111 + beq UpdatePositionCornersContinue + rts +UpdatePositionCornersContinue: + ldy #$01 + lda positionFrame + and #%00010000 + bne UpdatePositionCornersIncDecContinue: + ldy #$FF +UpdatePositionCornersIncDecContinue: + sty tmp + lda POSITION_0, X + clc + adc tmp + sta POSITION_0, X + inx + inx + inx + lda POSITION_0, X + clc + adc tmp + sta POSITION_0, X + inx + lda POSITION_0, X + clc + adc tmp + sta POSITION_0, X + inx + inx + inx + lda POSITION_0, X + sec + sbc tmp + sta POSITION_0, X + inx + lda POSITION_0, X + sec + sbc tmp + sta POSITION_0, X + inx + inx + inx + tya + clc + adc POSITION_0, X + sta POSITION_0, X + inx + lda POSITION_0, X + sec + sbc tmp + sta POSITION_0, X + inx + inx + inx + lda POSITION_0, X + sec + sbc tmp + sta POSITION_0, X + rts + +GetAvailablePositions: + lda #$00 + ldx knightPosition + cpx #$10 + bcs GetAvailablePositionsRow0Checked + ora #%00000011 +GetAvailablePositionsRow0Checked: + cpx #$08 + bcs GetAvailablePositionsRow1Checked + ora #%10000100 +GetAvailablePositionsRow1Checked: + cpx #$38 + bcc GetAvailablePositionsRow2Checked + ora #%01001000 +GetAvailablePositionsRow2Checked: + cpx #$30 + bcc GetAvailablePositionsRow3Checked + ora #%00110000 +GetAvailablePositionsRow3Checked: + sta tmp + lda knightPosition + and #%00000111 + tax + lda tmp + cpx #$02 + bcs GetAvailablePositionCol0Checked + ora #%11000000 +GetAvailablePositionCol0Checked: + cpx #$01 + bcs GetAvailablePositionCol1Checked + ora #%00100001 +GetAvailablePositionCol1Checked: + cpx #$07 + bcc GetAvailablePositionCol2Checked + ora #%00010010 +GetAvailablePositionCol2Checked: + cpx #$06 + bcc GetAvailablePositionCol3Checked + ora #%00001100 +GetAvailablePositionCol3Checked: + eor #$FF + sta availablePositions + rts + +CheckAPositionAvailable: + tax + lda #$00 + sec +CheckAPositionAvailableShiftLoop: + rol + dex + bpl CheckAPositionAvailableShiftLoop + and availablePositions + rts + +AdjustPosition: + lda #$00 + sta closestPositionLeft + sta closestPositionRight +AdjustPositionRightLoopStart: + lda position +AdjustPositionRightLoop: + tay + ; Set closest clockwise position to position value + sty newPositionRight + jsr CheckAPositionAvailable + bne AdjustPositionLeftLoopStart + ; new position is not a valid position + ; Increment distance from original position + inc closestPositionRight + ; increment position value by 1 (Go clockwise) + iny + cpy #$08 + bne AdjustPositionRightContinue + ; wrap position value back to 0 + ldy #$00 +AdjustPositionRightContinue: + tya + jmp AdjustPositionRightLoop +AdjustPositionLeftLoopStart: + lda position +AdjustPositionLeftLoop: + tay + ; Set closest anticlockwise position to position value + sty newPositionLeft + jsr CheckAPositionAvailable + bne AdjustPositionLeftDone + ; new position is not a valid position + ; Increment distance from original position + inc closestPositionLeft + ; decrement position value by 1 (Go anticlockwise) + dey + cpy #$FF + bne AdjustPositionLeftContinue + ; wrap position value back to 0 + ldy #$07 +AdjustPositionLeftContinue: + tya + jmp AdjustPositionLeftLoop +AdjustPositionLeftDone: + lda closestPositionLeft + cmp closestPositionRight + ; On a tie, go clockwise + bcs AdjustPositionIsRight + ; closestPositionLeft is less than closestPositionRight + ; Go anticlockwise + lda newPositionLeft + sta position + lda #$00 + sta positionFrame + rts +AdjustPositionIsRight: + ; closestPositionLeft is greater or equal to closestPositionRight + ; Go anticlockwise + lda newPositionRight + sta position + lda #$00 + sta positionFrame + rts + +DisableDottedLines: + lda #$FE + sta L_0 + sta L_1 + sta L_2 + sta L_3 + sta L_4 + rts + +DrawDottedLines: + lda cursorPosition + cmp #$08 + bne DrawDottedLinesCheckForSNESMouse + jsr DisableDottedLines + rts +DrawDottedLinesCheckForSNESMouse: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + bne DrawDottedLinesSNESMouseChecked + lda started + bne DrawDottedLinesSNESMouseChecked + lda #$01 + sta started + jsr DisableDottedLines + rts +DrawDottedLinesSNESMouseChecked: + lda KNIGHT_TL + clc + adc #$04 + sta L_0 + sta L_1 + sta L_2 + sta L_3 + sta L_4 + lda #$04 + sta (L_0 + 1) + sta (L_1 + 1) + sta (L_2 + 1) + lda #$06 + sta (L_3 + 1) + lda #$07 + sta (L_4 + 1) + lda #%00000001 + sta (L_0 + 2) + sta (L_1 + 2) + sta (L_2 + 2) + sta (L_3 + 2) + sta (L_4 + 2) + lda (KNIGHT_TL + 3) + clc + adc #$04 + sta (L_0 + 3) + sta (L_1 + 3) + sta (L_2 + 3) + sta (L_3 + 3) + sta (L_4 + 3) + lda position + bne DrawDottedLinesPositionNot0 + lda (L_0 + 3) + sec + sbc #$0C + sta (L_0 + 3) + lda L_3 + sec + sbc #$04 + sta L_3 + inc (L_1 + 1) + inc (L_2 + 1) + lda L_1 + sec + sbc #$0C + sta L_1 + lda L_2 + sec + sbc #$14 + sta L_2 + lda (L_1 + 3) + sec + sbc #$10 + sta (L_1 + 3) + sta (L_2 + 3) + lda (L_3 + 3) + sec + sbc #$10 + sta (L_3 + 3) + sta (L_4 + 3) + jmp DrawDottedLinesDone +DrawDottedLinesPositionNot0: + cmp #$01 + bne DrawDottedLinesPositionNot1 + lda (L_0 + 3) + clc + adc #$0C + sta (L_0 + 3) + lda L_3 + sec + sbc #$04 + sta L_3 + inc (L_1 + 1) + inc (L_2 + 1) + lda L_1 + sec + sbc #$0C + sta L_1 + lda L_2 + sec + sbc #$14 + sta L_2 + lda (L_1 + 3) + clc + adc #$10 + sta (L_1 + 3) + sta (L_2 + 3) + sta (L_4 + 3) + lda (L_3 + 3) + clc + adc #$10 + sta (L_3 + 3) + lda (L_3 + 2) + ora #%01000000 + sta (L_3 + 2) + lda (L_4 + 2) + ora #%01000000 + sta (L_4 + 2) + jmp DrawDottedLinesDone +DrawDottedLinesPositionNot1: + cmp #$02 + bne DrawDottedLinesPositionNot2 + lda (L_0 + 3) + clc + adc #$0C + sta (L_0 + 3) + lda L_3 + sec + sbc #$04 + sta L_3 + lda (L_1 + 3) + clc + adc #$14 + sta (L_1 + 3) + adc #$08 + sta (L_2 + 3) + adc #$04 + sta (L_3 + 3) + sta (L_4 + 3) + lda (L_3 + 2) + ora #%01000000 + sta (L_3 + 2) + lda (L_4 + 2) + ora #%01000000 + sta (L_4 + 2) + jmp DrawDottedLinesDone +DrawDottedLinesPositionNot2: + cmp #$03 + bne DrawDottedLinesPositionNot3 + lda (L_0 + 3) + clc + adc #$0C + sta (L_0 + 3) + lda L_3 + clc + adc #$04 + sta L_3 + lda (L_1 + 3) + clc + adc #$14 + sta (L_1 + 3) + adc #$08 + sta (L_2 + 3) + adc #$04 + sta (L_3 + 3) + sta (L_4 + 3) + lda (L_3 + 2) + ora #%11000000 + sta (L_3 + 2) + lda (L_4 + 2) + ora #%11000000 + sta (L_4 + 2) + jmp DrawDottedLinesDone +DrawDottedLinesPositionNot3: + cmp #$04 + bne DrawDottedLinesPositionNot4 + lda (L_0 + 3) + clc + adc #$0C + sta (L_0 + 3) + lda L_3 + clc + adc #$04 + sta L_3 + inc (L_1 + 1) + inc (L_2 + 1) + lda L_1 + clc + adc #$0C + sta L_1 + lda L_2 + clc + adc #$14 + sta L_2 + lda (L_1 + 3) + clc + adc #$10 + sta (L_1 + 3) + sta (L_2 + 3) + lda (L_3 + 3) + clc + adc #$10 + sta (L_3 + 3) + sta (L_4 + 3) + lda (L_3 + 2) + ora #%11000000 + sta (L_3 + 2) + lda (L_4 + 2) + ora #%11000000 + sta (L_4 + 2) + jmp DrawDottedLinesDone +DrawDottedLinesPositionNot4: + cmp #$05 + bne DrawDottedLinesPositionNot5 + lda (L_0 + 3) + sec + sbc #$0C + sta (L_0 + 3) + lda L_3 + clc + adc #$04 + sta L_3 + inc (L_1 + 1) + inc (L_2 + 1) + lda L_1 + clc + adc #$0C + sta L_1 + lda L_2 + clc + adc #$14 + sta L_2 + lda (L_1 + 3) + sec + sbc #$10 + sta (L_1 + 3) + sta (L_2 + 3) + lda (L_3 + 3) + sec + sbc #$10 + sta (L_3 + 3) + sta (L_4 + 3) + lda (L_3 + 2) + ora #%10000000 + sta (L_3 + 2) + lda (L_4 + 2) + ora #%10000000 + sta (L_4 + 2) + jmp DrawDottedLinesDone +DrawDottedLinesPositionNot5: + cmp #$06 + bne DrawDottedLinesPositionNot6 + lda (L_0 + 3) + sec + sbc #$0C + sta (L_0 + 3) + lda L_3 + clc + adc #$04 + sta L_3 + lda (L_1 + 3) + sec + sbc #$14 + sta (L_1 + 3) + sbc #$08 + sta (L_2 + 3) + sbc #$04 + sta (L_3 + 3) + sta (L_4 + 3) + lda (L_3 + 2) + ora #%10000000 + sta (L_3 + 2) + lda (L_4 + 2) + ora #%10000000 + sta (L_4 + 2) + jmp DrawDottedLinesDone +DrawDottedLinesPositionNot6: + lda (L_0 + 3) + sec + sbc #$0C + sta (L_0 + 3) + lda L_3 + sec + sbc #$04 + sta L_3 + lda (L_1 + 3) + sec + sbc #$14 + sta (L_1 + 3) + sbc #$08 + sta (L_2 + 3) + sbc #$04 + sta (L_3 + 3) + sta (L_4 + 3) + jmp DrawDottedLinesDone +DrawDottedLinesDone: + rts + +UpdateDisallowedPositions: + lda knightPosition + and #%00111000 + lsr + lsr + lsr + tax + lda knightPosition + and #%00000111 + tay + iny + lda #%00000000 + sec +UpdateDisallowedPositionsLoop: + ror + dey + bne UpdateDisallowedPositionsLoop + sta tmp + lda broken, X + ora tmp + sta broken, X + rts + +CheckDisallowedPositions: + sta availablePositionsTmp + lda knightPosition + sec + sbc #$11 + sta positionRealTmp + lda availablePositions + and #%00000001 + beq CheckDisallowedPosition1 + lda positionRealTmp + jsr CheckAPositionBroken + beq CheckDisallowedPosition1 + lda availablePositions + and #%11111110 + sta availablePositions +CheckDisallowedPosition1: + lda positionRealTmp + clc + adc #$02 + sta positionRealTmp + lda availablePositions + and #%00000010 + beq CheckDisallowedPosition2 + lda positionRealTmp + jsr CheckAPositionBroken + beq CheckDisallowedPosition2 + lda availablePositions + and #%11111101 + sta availablePositions +CheckDisallowedPosition2: + lda positionRealTmp + clc + adc #$09 + sta positionRealTmp + lda availablePositions + and #%00000100 + beq CheckDisallowedPosition3 + lda positionRealTmp + jsr CheckAPositionBroken + beq CheckDisallowedPosition3 + lda availablePositions + and #%11111011 + sta availablePositions +CheckDisallowedPosition3: + lda positionRealTmp + clc + adc #$10 + sta positionRealTmp + lda availablePositions + and #%00001000 + beq CheckDisallowedPosition4 + lda positionRealTmp + jsr CheckAPositionBroken + beq CheckDisallowedPosition4 + lda availablePositions + and #%11110111 + sta availablePositions +CheckDisallowedPosition4: + lda positionRealTmp + clc + adc #$07 + sta positionRealTmp + lda availablePositions + and #%00010000 + beq CheckDisallowedPosition5 + lda positionRealTmp + jsr CheckAPositionBroken + beq CheckDisallowedPosition5 + lda availablePositions + and #%11101111 + sta availablePositions +CheckDisallowedPosition5: + lda positionRealTmp + sec + sbc #$02 + sta positionRealTmp + lda availablePositions + and #%00100000 + beq CheckDisallowedPosition6 + lda positionRealTmp + jsr CheckAPositionBroken + beq CheckDisallowedPosition6 + lda availablePositions + and #%11011111 + sta availablePositions +CheckDisallowedPosition6: + lda positionRealTmp + sec + sbc #$09 + sta positionRealTmp + lda availablePositions + and #%01000000 + beq CheckDisallowedPosition7 + lda positionRealTmp + jsr CheckAPositionBroken + beq CheckDisallowedPosition7 + lda availablePositions + and #%10111111 + sta availablePositions +CheckDisallowedPosition7: + lda positionRealTmp + sec + sbc #$10 + sta positionRealTmp + lda availablePositions + and #%10000000 + beq CheckDisallowedPositionsDone + lda positionRealTmp + jsr CheckAPositionBroken + beq CheckDisallowedPositionsDone + lda availablePositions + and #%01111111 + sta availablePositions +CheckDisallowedPositionsDone: + lda availablePositions + bne CheckDisallowedPositionsNotGameOver + lda #$01 + sta end +CheckDisallowedPositionsNotGameOver: + lda canFall + beq CheckDisallowedPositionsNotCanFall + lda availablePositionsTmp + sta availablePositions +CheckDisallowedPositionsNotCanFall: + rts + +CheckAPositionBroken: + sta tmp + and #%00111000 + lsr + lsr + lsr + tax + lda tmp + and #%00000111 + tay + iny + lda #%00000000 + sec +CheckAPositionBrokenLoop: + ror + dey + bne CheckAPositionBrokenLoop + sta tmp + lda broken, X + and tmp + rts + +CrackTile: + lda invisibleCracks + beq CrackTileContinue + lda #$00 + sta drawCrack + rts +CrackTileContinue: + lda crackPosition + and #%00001000 + lsr + lsr + lsr + eor crackPosition + eor #%00000001 + and #%00000001 + asl + clc + adc #$83 + sta crackColor + lda #$21 + sta crackAddr + lda #$08 + sta (crackAddr + 1) + lda crackPosition + and #%00111000 + lsr + lsr + lsr + tay + iny +CrackTitleIncAddrRowLoop: + dey + beq CrackTitleIncAddrRowLoopDone + lda (crackAddr + 1) + clc + adc #$40 + sta (crackAddr + 1) + lda crackAddr + adc #$00 + sta crackAddr + jmp CrackTitleIncAddrRowLoop +CrackTitleIncAddrRowLoopDone: + lda crackPosition + and #%00000111 + asl + clc + adc (crackAddr + 1) + sta (crackAddr + 1) + lda #$01 + sta drawCrack + rts + +PositionMovementBiases: + .byte $00, $00, $00, $00, $00, $00, $00, $00 + .byte $01, $01, $06, $00, $00, $00, $00, $00 + .byte $01, $01, $01, $01, $04, $00, $00, $00 + .byte $03, $01, $06, $03, $04, $05, $02, $00 + +MovePosition: + ldy #$00 + lda positionMoveOffset + and #%00000111 + cmp #$04 + bcc MovePositionNotInvertBits + eor #%00000111 + iny +MovePositionNotInvertBits: + asl + asl + asl + tax + stx (tmp + 1) +MovePositionLoop: + ldx (tmp + 1) + lda PositionMovementBiases, X + cpy #$01 + bne MovePositionLoopContinue + lda #$00 + sec + sbc PositionMovementBiases, X +MovePositionLoopContinue: + sta tmp + lda positionTmp + sec + sbc tmp + sta positionTmp + inc (tmp + 1) + and #%00000111 + jsr CheckAPositionAvailable + beq MovePositionLoop + lda positionTmp + and #%00000111 + sta positionTmp + rts + +CheckEndPosition: + ldy endPositionOption + beq CheckEndPositionDone + ldy knightPosition + cpy endPosition + bne CheckEndPositionDone + lda #$00 + sta availablePositions +CheckEndPositionDone: + rts diff --git a/src/powerpad.asm b/src/powerpad.asm new file mode 100644 index 0000000..3e856cd --- /dev/null +++ b/src/powerpad.asm @@ -0,0 +1,100 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +CheckPowerPad: + lda #$00 + sta tmp + jsr PowerPadCheckA + ora tmp + sta tmp + jsr PowerPadCheckB + ora tmp + sta tmp + jsr PowerPadCheckUp + ora tmp + sta tmp + jsr PowerPadCheckDown + ora tmp + sta tmp + jsr PowerPadCheckLeft + ora tmp + sta tmp + jsr PowerPadCheckRight + ora tmp + ora controller1D0 + sta controller1D0 + rts + +PowerPadCheckA: + ldx #$00 + lda controller1D4 + and #POWER_PAD_4 + beq PowerPadCheckADone + ldx #%10000000 +PowerPadCheckADone: + txa + rts + +PowerPadCheckB: + ldx #$00 + lda controller1D3 + and #POWER_PAD_1 + beq PowerPadCheckBDone + ldx #%01000000 +PowerPadCheckBDone: + txa + rts + +PowerPadCheckUp: + ldx #$00 + lda controller1D3 + and #POWER_PAD_2 + beq PowerPadCheckUpNot2 + ldx #%00001000 + txa + rts +PowerPadCheckUpNot2: + lda controller1D4 + and #POWER_PAD_3 + beq PowerPadCheckUpDone + ldx #%00001000 +PowerPadCheckUpDone: + txa + rts + +PowerPadCheckDown: + ldx #$00 + lda controller1D3 + and #POWER_PAD_10 + beq PowerPadCheckDownNot10 + ldx #%00000100 + txa + rts +PowerPadCheckDownNot10: + lda controller1D3 + and #POWER_PAD_11 + beq PowerPadCheckDownDone + ldx #%00000100 +PowerPadCheckDownDone: + txa + rts + +PowerPadCheckLeft: + ldx #$00 + lda controller1D3 + and #POWER_PAD_5 + beq PowerPadCheckLeftDone + ldx #%00000010 +PowerPadCheckLeftDone: + txa + rts + +PowerPadCheckRight: + ldx #$00 + lda controller1D4 + and #POWER_PAD_8 + beq PowerPadCheckRightDone + ldx #%00000001 +PowerPadCheckRightDone: + txa + rts diff --git a/src/prg.asm b/src/prg.asm new file mode 100644 index 0000000..8f9002b --- /dev/null +++ b/src/prg.asm @@ -0,0 +1,191 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +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 + +InitialVWait: + lda regionTmp + sta region + ldy #$00 + lda PPU_STATUS + bpl InitialVWait +InitialVWait2: + inx + bne InitialVWait2NotIncY + iny +InitialVWait2NotIncY: + lda PPU_STATUS + bpl InitialVWait2 + ldx #$00 + cpy #$09 + bne NotNTSC + lda #60 + inx + jmp InitialVWaitDone +NotNTSC: + lda #50 + cpy #$0A + bne NotPAL + jmp InitialVWaitDone +NotPAL: + cpy #$0B + bne NotDendy + ldx #$02 + jmp InitialVWaitDone +NotDendy: + ldx #$03 +InitialVWaitDone: + sta fps + stx regionTmp + cpx region + bne InitialVWait + +InitializeRAM: + jsr CheckResetCheck + sta wasReset + ldx #$00 +InitializeRAMLoop: + lda #$00 + cpx #wasReset + beq InitilizeRAMLoop0100 + cpx #topscore + beq InitilizeRAMLoop0100 + cpx #(topscore + 1) + beq InitilizeRAMLoop0100 + cpx #(topscore + 2) + beq InitilizeRAMLoop0100 + cpx #(topscore + 3) + beq InitilizeRAMLoop0100 + cpx #fps + beq InitilizeRAMLoop0100 + cpx #region + beq InitilizeRAMLoop0100 + cpx #regionTmp + beq InitilizeRAMLoop0100 + cpx #lfsr + beq InitilizeRAMLoop0100 + cpx #(lfsr + 1) + beq InitilizeRAMLoop0100 + cpx #(lfsr + 2) + beq InitilizeRAMLoop0100 + cpx #leftHanded + beq InitilizeRAMLoop0100 + cpx #canFall + beq InitilizeRAMLoop0100 + cpx #invisibleCracks + beq InitilizeRAMLoop0100 + cpx #invisibleGuides + beq InitilizeRAMLoop0100 + cpx #endPositionOption + beq InitilizeRAMLoop0100 +InitilizeRAMLoop0000: + sta $0000, x +InitilizeRAMLoop0100: + sta $0100, x + sta $0300, x + sta $0400, x + sta $0500, x + sta $0600, x + sta $0700, x + lda #$FE + sta $0200, x + inx + bne InitializeRAMLoop + lda wasReset + bne InitializeRAMReset + jsr DefaultOptions + lda #$00 + sta topscore + sta (topscore + 1) + sta (topscore + 2) + sta (topscore + 3) + jsr SetLFSR +InitializeRAMReset: + lda #$0F + ; TODO - Consider a situation where titleOption and pointer are the same + sta titleOption + jsr SetTopScoreToTopScoreTmp + jsr SetResetCheck + lda #SCREEN_TITLE + sta screen + + jsr ResetGraphics + jsr BlankPalette + lda #$01 + sta needDraw + jsr ResetScroll + jsr StartTitleScreen + +Forever: + jmp Forever + + + +NMI: + pha + txa + pha + tya + pha + lda #$00 + sta PPU_OAM_ADDR + lda #$02 + sta OAM_DMA + inc frames + lda regionCheck + bne NMIDone +NMINotRegionCheck: + jsr UpdateDone + lda needDraw + beq NMISkipDraw +NMIProgramStarted: + lda PPU_STATUS + jsr Draw + jsr ReadThenResetGraphics + jsr ResetScroll +NMISkipDraw: +NMIContinue: + lda updateDisabled + bne NMISkipUpdate + jsr Update +NMISkipUpdate: +NMIDone: + pla + tay + pla + tax + pla + rti + +.include "draw.asm" +.include "controller.asm" +.include "position.asm" +.include "knight.asm" +.include "board.asm" +.include "score.asm" +.include "time.asm" +.include "reset.asm" +.include "mouse.asm" +.include "rng.asm" +.include "powerpad.asm" +.include "title.asm" +.include "options.asm" + +.include "graphics.asm" +;.include "screen.asm" +.include "frames.asm" +.include "update.asm" +.include "math.asm" diff --git a/src/ram.asm b/src/ram.asm new file mode 100644 index 0000000..5d42eca --- /dev/null +++ b/src/ram.asm @@ -0,0 +1,126 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +.enum $0000 +Variables: + pointer dsb 1 + + needDraw dsb 1 + regionCheck dsb 1 + updateDisabled dsb 1 + + frames dsb 1 + timer dsb 1 + +; Options (MUST BE IN ORDER) +OptionsVariables: + leftHanded dsb 1 + canFall dsb 1 + invisibleCracks dsb 1 + invisibleGuides dsb 1 + endPositionOption dsb 1 + + addr dsb 2 + spriteTable dsb 1 + backgroundTable dsb 1 + + screen dsb 1 + drawNewScreen dsb 1 + + titleOption dsb 1 + titleFrames dsb 1 + titleOptionHover dsb 1 + + lfsr dsb 3 + broken dsb 8 + + wasReset dsb 1 + + fps dsb 1 + region dsb 1 + regionTmp dsb 1 + + closestPositionLeft dsb 1 + closestPositionRight dsb 1 + newPositionLeft dsb 1 + newPositionRight dsb 1 + tmp dsb 2 + endPosition dsb 1 + knightPosition dsb 1 + knightPositionNew dsb 1 + knightFrame dsb 1 + positionFrame dsb 1 + position dsb 1 + + redrawSprites dsb 1 + animateKnight dsb 1 + availablePositions dsb 1 + + availablePositionsTmp dsb 1 + + positionRealTmp dsb 1 + positionTmp dsb 1 + positionMoveOffset dsb 1 + + crackPosition dsb 1 + crackAddr dsb 2 + crackAddrTmp dsb 2 + crackColor dsb 1 + drawCrack dsb 1 + + time dsb 3 + timeInc dsb 3 + timeFrame dsb 1 + currentBoardScore dsb 2 + score dsb 4 + topscore dsb 4 + topscoreTmp dsb 4 + end dsb 1 + + started dsb 1 + pointerFrames dsb 1 + +.ende + +.enum $00FA + resetCheck0 dsb 6 +.ende + +.enum $03FA + resetCheck3 dsb 6 +.ende + +.enum $04FA + resetCheck4 dsb 6 +.ende + +.enum $0500 + cursorPosition dsb 1 + controller1D0 dsb 4 + controller1D0LastFrame dsb 4 + controller1D0Final dsb 2 + controller1D3 dsb 1 + controller1D4 dsb 1 + controllerType dsb 1 + controllerTypeLastFrame dsb 1 + snesMouseReady dsb 1 +.ende +.enum $05FA + resetCheck5 dsb 6 +.ende + +.enum $06FA + resetCheck6 dsb 6 +.ende + +.enum $0700 + scoreCodeLFSR dsb 3 + knightPositionLFSR dsb 3 + endPositionTrue dsb 1 + runScore dsb 1 + runTime dsb 3 +.ende + +.enum $07FA + resetCheck7 dsb 6 +.ende diff --git a/src/reset.asm b/src/reset.asm new file mode 100644 index 0000000..4c94879 --- /dev/null +++ b/src/reset.asm @@ -0,0 +1,49 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +SetResetCheck: + ldx #$05 +SetResetCheckLoop: + lda KNIGHTWord, X + sta $00FA, X + sta $03FA, X + sta $04FA, X + sta $05FA, X + sta $06FA, X + sta $07FA, X + dex + bpl SetResetCheckLoop + rts + +CheckResetCheck: + lda #$FA + sta tmp + ldy #$05 +CheckResetCheckLoopStart: + lda #$00 + sta (tmp + 1) +CheckResetCheckLoop: + lda (tmp), Y + cmp (KNIGHTWord), Y + bne CheckResetWasReset + lda (tmp + 1) + bne CheckResetCheckLoopTmp2Not0 + inc (tmp + 1) + inc (tmp + 1) +CheckResetCheckLoopTmp2Not0: + inc (tmp + 1) + lda (tmp + 1) + cmp #$08 + bne CheckResetCheckLoop + dey + bmi CheckResetCheckDone + jmp CheckResetCheckLoopStart +CheckResetWasReset: + lda #$00 + rts +CheckResetCheckDone: + lda #$01 + rts + +KNIGHTWord: + .byte "KNIGHT" diff --git a/src/rng.asm b/src/rng.asm new file mode 100644 index 0000000..e69d67e --- /dev/null +++ b/src/rng.asm @@ -0,0 +1,42 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +LFSR: + ldx #$03 +LFSRRoundLoopStart: + ldy #$08 + lda lfsr +LFSRLoop: + lsr + ror (lfsr + 1) + ror (lfsr + 2) + bcc LFSRLoopContinue + eor #%11011000 +LFSRLoopContinue: + dey + bne LFSRLoop + sta lfsr + dex + bne LFSRRoundLoopStart + lda (lfsr + 1) + eor controller1D0 + eor (controller1D0 + 1) + sta (lfsr + 1) + rts + +SetLFSR: + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$00 + sta PPU_ADDR + lda PPU_DATA + lda PPU_DATA + eor #$63 + sta lfsr + lda PPU_DATA + eor #$C8 + sta (lfsr + 1) + lda #$16 + sta (lfsr + 2) + rts diff --git a/src/score.asm b/src/score.asm new file mode 100644 index 0000000..365b65b --- /dev/null +++ b/src/score.asm @@ -0,0 +1,166 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +IncScore: + ldx #$03 +IncScoreLoop: + inc score, X + lda score, X + cmp #$0A + bcs IncScoreLoopContinue + rts +IncScoreLoopContinue: + cpx #$00 + beq IncScoreLoopMaxScore + lda #$00 + sta score, X + dex + bpl IncScoreLoop + rts +IncScoreLoopMaxScore: + ldy #$03 + lda #$09 +IncScoreLoopMaxScoreLoop: + sta score, Y + dey + bpl IncScoreLoopMaxScoreLoop + rts + +IncCurrentBoardScore: + ldx #$01 +IncCurrentBoardScoreLoop: + inc currentBoardScore, X + lda currentBoardScore, X + cmp #$0A + bcs IncCurrentBoardScoreLoopContinue + rts +IncCurrentBoardScoreLoopContinue: + lda #$00 + sta currentBoardScore, X + dex + bpl IncCurrentBoardScoreLoop + rts + +UpdateTopScore: + ldy #$00 +UpdateTopScoreLoop: + lda score, Y + cmp topscoreTmp, Y + bcc UpdateTopScoreDone + bne UpdateTopScoreToScoreUpdate + iny + cpy #$04 + bne UpdateTopScoreLoop + rts +UpdateTopScoreToScoreUpdate: + ldy #$03 +UpdateTopScoreToScoreUpdateLoop: + lda score, Y + sta topscoreTmp, Y + dey + bpl UpdateTopScoreToScoreUpdateLoop +UpdateTopScoreDone: + rts + +SetTopScoreToTopScoreTmp: + ldy #$03 +SetTopScoreToTopScoreTmpLoop: + lda topscore, Y + sta topscoreTmp, Y + dey + bpl SetTopScoreToTopScoreTmpLoop + rts + +SetTopScoreTmpToTopScore: + ldy #$03 +SetTopScoreTmpToTopScoreLoop: + lda topscoreTmp, Y + sta topscore, Y + dey + bpl SetTopScoreTmpToTopScoreLoop + rts + +DrawScore: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + lda #$20 + sta graphics, X + inx + lda #$B3 + sta graphics, X + inx + lda #"S" + sta graphics, X + inx + lda #"C" + sta graphics, X + inx + lda #"O" + sta graphics, X + inx + lda #"R" + sta graphics, X + inx + lda #"E" + sta graphics, X + inx + lda #$3A + sta graphics, X + inx + ldy #$00 +DrawScoreLoop: + lda score, Y + clc + adc #$30 + sta graphics, X + inx + iny + cpy #$04 + bne DrawScoreLoop + stx graphicsPointer + rts + +DrawTopScore: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + lda #$20 + sta graphics, X + inx + lda #$75 + sta graphics, X + inx + sta PPU_ADDR + lda #"T" + sta graphics, X + inx + lda #"O" + sta graphics, X + inx + lda #"P" + sta graphics, X + inx + lda #$3A + sta graphics, X + inx + ldy #$00 +DrawTopScoreLoop: + lda topscoreTmp, Y + clc + adc #$30 + sta graphics, X + inx + iny + cpy #$04 + bne DrawTopScoreLoop + stx graphicsPointer + rts diff --git a/src/scorecode.asm b/src/scorecode.asm new file mode 100644 index 0000000..2d8a6b6 --- /dev/null +++ b/src/scorecode.asm @@ -0,0 +1,13 @@ +; LLLL LLLL LLLL LLLL LLLL LLLL +; ++++ ++++ ++++ ++++ ++++ ++++- LFSR of Score Code +; +; KKKK KKKK KKKK KKKK KKKK KKKK +; ++++ ++++ ++++ ++++ ++++ ++++- LFSR of Initial Knight Position +; +; EVVV VVVV +; |+++ ++++- Score Code Version/Subset +; +--------- End position true/false +; +; SS SSSSTT +; || ||||++- Time leftmost 2 bits +; ++ ++++--- Score diff --git a/src/screen.asm b/src/screen.asm new file mode 100644 index 0000000..6af81f8 --- /dev/null +++ b/src/screen.asm @@ -0,0 +1,51 @@ +NMISplit: + jmp NMIDone + + ; Draw Previous Frame Code Here + lda drawNewScreen + beq NMINotNewScreenDraw + ;;;;; New screen is ready to be drawn + jsr NMIDrawNewScreen + lda #$00 + sta drawNewScreen + jmp NMIDone + ; rti + ; End NMI (subroutine) + +NMINotNewScreenDraw: + lda screen + cmp #SCREEN_BOARD + bne NMINotScreenBoard + ; Do every frame Board screen +NMINotScreenBoard: + lda screen + cmp #SCREEN_OPTIONS + bne NMINotScreenOptions + ; Do every frame Options screen + jsr DrawOptionsValues +NMINotScreenOptions: + ; Draw Previous Frame Code Here + jmp NMIContinue + ;rts + + + +NMIDrawNewScreen: + jsr BlankPalettes + lda screen + cmp #SCREEN_TITLE + bne NMIDrawNewScreenNotTitle + jsr StartTitleScreen + rts +NMIDrawNewScreenNotTitle: + cmp #SCREEN_BOARD + bne NMIDrawNewScreenNotBoard + jsr StartBoardScreen + rts +NMIDrawNewScreenNotBoard: + cmp #SCREEN_OPTIONS + bne NMIDrawNewScreenNotOptions + jsr StartOptionsScreen + rts +NMIDrawNewScreenNotOptions: + rts diff --git a/src/time.asm b/src/time.asm new file mode 100644 index 0000000..7af10eb --- /dev/null +++ b/src/time.asm @@ -0,0 +1,135 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +IncTimer: + ldx #$02 + inc timeFrame + lda timeFrame + cmp fps + bcc IncTimerDone + lda #$00 + sta timeFrame +IncTimerLoop: + inc time, X + lda time, X + cmp #$0A + bcc IncTimerDone + lda #$00 + sta time, X + dex + bpl IncTimerLoop + lda #$09 + sta time + sta (time + 1) + sta (time + 2) +IncTimerDone: + rts + +DecTime: + ldx #$02 + inc timeFrame + lda timeFrame + cmp fps + bcc DecTimeDone + lda #$00 + sta timeFrame +DecTimeLoop: + dec time, X + lda time, X + bpl DecTimeDone + lda #$09 + sta time, X + dex + bpl DecTimeLoop + lda #$00 + sta time + sta (time + 1) + sta (time + 2) +DecTimeDone: + rts + +CheckTimer000: + lda time + ora (time + 1) + ora (time + 2) + bne CheckTimer000Done + lda #$01 + sta end +CheckTimer000Done: + rts + +DrawTimer: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + lda #$20 + sta graphics, X + inx + lda #$A3 + sta graphics, X + inx + lda #"T" + sta graphics, X + inx + lda #"I" + sta graphics, X + inx + lda #"M" + sta graphics, X + inx + lda #"E" + sta graphics, X + inx + lda #$3A + sta graphics, X + inx + ldy #$00 +DrawTimerLoop: + lda time, Y + clc + adc #$30 + sta graphics, X + inx + iny + cpy #$03 + bne DrawTimerLoop + stx graphicsPointer + rts + +IncTimerByTimeInc: + ldx #$02 +IncTimerByTimeIncLoop: + lda time, X + clc + adc timeInc, X + sta time, X + dex + bpl IncTimerByTimeIncLoop + ldx #$02 +IncTimerByTimeIncNormalizeTimer: + lda time, X + cmp #$0A + bcc IncTimerByTimeIncNormalizeContinue + sec + sbc #$0A + sta time, X + dex + inc time, X + inx +IncTimerByTimeIncNormalizeContinue: + dex + bne IncTimerByTimeIncNormalizeTimer +IncTimerByTimeIncCheckMaxTime: + lda time + cmp #$0A + bcc IncTimerByTimeIncDone + lda #$09 + sta time + sta (time + 1) + sta (time + 2) +IncTimerByTimeIncDone: + rts diff --git a/src/title.asm b/src/title.asm new file mode 100644 index 0000000..cc7083f --- /dev/null +++ b/src/title.asm @@ -0,0 +1,384 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + +StartTitleScreen: + ; Turn screen completely black for 1 frame to avoid flicker/tear + jsr BlankScreen + ; Turn screen and NMI off + jsr Blank + ; Set screen to SCREEN_TITLE + lda #SCREEN_TITLE + sta screen + ; Set background table to pattern table 01 + lda #$01 + sta backgroundTable + ; Initialize titleFrames and started. + ; Set sprite table to pattern table 00 + lda #$00 + sta titleFrames + ; Consider a situation where started is not needed + sta started + sta spriteTable + jsr DrawTitleScreen + jsr SetTitleScreenPalette + jsr UpdateDone + jsr ReadThenResetGraphics + ; Initialize controller1 last frame to say all buttons pressed + lda #$FF + sta controller1D0LastFrame + sta (controller1D0LastFrame + 1) + ; Check if controller is a SNES mouse + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + bne StartTitleScreenNotSNESMouse + ; Check if SNES mouse is ready + lda snesMouseReady + beq StartTitleScreenNotSNESMouse + ; Draw cursor if SNES mouse is ready + jsr DrawCursor +StartTitleScreenNotSNESMouse: + ; Place option pointer based on mouse cursor + jsr CursorTitleOption + jsr ManageTitleOption + ; Draw option pointer based on what titleOption is set to + jsr DrawTitleOptionCursor + jsr CursorTitleOption + ; Set newDraw for when new frame happens + jsr ReadThenResetGraphics + jsr DisableLevelModeAttr + lda #$01 + sta needDraw + ; Re-enable NMI + jsr ResetScroll + rts + +DrawTitleScreen: + lda #<(TitleScreen) + sta addr + lda #>(TitleScreen) + sta (addr + 1) + ldx #$04 + ldy #$00 + lda PPU_STATUS + lda #$20 + sta PPU_ADDR + lda #$00 + sta PPU_ADDR +DrawTitleScreenLoop: + lda (addr), Y + sta PPU_DATA + iny + bne DrawTitleScreenLoop + inc (addr + 1) + dex + bne DrawTitleScreenLoop + rts + +SetTitleScreenPalette: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + lda #$3F + sta graphics, X + inx + lda #$00 + sta graphics, X + inx + ldy #$04 +SetTitleScreenPaletteBackgroundLoop: + lda #$0F + sta graphics, X + inx + lda #$80 + sta graphics, X + inx + lda #$00 + sta graphics, X + inx + lda #$80 + sta graphics, X + inx + lda #$00 + sta graphics, X + inx + lda #$2D + cpy #$04 + bne SetTitleScreenPaletteBackgroundLoopContinue + lda #$30 +SetTitleScreenPaletteBackgroundLoopContinue: + sta graphics, X + inx + dey + bne SetTitleScreenPaletteBackgroundLoop + ldy #$04 +SetTitleScreenPaletteSpritesLoop: + lda #$0F + sta graphics, X + inx + sta graphics, X + inx + sta graphics, X + inx + lda #$30 + sta graphics, X + inx + dey + bne SetTitleScreenPaletteSpritesLoop + stx graphicsPointer + rts + +DisableLevelModeAttr: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FE + sta graphics, X + inx + lda #$23 + sta graphics, X + inx + lda #$D9 + sta graphics, X + inx + lda #$0C + sta graphics, X + inx + lda #$0F + sta graphics, X + inx + sta graphics, X + inx + stx graphicsPointer + rts + + + + +; TODO FIGURE OUT WHAT THIS CODE DOES!!! +; This is a hack-y way of preventing options during preview runs +ManageTitleOption: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + bne ManageTitleOptionsNotSNESMouse + lda titleOption + bne ManageTitleOptionsSNESMouseTitleOptionNot0 + lda #$03 + sta titleOption +ManageTitleOptionsSNESMouseTitleOptionNot0: + rts +ManageTitleOptionsNotSNESMouse: + ; hack + lda titleOption + bne HackManageTitleOptionNot0 + lda #$02 + sta titleOption +HackManageTitleOptionNot0: + ; hack + lda titleOption + and #%10000000 + beq ManageTitleOptionsNotNegative + lda #$02 + sta titleOption +ManageTitleOptionsNotNegative: + lda titleOption + cmp #$03 + bcc ManageTitleOptionsNotOverflow + ; hack + lda #$01 + ; hack +ManageTitleOptionsNotOverflow: + sta titleOption + rts + + + + +CheckControllerTitleScreen: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + bne CheckControllerTitleScreenNotSNESMouse + jsr CheckLeftClickTitleScreen + rts +CheckControllerTitleScreenNotSNESMouse: + jsr CheckATitleScreen + jsr CheckUpTitleScreen + jsr CheckDownTitleScreen + rts + +CheckATitleScreen: + lda controller1D0Final + and #BUTTON_A + beq CheckATitleScreenDone + lda titleOption + cmp #TITLE_OPTION_LEVEL_MODE + bne CheckATitleScreenOptionNotLevelMode + rts +CheckATitleScreenOptionNotLevelMode: + cmp #TITLE_OPTION_SCORE_MODE + bne CheckATitleScreenOptionNotScoreMode + jsr ResetTimeScore + jsr StartBoardScreen + rts +CheckATitleScreenOptionNotScoreMode: + cmp #TITLE_OPTION_OPTIONS + bne CheckATitleScreenOptionNotOptions + jsr StartOptionsScreen + rts +CheckATitleScreenOptionNotOptions: +CheckATitleScreenDone: + rts + +CheckUpTitleScreen: + lda controller1D0Final + and #BUTTON_UP + beq CheckUpTitleScreenDone + dec titleOption +CheckUpTitleScreenDone: + rts + +CheckDownTitleScreen: + lda controller1D0Final + and #BUTTON_DOWN + beq CheckDownTitleScreenDone + inc titleOption +CheckDownTitleScreenDone: + rts + +DrawTitleOptionCursor: + lda titleOption + cmp #TITLE_OPTION_OPTIONS + 1 + bcc DrawTitleOptionCursorContinue + jsr ErasePointer + rts +DrawTitleOptionCursorContinue: + ldy #$20 + lda titleOption + asl + asl + asl + asl + clc + adc #$5F + sta $2FC + lda #$13 + sta $2FD + lda #%00000000 + sta $2FE + lda titleFrames + and #%00001000 + beq DrawTitleOptionCursorFinish + lda titleFrames + and #%00010000 + bne DrawTitleOptionCursorNot3 + dey + jmp DrawTitleOptionCursorFinish +DrawTitleOptionCursorNot3: + iny +DrawTitleOptionCursorFinish: + sty $2FF + rts + +CheckLeftClickTitleScreen: + lda (controller1D0Final + 1) + and #LEFT_CLICK + beq CheckLeftClickTitleScreenDone + lda titleOption + cmp #TITLE_OPTION_LEVEL_MODE + bne CheckLeftClickTitleScreenOptionNotLevelMode + rts +CheckLeftClickTitleScreenOptionNotLevelMode: + cmp #TITLE_OPTION_SCORE_MODE + bne CheckLeftClickTitleScreenOptionNotScoreMode + jsr ResetTimeScore + jsr StartBoardScreen + rts +CheckLeftClickTitleScreenOptionNotScoreMode: + cmp #TITLE_OPTION_OPTIONS + bne CheckLeftClickTitleScreenOptionNotOptions + jsr StartOptionsScreen + rts +CheckLeftClickTitleScreenOptionNotOptions: +CheckLeftClickTitleScreenDone: + rts + +CursorTitleOption: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + beq CursorTitleOptionContinue + rts +CursorTitleOptionContinue: + ldy #$00 + ldx #$00 +CursorTitleOptionYPositionLoop: + lda CURSOR + cmp TitleOptionsHitBoxes, X + bcs CursorTitleOptionCheckRange8 + ldy #OPTIONS_TITLE_SCREEN + 1 + sty titleOption + rts +CursorTitleOptionCheckRange8: + lda TitleOptionsHitBoxes, X + inx + inx + inx + inx + clc + adc #$08 + sta tmp + lda CURSOR + cmp tmp + bcs CursorTitleOptionYPositionNotCorrect + sty titleOption + jsr CursorTitleOptionHorizontal + rts +CursorTitleOptionYPositionNotCorrect: + iny + cpy #OPTIONS_TITLE_SCREEN + 1 + bne CursorTitleOptionYPositionLoop + sty titleOption + rts + +CursorTitleOptionHorizontal: + lda titleOption + asl + asl + tax + inx + lda TitleOptionsHitBoxes, X + sta tmp + lda (CURSOR + 3) + cmp tmp + bcs CursorTitleOptionHorizontalNotTooLeft + ldy #OPTIONS_TITLE_SCREEN + 1 + sty titleOption + rts +CursorTitleOptionHorizontalNotTooLeft: + inx + lda TitleOptionsHitBoxes, X + asl + asl + asl + clc + adc tmp + sta tmp + lda (CURSOR + 3) + cmp tmp + bcc CursorTitleOptionHoriziontalNotTooFarRight + ldy #OPTIONS_TITLE_SCREEN + 1 + sty titleOption +CursorTitleOptionHoriziontalNotTooFarRight: + rts + +TitleOptionsHitBoxes: + .byte $5F, $30, $0A, $00 + .byte $6F, $30, $0A, $00 + .byte $7F, $30, $07, $00 + +TitleScreen: + .incbin "graphics/title.nam" + .incbin "graphics/title.atr" diff --git a/src/update.asm b/src/update.asm new file mode 100644 index 0000000..a66f4db --- /dev/null +++ b/src/update.asm @@ -0,0 +1,117 @@ +; Copyright (C) 2020, Vi Grey +; All rights reserved. + + +Update: + jsr LFSR + jsr PollController + jsr ModifyController + jsr UpdateScreen + rts + +UpdateDone: + ldx graphicsPointer + lda #$00 + sta graphics, X + inx + lda #$FF + sta graphics, X + inx + stx graphicsPointer + rts + +UpdateScreen: + lda screen + cmp #SCREEN_TITLE + bne UpdateScreenNotTitle + jsr UpdateTitleScreen + rts +UpdateScreenNotTitle: + cmp #SCREEN_OPTIONS + bne UpdateScreenNotOptions + jsr UpdateOptionsScreen + rts +UpdateScreenNotOptions: + cmp #SCREEN_BOARD + bne UpdateScreenNotBoard + jsr UpdateBoardScreen + rts +UpdateScreenNotBoard: + rts + +UpdateTitleScreen: + jsr MoveCursor + jsr CursorTitleOption + jsr ManageTitleOption + jsr DrawTitleOptionCursor + inc titleFrames + jsr CheckControllerTitleScreen + rts + +UpdateOptionsScreen: + jsr MoveCursor + jsr CursorOptionPointer + jsr ModifyOptionsPointer + jsr DrawOptionsPointer + jsr CheckControllerOptionsScreen + rts + +UpdateBoardScreen: + jsr DrawBoardTopBar + lda drawCrack + beq UpdateBoardNotDrawCrack + jsr DrawCrack +UpdateBoardNotDrawCrack: + ;jsr IncTimer + jsr DecTime + jsr CheckTimer000 + lda end + beq UpdateBoardNotEnd + lda #$01 + sta updateDisabled + jsr CheckBoardFinished + jsr StartBoardScreen + lda #$00 + sta updateDisabled + rts +UpdateBoardNotEnd: + lda timeFrame + cmp #$02 + bcc UpdateBoardContinue + ; TODO figure out what this part does + lda #$01 + sta started +UpdateBoardContinue: + jsr MoveCursor + jsr DetermineCursorOverPosition + lda animateKnight + beq UpdateBoardNotAnimateKnight + ; While the knight is animated + jsr DisableDottedLines + jsr AnimateKnightStep + sta positionFrame + jsr UpdatePositionCorners + jsr ManageInvisibleGuides + rts +UpdateBoardNotAnimateKnight: + ; While the knight was not animated + lda redrawSprites + beq UpdateBoardNotRedrawSprites + jsr DrawKnight + jsr DrawCorners +UpdateBoardNotRedrawSprites: + lda controllerType + cmp #CONTROLLER_SNES_MOUSE + beq UpdateBoardSNESMouse + lda position + sta cursorPosition +UpdateBoardSNESMouse: + lda #$00 + sta redrawSprites + inc positionFrame + jsr DrawDottedLines + jsr UpdatePositionCorners + jsr CheckController +UpdateBoardDone: + jsr ManageInvisibleGuides + rts