Here are my notes on tile properties (some bits with corresponding ZoneDoctor names):
Code:
$7E7600-$7E76FF tile properties byte 1
special values: $F7 = always impassable, $07 = counter tile, can be talked over
lrdbtslu
l: Tile uses up/left movement (stairs)
r: Tile uses up/right movement (stairs)
d: Door Tile
b: Bottom sprite shown above priority 1 bg (not active for bridge tiles, ZoneDoctor: "0.4")
t: Top sprite shown above priority 1 bg (not active for bridge tiles, ZoneDoctor: "0.3")
s: Bridge tile (ZoneDoctor: "solid tile, cannot be walked on")
l: Passable on lower z-level (ZoneDoctor: "Solid to tier 2")
u: Passable on upper z-level (ZoneDoctor: "Solid to tier 1")
note: if l & u are both set, this tile can be a transition between upper and lower z-level
$7E7700-$7E77FF tile properties byte 2
nu--btrl
n: NPC can randomly move here (ZoneDoctor: "Passable quadrants")
u: Always Face Up (ladder)
-: (ZoneDoctor: "1.5")
-: (ZoneDoctor: "1.4")
b: Passable through bottom
t: Passable through top
r: Passable through right
l: Passable through left
Here are a bunch of subroutines that deal with user-controlled movement:
C0/46F4: Check adjacent NPC's
C0/485F: Do user-controlled movement
C0/4A3F: Update HP each step
C0/4B60: Increment steps
C0/4B83: Check treasures
C0/4D51: Open door (returns 0 if no door)
C0/4E16: User takes a step (A = movement direction, returns 0 if movement is not allowed)
C0/4F14: Update party sprite priority (current tile)
C0/4F2D: Update party sprite priority (destination tile)
C0/4F9F: Update party layer priority (current tile)
C0/4FE6: Update party layer priority (destination tile)
C0/5044: Update adjacent tile properties
I think most of what you're looking for is in C0/4E16. Here's my commented disassembly:
Code:
; [ Party Takes a Step ]
; A = facing direction (in)
; A = 1 if movement allowed, 0 if not (out)
C0/4E16: 85 B3 STA $B3 ; set movement direction
C0/4E18: AA TAX
C0/4E19: BF 8D 4F C0 LDA $C04F8D,X ; get pointer to tile number
C0/4E1D: AA TAX
C0/4E1E: B5 A3 LDA $A3,X ; bg1 tile
C0/4E20: AA TAX
C0/4E21: AD B8 1E LDA $1EB8 ; branch if sprint shoes effect is disabled
C0/4E24: 29 02 AND #$02
C0/4E26: D0 0B BNE $4E33
C0/4E28: AD DF 11 LDA $11DF ; branch if not wearing sprint shoes
C0/4E2B: 29 20 AND #$20
C0/4E2D: F0 04 BEQ $4E33
C0/4E2F: A9 03 LDA #$03 ; object speed = 3 (sprint shoes)
C0/4E31: 80 02 BRA $4E35
C0/4E33: A9 02 LDA #$02 ; object speed = 2 (normal)
C0/4E35: 99 75 08 STA $0875,Y
C0/4E38: A9 7E LDA #$7E
C0/4E3A: 48 PHA
C0/4E3B: AB PLB
C0/4E3C: DA PHX
C0/4E3D: A5 B3 LDA $B3 ; movement direction
C0/4E3F: 3A DEC
C0/4E40: AA TAX
C0/4E41: BF 10 4F C0 LDA $C04F10,X ; get direction bit mask
C0/4E45: 85 1A STA $1A
C0/4E47: FA PLX
C0/4E48: A5 B9 LDA $B9 ; directional passability of current tile
C0/4E4A: 29 0F AND #$0F
C0/4E4C: 25 1A AND $1A
C0/4E4E: F0 48 BEQ $4E98 ; return if direction not allowed
C0/4E50: BD 00 76 LDA $7600,X ; destination tile properties
C0/4E53: 29 07 AND #$07
C0/4E55: C9 07 CMP #$07
C0/4E57: F0 3F BEQ $4E98 ; return if destination is a counter tile
C0/4E59: A5 B8 LDA $B8 ; branch if current tile is not a bridge tile
C0/4E5B: 29 04 AND #$04
C0/4E5D: F0 18 BEQ $4E77
; bridge tile
C0/4E5F: A5 B2 LDA $B2
C0/4E61: 29 01 AND #$01
C0/4E63: F0 09 BEQ $4E6E ; branch if party is on lower z-level
; bridge tile, party on upper z-level
C0/4E65: BD 00 76 LDA $7600,X ; movement allowed unless destination tile is lower z-level
C0/4E68: 29 02 AND #$02
C0/4E6A: D0 2C BNE $4E98
C0/4E6C: 80 2F BRA $4E9D
; bridge tile, party on lower z-level
C0/4E6E: BD 00 76 LDA $7600,X ; movement allowed unless destination tile is upper z-level
C0/4E71: 29 01 AND #$01
C0/4E73: D0 23 BNE $4E98
C0/4E75: 80 26 BRA $4E9D
; current tile is not a bridge tile
C0/4E77: BD 00 76 LDA $7600,X ; destination tile z-level
C0/4E7A: 29 03 AND #$03
C0/4E7C: C9 03 CMP #$03
C0/4E7E: F0 1D BEQ $4E9D ; movement always allowed if destination tile is upper & lower z-level
C0/4E80: A5 B8 LDA $B8
C0/4E82: 29 03 AND #$03
C0/4E84: C9 03 CMP #$03
C0/4E86: F0 09 BEQ $4E91 ; branch if party is on upper & lower z-level
C0/4E88: 49 03 EOR #$03
C0/4E8A: 3D 00 76 AND $7600,X ; movement allowed if party and destination z-level match
C0/4E8D: D0 09 BNE $4E98
C0/4E8F: 80 0C BRA $4E9D
C0/4E91: BD 00 76 LDA $7600,X ; party on upper & lower, movement allowed unless destination is a bridge tile
C0/4E94: 29 04 AND #$04
C0/4E96: F0 05 BEQ $4E9D
C0/4E98: 7B TDC
C0/4E99: 48 PHA
C0/4E9A: AB PLB
C0/4E9B: 7B TDC ; A = 0 (no movement)
C0/4E9C: 60 RTS
; movement allowed
C0/4E9D: DA PHX
C0/4E9E: A5 B3 LDA $B3
C0/4EA0: 20 03 7D JSR $7D03 ; get pointer to object map data in facing direction
C0/4EA3: FA PLX
C0/4EA4: A4 1E LDY $1E
C0/4EA6: B9 00 20 LDA $2000,Y ; object map data at destination
C0/4EA9: 30 19 BMI $4EC4 ; branch if there's no object there
C0/4EAB: BD 00 76 LDA $7600,X
C0/4EAE: 29 04 AND #$04
C0/4EB0: F0 E6 BEQ $4E98 ; movement not allowed unless destination tile is a bridge tile
C0/4EB2: A5 B8 LDA $B8
C0/4EB4: 29 07 AND #$07
C0/4EB6: C9 01 CMP #$01
C0/4EB8: F0 DE BEQ $4E98 ; movement not allowed if current tile is upper z-level
C0/4EBA: C9 02 CMP #$02
C0/4EBC: F0 06 BEQ $4EC4 ; movement allowed if current tile is lower z-level
C0/4EBE: A5 B2 LDA $B2
C0/4EC0: C9 02 CMP #$02
C0/4EC2: D0 D4 BNE $4E98 ; movement not allowed if party is not on lower z-level
C0/4EC4: BD 00 76 LDA $7600,X ; branch if destination tile is not a bridge tile
C0/4EC7: 29 04 AND #$04
C0/4EC9: F0 06 BEQ $4ED1
C0/4ECB: A5 B2 LDA $B2 ; branch if party is on lower z-level (object map data doesn't get set if party is on bottom of a bridge tile)
C0/4ECD: C9 02 CMP #$02
C0/4ECF: F0 1E BEQ $4EEF
C0/4ED1: 7B TDC
C0/4ED2: 48 PHA
C0/4ED3: AB PLB
C0/4ED4: AE 03 08 LDX $0803 ; get party object number
C0/4ED7: 8E 04 42 STX $4204
C0/4EDA: A9 29 LDA #$29
C0/4EDC: 8D 06 42 STA $4206
C0/4EDF: EA NOP
C0/4EE0: EA NOP
C0/4EE1: EA NOP
C0/4EE2: EA NOP
C0/4EE3: A9 7E LDA #$7E
C0/4EE5: 48 PHA
C0/4EE6: AB PLB
C0/4EE7: AF 14 42 00 LDA $004214
C0/4EEB: 0A ASL
C0/4EEC: 99 00 20 STA $2000,Y ; set object map data
C0/4EEF: A5 B8 LDA $B8 ; current tile z-level
C0/4EF1: 29 07 AND #$07
C0/4EF3: C9 03 CMP #$03
C0/4EF5: B0 06 BCS $4EFD ; branch if a bridge tile (party retains previous z-level)
C0/4EF7: A5 B8 LDA $B8
C0/4EF9: 29 03 AND #$03 ; set new party z-level
C0/4EFB: 85 B2 STA $B2
C0/4EFD: 20 2D 4F JSR $4F2D ; update party sprite priority (based on destination tile)
C0/4F00: 20 E6 4F JSR $4FE6 ; update party layer priority (based on destination tile)
C0/4F03: 7B TDC
C0/4F04: 48 PHA
C0/4F05: AB PLB
C0/4F06: A4 DA LDY $DA ; pointer to object data
C0/4F08: A5 B3 LDA $B3 ; set movement direction
C0/4F0A: 99 7E 08 STA $087E,Y
C0/4F0D: A9 01 LDA #$01 ; A = 1 (movement allowed)
C0/4F0F: 60 RTS
C0/4F10: .DB $08, $01, $04, $02
Hopefully this will help. The z-level/bridge stuff is really confusing but it essentially allows each tile to have different passability depending on whether you are upstairs or downstairs. Let me know if I can clarify anything.