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