initial commit
This commit is contained in:
commit
8e20553b52
19
LICENSE
Normal file
19
LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright © 2021 John Bintz
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the “Software”), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished
|
||||||
|
to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
20
README.md
Normal file
20
README.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# NES Password ROM
|
||||||
|
|
||||||
|
An NES ROM that shows how the Space character worked in Metroid passwords.
|
||||||
|
It was also an opportunity to learn 6502 assembler and the basics of
|
||||||
|
NES development! Visit
|
||||||
|
[r1kr.blog/read/nestextpasswordrom](https://r1kr.blog/read/nestextpasswordrom)
|
||||||
|
to learn more!
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
* Install [dasm](https://dasm-assembler.github.io/)
|
||||||
|
* Run `dasm password.asm -f3 -opassword.nes`
|
||||||
|
* Run `password.nes` in your favorite emulator.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
* 8bitworkshop: https://8bitworkshop.com/
|
||||||
|
* galois16: https://github.com/bbbradsmith/prng_6502/blob/master/galois16.s
|
||||||
|
* Calderon Handwriting Condensed: https://www.romhacking.net/fonts/32/
|
||||||
|
|
BIN
calderon_with_bamboo.chr
Normal file
BIN
calderon_with_bamboo.chr
Normal file
Binary file not shown.
70
data.asm
Normal file
70
data.asm
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
Letters
|
||||||
|
byte "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz?! "
|
||||||
|
Passwords
|
||||||
|
byte "D N E "
|
||||||
|
byte "! ! ! "
|
||||||
|
byte "T R O "
|
||||||
|
byte "H R O "
|
||||||
|
|
||||||
|
byte "JUSTIN"
|
||||||
|
byte "BAILEY"
|
||||||
|
byte "!a!b!c"
|
||||||
|
byte "!d!e!f"
|
||||||
|
|
||||||
|
byte "6eW3!!"
|
||||||
|
byte "!!!!00"
|
||||||
|
byte "F38W!H"
|
||||||
|
byte "C0042N"
|
||||||
|
|
||||||
|
byte "llv!?l"
|
||||||
|
byte "z!!mU4"
|
||||||
|
byte "!!y000"
|
||||||
|
byte "00m03x"
|
||||||
|
|
||||||
|
byte "DRAGON"
|
||||||
|
byte "BALL Z"
|
||||||
|
byte "Dragon"
|
||||||
|
byte "Ball z"
|
||||||
|
|
||||||
|
CanAlsoMessage
|
||||||
|
byte " might also be written as "
|
||||||
|
byte 0
|
||||||
|
|
||||||
|
AButtonMessage
|
||||||
|
byte "A - Change password"
|
||||||
|
byte 0
|
||||||
|
|
||||||
|
BButtonMessage
|
||||||
|
byte "B - Randomize alternative"
|
||||||
|
byte 0
|
||||||
|
|
||||||
|
R1KRTitleOne:
|
||||||
|
byte "The Rabbit with"
|
||||||
|
byte 0
|
||||||
|
R1KRTitleTwo:
|
||||||
|
byte "1000 Repos"
|
||||||
|
byte 0
|
||||||
|
|
||||||
|
R1KRBlogTitle:
|
||||||
|
byte "NES Text Passwords"
|
||||||
|
byte 0
|
||||||
|
|
||||||
|
R1KRBlogLinkOne:
|
||||||
|
byte "r1kr.blog/read/"
|
||||||
|
byte 0
|
||||||
|
|
||||||
|
R1KRBlogLinkTwo:
|
||||||
|
byte "nestextpasswordrom"
|
||||||
|
byte 0
|
||||||
|
|
||||||
|
Palette:
|
||||||
|
hex ff ;screen color
|
||||||
|
hex 0d262400 ;background 0
|
||||||
|
hex 0d262100 ;background 1
|
||||||
|
hex 0d262a00 ;background 2
|
||||||
|
hex 00122200 ;background 3
|
||||||
|
hex 19293900 ;sprite 0
|
||||||
|
hex 1a2a3a00 ;sprite 1
|
||||||
|
hex 1b2b3b00 ;sprite 2
|
||||||
|
hex 1c2c3c ;sprite 3
|
||||||
|
|
37
galois16.asm
Normal file
37
galois16.asm
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
;
|
||||||
|
; 6502 LFSR PRNG - 16-bit
|
||||||
|
; Brad Smith, 2019
|
||||||
|
; http://rainwarrior.ca
|
||||||
|
;
|
||||||
|
|
||||||
|
; A 16-bit Galois LFSR
|
||||||
|
|
||||||
|
; Possible feedback values that generate a full 65535 step sequence:
|
||||||
|
; $2D = %00101101
|
||||||
|
; $39 = %00111001
|
||||||
|
; $3F = %00111111
|
||||||
|
; $53 = %01010011
|
||||||
|
; $BD = %10111101
|
||||||
|
; $D7 = %11010111
|
||||||
|
|
||||||
|
; $39 is chosen for its compact bit pattern
|
||||||
|
|
||||||
|
; simplest version iterates the LFSR 8 times to generate 8 random bits
|
||||||
|
; 133-141 cycles per call
|
||||||
|
; 19 bytes
|
||||||
|
|
||||||
|
galois16: subroutine
|
||||||
|
ldy #8
|
||||||
|
lda Seed+0
|
||||||
|
.one
|
||||||
|
asl ; shift the register
|
||||||
|
rol Seed+1
|
||||||
|
bcc .two
|
||||||
|
eor #$39 ; apply XOR feedback whenever a 1 bit is shifted out
|
||||||
|
.two
|
||||||
|
dey
|
||||||
|
bne .one
|
||||||
|
sta Seed+0
|
||||||
|
cmp #0 ; reload flags
|
||||||
|
rts
|
||||||
|
|
184
nesdefs.dasm
Normal file
184
nesdefs.dasm
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
|
||||||
|
processor 6502
|
||||||
|
|
||||||
|
;;;;; CONSTANTS
|
||||||
|
|
||||||
|
PPU_CTRL = $2000
|
||||||
|
PPU_MASK = $2001
|
||||||
|
PPU_STATUS = $2002
|
||||||
|
OAM_ADDR = $2003
|
||||||
|
OAM_DATA = $2004
|
||||||
|
PPU_SCROLL = $2005
|
||||||
|
PPU_ADDR = $2006
|
||||||
|
PPU_DATA = $2007
|
||||||
|
|
||||||
|
PPU_OAM_DMA = $4014
|
||||||
|
DMC_FREQ = $4010
|
||||||
|
APU_STATUS = $4015
|
||||||
|
APU_NOISE_VOL = $400C
|
||||||
|
APU_NOISE_FREQ = $400E
|
||||||
|
APU_NOISE_TIMER = $400F
|
||||||
|
APU_DMC_CTRL = $4010
|
||||||
|
APU_CHAN_CTRL = $4015
|
||||||
|
APU_FRAME = $4017
|
||||||
|
|
||||||
|
JOYPAD1 = $4016
|
||||||
|
JOYPAD2 = $4017
|
||||||
|
|
||||||
|
; NOTE: I've put this outside of the PPU & APU, because it is a feature
|
||||||
|
; of the APU that is primarily of use to the PPU.
|
||||||
|
OAM_DMA = $4014
|
||||||
|
; OAM local RAM copy goes from $0200-$02FF:
|
||||||
|
OAM_RAM = $0200
|
||||||
|
|
||||||
|
; PPU_CTRL flags
|
||||||
|
CTRL_NMI = %10000000 ; Execute Non-Maskable Interrupt on VBlank
|
||||||
|
CTRL_8x8 = %00000000 ; Use 8x8 Sprites
|
||||||
|
CTRL_8x16 = %00100000 ; Use 8x16 Sprites
|
||||||
|
CTRL_BG_0000 = %00000000 ; Background Pattern Table at $0000 in VRAM
|
||||||
|
CTRL_BG_1000 = %00010000 ; Background Pattern Table at $1000 in VRAM
|
||||||
|
CTRL_SPR_0000 = %00000000 ; Sprite Pattern Table at $0000 in VRAM
|
||||||
|
CTRL_SPR_1000 = %00001000 ; Sprite Pattern Table at $1000 in VRAM
|
||||||
|
CTRL_INC_1 = %00000000 ; Increment PPU Address by 1 (Horizontal rendering)
|
||||||
|
CTRL_INC_32 = %00000100 ; Increment PPU Address by 32 (Vertical rendering)
|
||||||
|
CTRL_NT_2000 = %00000000 ; Name Table Address at $2000
|
||||||
|
CTRL_NT_2400 = %00000001 ; Name Table Address at $2400
|
||||||
|
CTRL_NT_2800 = %00000010 ; Name Table Address at $2800
|
||||||
|
CTRL_NT_2C00 = %00000011 ; Name Table Address at $2C00
|
||||||
|
|
||||||
|
; PPU_MASK flags
|
||||||
|
MASK_TINT_RED = %00100000 ; Red Background
|
||||||
|
MASK_TINT_BLUE = %01000000 ; Blue Background
|
||||||
|
MASK_TINT_GREEN = %10000000 ; Green Background
|
||||||
|
MASK_SPR = %00010000 ; Sprites Visible
|
||||||
|
MASK_BG = %00001000 ; Backgrounds Visible
|
||||||
|
MASK_SPR_CLIP = %00000100 ; Sprites clipped on left column
|
||||||
|
MASK_BG_CLIP = %00000010 ; Background clipped on left column
|
||||||
|
MASK_COLOR = %00000000 ; Display in Color
|
||||||
|
MASK_MONO = %00000001 ; Display in Monochrome
|
||||||
|
|
||||||
|
; read flags
|
||||||
|
F_BLANK = %10000000 ; VBlank Active
|
||||||
|
F_SPRITE0 = %01000000 ; VBlank hit Sprite 0
|
||||||
|
F_SCAN8 = %00100000 ; More than 8 sprites on current scanline
|
||||||
|
F_WIGNORE = %00010000 ; VRAM Writes currently ignored.
|
||||||
|
|
||||||
|
|
||||||
|
;;;;; CARTRIDGE FILE HEADER
|
||||||
|
|
||||||
|
NES_MIRR_HORIZ = 0
|
||||||
|
NES_MIRR_VERT = 1
|
||||||
|
NES_MIRR_QUAD = 8
|
||||||
|
|
||||||
|
MAC NES_HEADER
|
||||||
|
seg Header
|
||||||
|
org $7ff0
|
||||||
|
.NES_MAPPER SET {1} ;mapper number
|
||||||
|
.NES_PRG_BANKS SET {2} ;number of 16K PRG banks, change to 2 for NROM256
|
||||||
|
.NES_CHR_BANKS SET {3} ;number of 8K CHR banks (0 = RAM)
|
||||||
|
.NES_MIRRORING SET {4} ;0 horizontal, 1 vertical, 8 four screen
|
||||||
|
byte $4e,$45,$53,$1a ; header
|
||||||
|
byte .NES_PRG_BANKS
|
||||||
|
byte .NES_CHR_BANKS
|
||||||
|
byte .NES_MIRRORING|(.NES_MAPPER<<4)
|
||||||
|
byte .NES_MAPPER&$f0
|
||||||
|
byte 0,0,0,0,0,0,0,0 ; reserved, set to zero
|
||||||
|
seg Code
|
||||||
|
org $8000
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
;;;;; NES_INIT SETUP MACRO (place at start)
|
||||||
|
|
||||||
|
MAC NES_INIT
|
||||||
|
sei ;disable IRQs
|
||||||
|
cld ;decimal mode not supported
|
||||||
|
ldx #$ff
|
||||||
|
txs ;set up stack pointer
|
||||||
|
inx ;increment X to 0
|
||||||
|
stx PPU_MASK ;disable rendering
|
||||||
|
stx DMC_FREQ ;disable DMC interrupts
|
||||||
|
stx PPU_CTRL ;disable NMI interrupts
|
||||||
|
bit PPU_STATUS ;clear VBL flag
|
||||||
|
bit APU_CHAN_CTRL ;ack DMC IRQ bit 7
|
||||||
|
lda #$40
|
||||||
|
sta APU_FRAME ;disable APU Frame IRQ
|
||||||
|
lda #$0F
|
||||||
|
sta APU_CHAN_CTRL ;disable DMC, enable/init other channels.
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
;;;;; NES_VECTORS - CPU vectors at end of address space
|
||||||
|
|
||||||
|
MAC NES_VECTORS
|
||||||
|
seg Vectors ; segment "Vectors"
|
||||||
|
org $fffa ; start at address $fffa
|
||||||
|
.word NMIHandler ; $fffa vblank nmi
|
||||||
|
.word Start ; $fffc reset
|
||||||
|
.word NMIHandler ; $fffe irq / brk
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
;;;;; PPU_SETADDR <address> - set 16-bit PPU address
|
||||||
|
|
||||||
|
MAC PPU_SETADDR
|
||||||
|
lda #>{1} ; upper byte
|
||||||
|
sta PPU_ADDR
|
||||||
|
lda #<{1} ; lower byte
|
||||||
|
sta PPU_ADDR
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
;;;;; PPU_SETVALUE <value> - feed 8-bit value to PPU
|
||||||
|
|
||||||
|
MAC PPU_SETVALUE
|
||||||
|
lda #{1}
|
||||||
|
sta PPU_DATA
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
;;;;; SAVE_REGS - save A/X/Y registers
|
||||||
|
|
||||||
|
MAC SAVE_REGS
|
||||||
|
pha
|
||||||
|
txa
|
||||||
|
pha
|
||||||
|
tya
|
||||||
|
pha
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
;;;;; RESTORE_REGS - restore Y/X/A registers
|
||||||
|
|
||||||
|
MAC RESTORE_REGS
|
||||||
|
pla
|
||||||
|
tay
|
||||||
|
pla
|
||||||
|
tax
|
||||||
|
pla
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; SLEEP clockcycles
|
||||||
|
; Original author: Thomas Jentzsch
|
||||||
|
; Inserts code which takes the specified number of cycles to execute. This is
|
||||||
|
; useful for code where precise timing is required.
|
||||||
|
; LEGAL OPCODE VERSION MAY AFFECT FLAGS (uses 'bit' opcode)
|
||||||
|
|
||||||
|
NO_ILLEGAL_OPCODES = 1
|
||||||
|
|
||||||
|
MAC SLEEP ;usage: SLEEP n (n>1)
|
||||||
|
.CYCLES SET {1}
|
||||||
|
|
||||||
|
IF .CYCLES < 2
|
||||||
|
ECHO "MACRO ERROR: 'SLEEP': Duration must be > 1"
|
||||||
|
ERR
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF .CYCLES & 1
|
||||||
|
IFNCONST NO_ILLEGAL_OPCODES
|
||||||
|
nop 0
|
||||||
|
ELSE
|
||||||
|
bit $00
|
||||||
|
ENDIF
|
||||||
|
.CYCLES SET .CYCLES - 3
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
REPEAT .CYCLES / 2
|
||||||
|
nop
|
||||||
|
REPEND
|
||||||
|
ENDM
|
64
nesppu.dasm
Normal file
64
nesppu.dasm
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
;;;;; SUBROUTINES
|
||||||
|
|
||||||
|
ClearRAM: subroutine
|
||||||
|
lda #0 ; A = 0
|
||||||
|
tax ; X = 0
|
||||||
|
.clearRAM
|
||||||
|
sta $0,x ; clear $0-$ff
|
||||||
|
cpx #$fe ; last 2 bytes of stack?
|
||||||
|
bcs .skipStack ; don't clear it
|
||||||
|
sta $100,x ; clear $100-$1fd
|
||||||
|
.skipStack
|
||||||
|
sta $200,x ; clear $200-$2ff
|
||||||
|
sta $300,x ; clear $300-$3ff
|
||||||
|
sta $400,x ; clear $400-$4ff
|
||||||
|
sta $500,x ; clear $500-$5ff
|
||||||
|
sta $600,x ; clear $600-$6ff
|
||||||
|
sta $700,x ; clear $700-$7ff
|
||||||
|
inx ; X = X + 1
|
||||||
|
bne .clearRAM ; loop 256 times
|
||||||
|
rts
|
||||||
|
|
||||||
|
; wait for VSYNC to start
|
||||||
|
WaitSync:
|
||||||
|
bit PPU_STATUS
|
||||||
|
bpl WaitSync
|
||||||
|
rts
|
||||||
|
|
||||||
|
;;;;; RANDOM NUMBERS
|
||||||
|
|
||||||
|
NextRandom subroutine
|
||||||
|
lsr
|
||||||
|
bcc .NoEor
|
||||||
|
eor #$d4
|
||||||
|
.NoEor:
|
||||||
|
rts
|
||||||
|
; Get previous random value
|
||||||
|
PrevRandom subroutine
|
||||||
|
asl
|
||||||
|
bcc .NoEor
|
||||||
|
eor #$a9
|
||||||
|
.NoEor:
|
||||||
|
rts
|
||||||
|
|
||||||
|
;;;;; CONTROLLER READING
|
||||||
|
|
||||||
|
ReadJoypad0 subroutine
|
||||||
|
ldy #0
|
||||||
|
ReadJoypadY
|
||||||
|
lda #$01
|
||||||
|
sta JOYPAD1,y ; set strobe bit
|
||||||
|
lsr ; now A is 0
|
||||||
|
sta JOYPAD1,y ; clear strobe bit
|
||||||
|
ldx #8 ; read 8 bits
|
||||||
|
.loop:
|
||||||
|
pha ; save A (result)
|
||||||
|
lda JOYPAD1,y ; load controller state
|
||||||
|
lsr ; bit 0 -> carry
|
||||||
|
pla ; restore A (result)
|
||||||
|
rol ; carry -> bit 0 of result
|
||||||
|
dex ; X = X - 1
|
||||||
|
bne .loop ; repeat if X is 0
|
||||||
|
rts ; controller bits returned in A
|
||||||
|
|
265
password.asm
Normal file
265
password.asm
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
PASSWORD_LENGTH = 24 ; length for comparing to Y
|
||||||
|
SPACE_VALUE = 64
|
||||||
|
SPACE_LOCATION = 64
|
||||||
|
SPACE_BECOME_VALUE = SPACE_LOCATION - 1
|
||||||
|
PASSWORD_COUNT = 5
|
||||||
|
|
||||||
|
include "nesdefs.dasm"
|
||||||
|
|
||||||
|
;;;;; VARIABLES
|
||||||
|
|
||||||
|
seg.u ZEROPAGE
|
||||||
|
org $0
|
||||||
|
|
||||||
|
;; global
|
||||||
|
|
||||||
|
Seed ds 2
|
||||||
|
PasswordInUse ds 1
|
||||||
|
|
||||||
|
;; controller
|
||||||
|
|
||||||
|
CurrentController ds 1
|
||||||
|
BButtonDown ds 1
|
||||||
|
AButtonDown ds 1
|
||||||
|
|
||||||
|
;; decoding
|
||||||
|
|
||||||
|
CurrentLetter ds 1
|
||||||
|
CurrentPasswordChunk ds 1
|
||||||
|
RandomValueForPasswordLetterModification ds 1
|
||||||
|
DecodedPasswordOffset ds 1
|
||||||
|
CurrentLetterPositionProcess ds 1
|
||||||
|
CurrentLetterPositionDisplay ds 1
|
||||||
|
|
||||||
|
;; rendering
|
||||||
|
|
||||||
|
BambooRenderPos ds 1
|
||||||
|
StringToWrite ds 2
|
||||||
|
|
||||||
|
seg.u PASSWORDS
|
||||||
|
org $400
|
||||||
|
|
||||||
|
;; password storage
|
||||||
|
|
||||||
|
DecodedPassword ds 24
|
||||||
|
AlternatePassword ds 24
|
||||||
|
|
||||||
|
|
||||||
|
;;;;; NES CARTRIDGE HEADER
|
||||||
|
|
||||||
|
NES_HEADER 0,2,1,NES_MIRR_HORIZ ; mapper 0, 2 PRGs, 1 CHR
|
||||||
|
|
||||||
|
;;;;; START OF CODE
|
||||||
|
|
||||||
|
Start:
|
||||||
|
; wait for PPU warmup; clear CPU RAM
|
||||||
|
NES_INIT ; set up stack pointer, turn off PPU
|
||||||
|
jsr WaitSync ; wait for VSYNC
|
||||||
|
jsr ClearRAM ; clear RAM
|
||||||
|
jsr WaitSync ; wait for VSYNC (and PPU warmup)
|
||||||
|
; set palette and nametable VRAM
|
||||||
|
jsr SetPalette ; set palette colors
|
||||||
|
lda #0
|
||||||
|
sta PasswordInUse
|
||||||
|
|
||||||
|
; reset PPU address and scroll registers
|
||||||
|
lda #0
|
||||||
|
sta PPU_ADDR
|
||||||
|
sta PPU_ADDR ; PPU addr = $0000
|
||||||
|
sta PPU_SCROLL
|
||||||
|
sta PPU_SCROLL ; PPU scroll = $0000
|
||||||
|
|
||||||
|
; seed rng
|
||||||
|
lda #25
|
||||||
|
sta Seed
|
||||||
|
lda #43
|
||||||
|
sta Seed+1
|
||||||
|
|
||||||
|
; disable NMI and scroll
|
||||||
|
lda #0 ; disable NMI
|
||||||
|
sta PPU_CTRL
|
||||||
|
|
||||||
|
lda #$0
|
||||||
|
sta PPU_SCROLL
|
||||||
|
sta PPU_SCROLL ; PPU scroll = $0000
|
||||||
|
|
||||||
|
; set up controller
|
||||||
|
lda #0
|
||||||
|
sta AButtonDown
|
||||||
|
sta BButtonDown
|
||||||
|
|
||||||
|
jsr DecodePassword
|
||||||
|
jsr ConvertDecodedPasswordToAlternatePassword
|
||||||
|
|
||||||
|
jsr WriteUI
|
||||||
|
|
||||||
|
.endless
|
||||||
|
jsr ReadJoypad0
|
||||||
|
sta CurrentController
|
||||||
|
|
||||||
|
jsr HandleBButton
|
||||||
|
jsr HandleAButton
|
||||||
|
|
||||||
|
inc Seed
|
||||||
|
jmp .endless ; endless loop
|
||||||
|
|
||||||
|
|
||||||
|
;;;;; COMMON SUBROUTINES
|
||||||
|
|
||||||
|
include "nesppu.dasm"
|
||||||
|
include "processing.asm"
|
||||||
|
include "view.asm"
|
||||||
|
include "galois16.asm"
|
||||||
|
include "data.asm"
|
||||||
|
|
||||||
|
WriteString: subroutine
|
||||||
|
ldy #0
|
||||||
|
.Continue:
|
||||||
|
lda (StringToWrite),y
|
||||||
|
beq .Done
|
||||||
|
sta PPU_DATA
|
||||||
|
iny
|
||||||
|
bne .Continue
|
||||||
|
.Done
|
||||||
|
rts
|
||||||
|
|
||||||
|
MAC WRITE_STRING
|
||||||
|
lda #<{1}
|
||||||
|
sta StringToWrite
|
||||||
|
lda #>{1}
|
||||||
|
sta StringToWrite+1
|
||||||
|
jsr WriteString
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
WriteUI: subroutine
|
||||||
|
lda #0
|
||||||
|
sta PPU_MASK ; turn rendering off
|
||||||
|
|
||||||
|
PPU_SETADDR $2069
|
||||||
|
jsr WritePassword
|
||||||
|
|
||||||
|
PPU_SETADDR $20c1
|
||||||
|
WRITE_STRING CanAlsoMessage
|
||||||
|
|
||||||
|
PPU_SETADDR $2109
|
||||||
|
jsr WriteAlternateDecodedPassword
|
||||||
|
|
||||||
|
PPU_SETADDR $21a6
|
||||||
|
WRITE_STRING AButtonMessage
|
||||||
|
|
||||||
|
PPU_SETADDR $21c3
|
||||||
|
WRITE_STRING BButtonMessage
|
||||||
|
|
||||||
|
PPU_SETADDR $2242
|
||||||
|
jsr DrawBamboo
|
||||||
|
|
||||||
|
PPU_SETADDR $224a
|
||||||
|
WRITE_STRING R1KRTitleOne
|
||||||
|
|
||||||
|
PPU_SETADDR $226d
|
||||||
|
WRITE_STRING R1KRTitleTwo
|
||||||
|
|
||||||
|
PPU_SETADDR $22a9
|
||||||
|
WRITE_STRING R1KRBlogTitle
|
||||||
|
|
||||||
|
PPU_SETADDR $22e9
|
||||||
|
WRITE_STRING R1KRBlogLinkOne
|
||||||
|
|
||||||
|
PPU_SETADDR $230b
|
||||||
|
WRITE_STRING R1KRBlogLinkTwo
|
||||||
|
|
||||||
|
;;;;; palette stuff
|
||||||
|
|
||||||
|
PPU_SETADDR $23e8
|
||||||
|
|
||||||
|
lda #%01010101
|
||||||
|
sta PPU_DATA
|
||||||
|
sta PPU_DATA
|
||||||
|
|
||||||
|
PPU_SETADDR $23f0
|
||||||
|
|
||||||
|
lda #%10101010
|
||||||
|
sta PPU_DATA
|
||||||
|
sta PPU_DATA
|
||||||
|
|
||||||
|
lda #MASK_BG
|
||||||
|
sta PPU_MASK ; enable rendering
|
||||||
|
lda #$0
|
||||||
|
sta PPU_ADDR
|
||||||
|
sta PPU_ADDR ; PPU addr = $0000
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
HandleBButton: subroutine
|
||||||
|
lda #%01000000 ; lowest bit is b
|
||||||
|
bit CurrentController
|
||||||
|
beq .BButtonUp ; button is up
|
||||||
|
.BButtonDown
|
||||||
|
lda #0
|
||||||
|
cmp BButtonDown
|
||||||
|
bne .BButtonWasDown
|
||||||
|
|
||||||
|
jsr ConvertDecodedPasswordToAlternatePassword
|
||||||
|
jsr WriteUI
|
||||||
|
|
||||||
|
.BButtonWasDown
|
||||||
|
lda #1
|
||||||
|
sta BButtonDown
|
||||||
|
bne .BButtonDone
|
||||||
|
.BButtonUp
|
||||||
|
lda #0
|
||||||
|
sta BButtonDown
|
||||||
|
.BButtonDone
|
||||||
|
rts
|
||||||
|
|
||||||
|
HandleAButton: subroutine
|
||||||
|
lda #%10000000 ; lowest bit is b
|
||||||
|
bit CurrentController
|
||||||
|
beq .AButtonUp ; button is up
|
||||||
|
.AButtonDown
|
||||||
|
lda #0
|
||||||
|
cmp AButtonDown
|
||||||
|
bne .AButtonWasDown
|
||||||
|
|
||||||
|
inc PasswordInUse
|
||||||
|
lda #PASSWORD_COUNT
|
||||||
|
cmp PasswordInUse
|
||||||
|
bne .NotEqual
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta PasswordInUse
|
||||||
|
.NotEqual
|
||||||
|
|
||||||
|
jsr DecodePassword
|
||||||
|
jsr ConvertDecodedPasswordToAlternatePassword
|
||||||
|
jsr WriteUI
|
||||||
|
|
||||||
|
.AButtonWasDown
|
||||||
|
lda #1
|
||||||
|
sta AButtonDown
|
||||||
|
bne .AButtonDone
|
||||||
|
.AButtonUp
|
||||||
|
lda #0
|
||||||
|
sta AButtonDown
|
||||||
|
.AButtonDone
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
;;;;; INTERRUPT HANDLERS
|
||||||
|
|
||||||
|
|
||||||
|
NMIHandler: subroutine
|
||||||
|
SAVE_REGS
|
||||||
|
|
||||||
|
RESTORE_REGS
|
||||||
|
rti
|
||||||
|
|
||||||
|
;;;;; CPU VECTORS
|
||||||
|
|
||||||
|
NES_VECTORS
|
||||||
|
|
||||||
|
org $10000
|
||||||
|
|
||||||
|
|
||||||
|
incbin "calderon_with_bamboo.chr"
|
||||||
|
incbin "calderon_with_bamboo.chr"
|
BIN
password.nes
Normal file
BIN
password.nes
Normal file
Binary file not shown.
118
processing.asm
Normal file
118
processing.asm
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
GetCurrentLetterPosition: subroutine
|
||||||
|
lda #0
|
||||||
|
ldx #0
|
||||||
|
SelectPassword:
|
||||||
|
cpx PasswordInUse
|
||||||
|
beq SelectPasswordDone
|
||||||
|
adc #24
|
||||||
|
inx
|
||||||
|
bne SelectPassword
|
||||||
|
SelectPasswordDone:
|
||||||
|
rts
|
||||||
|
|
||||||
|
DecodePassword: subroutine
|
||||||
|
lda #0 ; set up decoding variables
|
||||||
|
sta DecodedPasswordOffset
|
||||||
|
jsr GetCurrentLetterPosition
|
||||||
|
sta CurrentLetterPositionProcess
|
||||||
|
ldx #0
|
||||||
|
.ReadLetterLoop
|
||||||
|
ldy CurrentLetterPositionProcess ; load the next letter of the password
|
||||||
|
lda Passwords,y
|
||||||
|
sta CurrentLetter ; ...and stick it in a spot in RAM
|
||||||
|
ldx #0 ;
|
||||||
|
ldy DecodedPasswordOffset
|
||||||
|
.FindMatchLoop
|
||||||
|
lda Letters,x ; put the next search letter into accumulator
|
||||||
|
jsr PushLetterToDecodedPassword ; always push the letter offset onto the decode list
|
||||||
|
cmp CurrentLetter ; if it's the same, we're done
|
||||||
|
beq .FindMatchExit
|
||||||
|
inx
|
||||||
|
;cpx #SPACE_LOCATION
|
||||||
|
bne .FindMatchLoop
|
||||||
|
|
||||||
|
lda Letters,x ; this is a space
|
||||||
|
ldx #SPACE_VALUE
|
||||||
|
jsr PushLetterToDecodedPassword
|
||||||
|
.FindMatchExit
|
||||||
|
inc DecodedPasswordOffset
|
||||||
|
iny
|
||||||
|
inc CurrentLetterPositionProcess
|
||||||
|
cpy #PASSWORD_LENGTH
|
||||||
|
bne .ReadLetterLoop
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
ConvertDecodedPasswordToAlternatePassword: subroutine
|
||||||
|
ldx #0
|
||||||
|
.NextCharacter
|
||||||
|
lda DecodedPassword,x
|
||||||
|
sta AlternatePassword,x
|
||||||
|
cpx #0 ; we can't do anything at position 0
|
||||||
|
beq .NotSpaceValue
|
||||||
|
cmp #SPACE_VALUE ; not a candidate for modifying the prior value
|
||||||
|
beq .SpaceValue
|
||||||
|
cmp #SPACE_BECOME_VALUE ; not a candidate for modifying the prior value
|
||||||
|
beq .CanBecomeSpaceValue
|
||||||
|
bne .NotSpaceValue
|
||||||
|
.SpaceValue
|
||||||
|
lda #SPACE_BECOME_VALUE
|
||||||
|
sta AlternatePassword,x
|
||||||
|
jsr galois16
|
||||||
|
tay
|
||||||
|
and #%00000100
|
||||||
|
bne .UseASpace
|
||||||
|
dex
|
||||||
|
lda DecodedPassword,x
|
||||||
|
ora #%00000011
|
||||||
|
sta AlternatePassword,x
|
||||||
|
inx
|
||||||
|
bcs .NotSpaceValue
|
||||||
|
.CanBecomeSpaceValue
|
||||||
|
; check to make sure both low bits are set on prior
|
||||||
|
dex
|
||||||
|
lda AlternatePassword,x
|
||||||
|
and #%00000011
|
||||||
|
bne .DoneBecomingSpace
|
||||||
|
inx
|
||||||
|
jsr galois16
|
||||||
|
tay
|
||||||
|
and #%00000100
|
||||||
|
bne .NotSpaceValue
|
||||||
|
lda #SPACE_VALUE
|
||||||
|
sta AlternatePassword,x
|
||||||
|
dex
|
||||||
|
lda AlternatePassword,x
|
||||||
|
cmp #SPACE_VALUE
|
||||||
|
.DoneBecomingSpace
|
||||||
|
inx
|
||||||
|
lda #0
|
||||||
|
beq .NotSpaceValue
|
||||||
|
.UseASpace
|
||||||
|
tya
|
||||||
|
and #%00000011
|
||||||
|
sta RandomValueForPasswordLetterModification ; y contains the lower bits to use instead
|
||||||
|
lda #SPACE_LOCATION
|
||||||
|
sta AlternatePassword,x
|
||||||
|
dex
|
||||||
|
lda DecodedPassword,x
|
||||||
|
and #%11111100
|
||||||
|
ora RandomValueForPasswordLetterModification
|
||||||
|
sta AlternatePassword,x
|
||||||
|
inx
|
||||||
|
.NotSpaceValue
|
||||||
|
inx
|
||||||
|
cpx #PASSWORD_LENGTH
|
||||||
|
bne .NextCharacter
|
||||||
|
.done
|
||||||
|
rts
|
||||||
|
|
||||||
|
PushLetterToDecodedPassword: subroutine
|
||||||
|
; X contains the letters.indexOf(letter)
|
||||||
|
; Y contains the current letter index
|
||||||
|
; A will get preserved
|
||||||
|
pha
|
||||||
|
txa
|
||||||
|
sta DecodedPassword,y
|
||||||
|
pla
|
||||||
|
rts
|
115
view.asm
Normal file
115
view.asm
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
MAC MOVE_TO_NEXT_CHUNK
|
||||||
|
lda #1
|
||||||
|
bit CurrentPasswordChunk
|
||||||
|
bne .NextLine
|
||||||
|
lda #0
|
||||||
|
sta PPU_DATA
|
||||||
|
beq .NextChunk
|
||||||
|
.NextLine:
|
||||||
|
txa
|
||||||
|
pha
|
||||||
|
lda #0
|
||||||
|
ldx #19
|
||||||
|
.NextLineLoop:
|
||||||
|
sta PPU_DATA
|
||||||
|
dex
|
||||||
|
cpx #0
|
||||||
|
bne .NextLineLoop
|
||||||
|
pla
|
||||||
|
tax
|
||||||
|
.NextChunk:
|
||||||
|
inc CurrentPasswordChunk
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
WritePassword: subroutine
|
||||||
|
lda #0
|
||||||
|
sta CurrentPasswordChunk
|
||||||
|
jsr GetCurrentLetterPosition
|
||||||
|
tax
|
||||||
|
ldy #0
|
||||||
|
.WriteLetterInChunk:
|
||||||
|
tya
|
||||||
|
pha
|
||||||
|
lda Passwords,x
|
||||||
|
sta PPU_DATA
|
||||||
|
pla
|
||||||
|
tay
|
||||||
|
cpy #5
|
||||||
|
beq .ChunkDone
|
||||||
|
inx
|
||||||
|
iny
|
||||||
|
bne .WriteLetterInChunk
|
||||||
|
.ChunkDone:
|
||||||
|
MOVE_TO_NEXT_CHUNK
|
||||||
|
lda #4
|
||||||
|
ldy #0
|
||||||
|
inx
|
||||||
|
cmp CurrentPasswordChunk
|
||||||
|
bne .WriteLetterInChunk
|
||||||
|
rts
|
||||||
|
|
||||||
|
WriteAlternateDecodedPassword: subroutine
|
||||||
|
lda #0
|
||||||
|
sta CurrentPasswordChunk
|
||||||
|
ldx #0
|
||||||
|
ldy #0
|
||||||
|
.WriteLetterInChunk
|
||||||
|
tya
|
||||||
|
pha
|
||||||
|
lda AlternatePassword,x
|
||||||
|
tay
|
||||||
|
lda Letters,y
|
||||||
|
sta PPU_DATA
|
||||||
|
pla
|
||||||
|
tay
|
||||||
|
cpy #5
|
||||||
|
beq .ChunkDone
|
||||||
|
inx
|
||||||
|
iny
|
||||||
|
bne .WriteLetterInChunk
|
||||||
|
.ChunkDone
|
||||||
|
MOVE_TO_NEXT_CHUNK
|
||||||
|
lda #4
|
||||||
|
ldy #0
|
||||||
|
inx
|
||||||
|
cmp CurrentPasswordChunk
|
||||||
|
bne .WriteLetterInChunk
|
||||||
|
rts
|
||||||
|
|
||||||
|
DrawBamboo: subroutine
|
||||||
|
lda #$80
|
||||||
|
sta BambooRenderPos
|
||||||
|
.WriteColumn:
|
||||||
|
lda BambooRenderPos
|
||||||
|
sta PPU_DATA
|
||||||
|
inc BambooRenderPos
|
||||||
|
lda #%00000111
|
||||||
|
and BambooRenderPos
|
||||||
|
bne .WriteColumn
|
||||||
|
.MaybeNextRow
|
||||||
|
lda #%11111110
|
||||||
|
and BambooRenderPos
|
||||||
|
beq .Done
|
||||||
|
ldy #8
|
||||||
|
lda #0
|
||||||
|
.ToNextRow
|
||||||
|
sta PPU_DATA
|
||||||
|
dey
|
||||||
|
cpy #0
|
||||||
|
bne .ToNextRow
|
||||||
|
bcs .WriteColumn
|
||||||
|
.Done
|
||||||
|
rts
|
||||||
|
|
||||||
|
; set palette colors
|
||||||
|
SetPalette: subroutine
|
||||||
|
; set PPU address to palette start
|
||||||
|
PPU_SETADDR $3f00
|
||||||
|
ldy #0
|
||||||
|
.loop:
|
||||||
|
lda Palette,y ; lookup byte in ROM
|
||||||
|
sta PPU_DATA ; store byte to PPU data
|
||||||
|
iny ; Y = Y + 1
|
||||||
|
cpy #32 ; is Y equal to 32?
|
||||||
|
bne .loop ; not yet, loop
|
||||||
|
rts ; return to caller
|
Loading…
Reference in New Issue
Block a user