Pass 2 _wip: Slalom (U), Kung Fu (U), Othello (U) label replacement complete
Pass 3 _wip: Slalom (U), Kung Fu (U), Othello (U) semantic naming complete Pass 3 _wip: apply symbols (0 residue) for Slalom (U), Kung Fu (U), Othello (U) Pass 2/3 _wip: 10 NROM projects (Elevator Action, 1942, Tag Team Wrestling, Galaga, Kung Fu a1, Stack-Up, Magmax, Ms Pac-Man Namco, Soccer, Sqoon) Promote 13 _wip/NROM projects to NROM/ (Slalom, Kung Fu, Othello, Elevator Action, 1942, Tag Team Wrestling, Galaga, Kung Fu a1, Stack-Up, Magmax, Ms Pac-Man Namco, Soccer, Sqoon) Pass 2/3 _wip: 5 CNROM games (Tiger-Heli, Paperboy, Last Starfighter, Mighty Bomb Jack, Kung-Fu Heroes) Docs: document CDL capture + re-trace workflow in TODO.md Adds more code for - Elevator Action (U) - Kung Fu (U) - Othello (U) - Slalom (U) - Sqoon (U)
This commit is contained in:
1 parent
f8d62601e5
commit
0a49ee6da7
228 files changed
+101961
-37231
No files matched your search
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
CA65 ?= ca65
|
||||
LD65 ?= ld65
|
||||
|
||||
all: reconstructed.nes verify
|
||||
|
||||
prg.o: prg.s symbols.inc locals.inc prg.bin
|
||||
$(CA65) -g -o $@ $<
|
||||
|
||||
header.o: header.s header.bin
|
||||
$(CA65) -g -o $@ $<
|
||||
|
||||
chr.o: chr.s chr.bin
|
||||
$(CA65) -g -o $@ $<
|
||||
|
||||
reconstructed.nes: header.o prg.o chr.o linker.cfg
|
||||
$(LD65) -C linker.cfg -m reconstructed.map -Ln reconstructed.lbl -o $@ header.o prg.o chr.o
|
||||
|
||||
verify: reconstructed.nes rom.nes
|
||||
cmp reconstructed.nes rom.nes
|
||||
@echo "Byte-identical ROM verified."
|
||||
|
||||
clean:
|
||||
rm -f *.o reconstructed.nes reconstructed_prg.bin reconstructed.map reconstructed.lbl
|
||||
|
||||
.PHONY: all verify clean
|
||||
@@ -0,0 +1,67 @@
|
||||
# Galaga (U)
|
||||
|
||||
## Status
|
||||
|
||||
**Pass 3.** All address-derived `Label_XXXX` definitions replaced;
|
||||
every `jsr`/`jmp` operand symbolic; hardware-register operands resolved
|
||||
via `apply_symbols.py` (0 residue); audit comments aligned; `make`
|
||||
stays byte-identical.
|
||||
|
||||
`make` assembles `header.s`, `prg.s`, `chr.s`, links them with `ld65` and compares the
|
||||
result against `rom.nes`:
|
||||
|
||||
```
|
||||
Byte-identical ROM verified.
|
||||
```
|
||||
|
||||
## ROM
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Format | iNES |
|
||||
| Mapper | 0 |
|
||||
| Board | NROM-256 |
|
||||
| Mirroring | Horizontal |
|
||||
| Four-screen VRAM | no |
|
||||
| Battery | no |
|
||||
| PRG | 32 KB (2 x 16 KB), mapped at CPU $8000-$FFFF |
|
||||
| CHR | 8 KB (1 x 8 KB) |
|
||||
| Trainer | none |
|
||||
| Footer | none |
|
||||
| NMI vector | $C0C8 |
|
||||
| RESET vector | $C000 |
|
||||
| IRQ vector | $C000 |
|
||||
| ROM file | `Galaga (U).nes` |
|
||||
| SHA-256 | `38f999bb2fa88893446d25a1885b0af1569f1260652d1c49332276c651315541` |
|
||||
|
||||
### Header notes
|
||||
|
||||
- none
|
||||
|
||||
## Open work
|
||||
|
||||
- **Pass 1** - run `nesdis.py` over `prg.bin` to produce the code/data
|
||||
split. The tracer reads the vectors from the last six bytes of the PRG
|
||||
image, so the split seeds correctly.
|
||||
- **Pass 1** must emit the canonical audit comment
|
||||
`; CPU:$C123 PRG:0123 AD 21 03` at column 35 for every instruction.
|
||||
- **Pass 2** - replace the address-derived `Label_XXXX` names and the raw
|
||||
`$XXXX` call operands.
|
||||
- **Pass 3** - semantic zero-page aliases (applied only at the sites where
|
||||
their role is proven) and named data tables.
|
||||
- **Promotion** to `NROM/<name>/` once Pass 3 is done, as `git mv`.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `prg.s` | Pass 0 PRG include (replaced by the Pass 1 disassembly) |
|
||||
| `header.s` | iNES header include |
|
||||
| `chr.s` | CHR include |
|
||||
| `prg.bin` | 32768 bytes (32 KB) PRG image |
|
||||
| `chr.bin` | 8192 bytes (8 KB) CHR image |
|
||||
| `rom.nes` | byte-identical copy of the original ROM |
|
||||
| `linker.cfg` | HEADER / PRG / CHR memory areas |
|
||||
| `symbols.inc` | NES hardware register names |
|
||||
| `locals.inc` | zero-page aliases (empty at Pass 0) |
|
||||
| `Makefile` | build and byte-identity check |
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
.segment "CHR"
|
||||
.incbin "chr.bin"
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
.segment "HEADER"
|
||||
.incbin "header.bin"
|
||||
@@ -0,0 +1,148 @@
|
||||
C000 Reset
|
||||
C0C8 NmiHandler
|
||||
|
||||
# ---- derived internal branch-target names ----
|
||||
C000 Reset
|
||||
C00A Reset_OnNonnegative
|
||||
C01C Reset_Loop
|
||||
C01E Reset_Loop2
|
||||
C026 Reset_OnNonzero
|
||||
C044 Reset_Loop3
|
||||
C075 Sub_C075
|
||||
C079 Reset_OnNonzero2
|
||||
C089 Reset_Loop4
|
||||
C0AB Reset_Loop5
|
||||
C0B3 Reset_Loop6
|
||||
C0BD Reset_Loop7
|
||||
C0C2 Sub_C0C2
|
||||
C0C8 NmiHandler
|
||||
C0EB NmiHandler_Loop
|
||||
C0F5 Sub_C0F5
|
||||
C103 Sub_C103
|
||||
C117 Sub_C117
|
||||
C11A Sub_C11A
|
||||
C12D Sub_C12D
|
||||
C149 NmiHandler_OnNonzero
|
||||
C18C Sub_C18C
|
||||
C190 NmiHandler_OnZero
|
||||
C191 Sub_C191
|
||||
C1A7 NmiHandler_Loop2
|
||||
C1BF Sub_C1BF
|
||||
C1C4 Sub_C1C4
|
||||
C1EA NmiHandler_Loop3
|
||||
C1F4 NmiHandler_OnNonzero2
|
||||
C214 NmiHandler_OnNonzero3
|
||||
C232 NmiHandler_Loop4
|
||||
C23B Sub_C23B
|
||||
C242 Sub_C242
|
||||
C258 NmiHandler_OnNonzero4
|
||||
C275 Sub_C275
|
||||
C2BC Sub_C2BC
|
||||
C2D2 Sub_C2D2
|
||||
C2DC NmiHandler_OnNonnegative
|
||||
C2E0 NmiHandler_OnCarryClear
|
||||
C2EC NmiHandler_Loop5
|
||||
C301 Sub_C301
|
||||
C317 Sub_C317
|
||||
C32C NmiHandler_Loop6
|
||||
C32E NmiHandler_Loop7
|
||||
C330 NmiHandler_Loop8
|
||||
C4A0 Sub_C4A0
|
||||
C4EF Sub_C4EF
|
||||
C4F1 NmiHandler_OnNonzero5
|
||||
C500 Sub_C500
|
||||
C550 NmiHandler_Loop9
|
||||
C55F NmiHandler_Loop10
|
||||
C567 NmiHandler_Loop11
|
||||
C584 NmiHandler_OnNonzero6
|
||||
C5A1 NmiHandler_Loop12
|
||||
C5C3 NmiHandler_Loop13
|
||||
C5CA NmiHandler_OnNonzero7
|
||||
C5D3 NmiHandler_Loop14
|
||||
C5D4 Sub_C5D4
|
||||
C5E5 NmiHandler_OnNonzero8
|
||||
C5F4 NmiHandler_Loop15
|
||||
C5F8 NmiHandler_OnNonzero9
|
||||
C607 Sub_C607
|
||||
C612 NmiHandler_OnNegative
|
||||
C613 NmiHandler_Loop16
|
||||
C640 NmiHandler_Loop17
|
||||
C65A NmiHandler_Loop18
|
||||
C65E NmiHandler_Loop19
|
||||
C661 NmiHandler_Loop20
|
||||
C663 NmiHandler_Loop21
|
||||
C673 NmiHandler_Loop22
|
||||
C67B NmiHandler_Loop23
|
||||
C693 Sub_C693
|
||||
C69C NmiHandler_OnNonnegative2
|
||||
C6A4 NmiHandler_Loop24
|
||||
C6A7 NmiHandler_Loop25
|
||||
C6A8 Sub_C6A8
|
||||
C6C9 NmiHandler_Loop26
|
||||
C6D1 NmiHandler_OnNonzero10
|
||||
C6E0 Sub_C6E0
|
||||
C6ED NmiHandler_OnNegative2
|
||||
C6EE NmiHandler_Loop27
|
||||
C710 Sub_C710
|
||||
C71C NmiHandler_OnNonzero11
|
||||
C725 NmiHandler_Loop28
|
||||
C731 Sub_C731
|
||||
C74A NmiHandler_OnZero2
|
||||
C750 NmiHandler_Loop29
|
||||
C76C NmiHandler_Loop30
|
||||
C776 NmiHandler_Loop31
|
||||
C77E NmiHandler_Loop32
|
||||
C782 Sub_C782
|
||||
C790 NmiHandler_Loop33
|
||||
C794 NmiHandler_Loop34
|
||||
C796 NmiHandler_Loop35
|
||||
C7A8 Sub_C7A8
|
||||
C7C6 NmiHandler_Loop36
|
||||
C7C7 NmiHandler_Loop37
|
||||
C7CB NmiHandler_Loop38
|
||||
C7CF NmiHandler_Loop39
|
||||
C7D3 NmiHandler_Loop40
|
||||
C7D5 NmiHandler_Loop41
|
||||
C7EA Sub_C7EA
|
||||
C855 Sub_C855
|
||||
C85D Sub_C85D
|
||||
C865 NmiHandler_Loop42
|
||||
C876 NmiHandler_Loop43
|
||||
C886 Sub_C886
|
||||
C8A6 NmiHandler_Loop44
|
||||
C8A7 NmiHandler_Loop45
|
||||
D776 NmiHandler_OnCarryClear2
|
||||
D781 NmiHandler_Loop46
|
||||
D78C Sub_D78C
|
||||
D7AA Sub_D7AA
|
||||
D7BA Sub_D7BA
|
||||
EADA Sub_EADA
|
||||
EAF0 NmiHandler_OnNonzero12
|
||||
EB02 NmiHandler_Loop47
|
||||
EB08 Sub_EB08
|
||||
EB12 NmiHandler_Loop48
|
||||
EB14 NmiHandler_Loop49
|
||||
EB2A NmiHandler_OnNonzero13
|
||||
EB3F NmiHandler_Loop50
|
||||
EB5A NmiHandler_OnNonzero14
|
||||
EB65 NmiHandler_Loop51
|
||||
EB70 NmiHandler_Loop52
|
||||
EB76 NmiHandler_OnCarryClear3
|
||||
EB88 NmiHandler_Loop53
|
||||
EB9B NmiHandler_OnCarryClear4
|
||||
EBAC NmiHandler_Loop54
|
||||
EBB7 NmiHandler_Loop55
|
||||
EBC2 NmiHandler_Loop56
|
||||
EBCB NmiHandler_Loop57
|
||||
EC01 NmiHandler_Loop58
|
||||
EC04 NmiHandler_Loop59
|
||||
EC27 NmiHandler_OnNonzero15
|
||||
EC2E NmiHandler_Loop60
|
||||
EC4A NmiHandler_Loop61
|
||||
EC54 NmiHandler_Loop62
|
||||
EC5C NmiHandler_Loop63
|
||||
ED51 Sub_ED51
|
||||
ED60 Sub_ED60
|
||||
F790 Sub_F790
|
||||
F794 NmiHandler_OnNonzero16
|
||||
F7A2 NmiHandler_OnZero3
|
||||
|
@@ -0,0 +1,10 @@
|
||||
MEMORY {
|
||||
HEADER: start = $0000, size = $0010, fill = yes;
|
||||
PRG: start = $8000, size = $8000, fill = yes;
|
||||
CHR: start = $0000, size = $2000, fill = yes;
|
||||
}
|
||||
SEGMENTS {
|
||||
HEADER: load = HEADER, type = ro;
|
||||
PRG: load = PRG, type = ro;
|
||||
CHR: load = CHR, type = ro;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
; Galaga (U) application-specific RAM aliases - Pass 1
|
||||
; Generated from every direct zero-page operand in reachable code:
|
||||
; ref counts are reads/writes, `where` lists the referencing addresses.
|
||||
; ZpXX names indicate storage with a role not yet unique enough for a behavioral name;
|
||||
; Pass 2 replaces them with names derived from observed usage.
|
||||
|
||||
Zp00 = $00 ; 75 refs; reads=25 writes=50; used at $C022, C027, C11C, C132, +71 more
|
||||
Zp01 = $01 ; 32 refs; reads=8 writes=24; used at $C020, C02B, C122, C1A5, +23 more
|
||||
Zp02 = $02 ; 28 refs; reads=9 writes=19; used at $C13E, C1E1, C4B3, C4C2, +24 more
|
||||
Zp03 = $03 ; 10 refs; reads=5 writes=5; used at $C519, C542, C6FB, C79A, +6 more
|
||||
Zp04 = $04 ; 27 refs; reads=11 writes=16; used at $C140, C1D5, C4A2, C4DC, +21 more
|
||||
Zp05 = $05 ; 21 refs; reads=7 writes=14; used at $C142, C1DB, C58B, C5BB, +17 more
|
||||
Zp06 = $06 ; 15 refs; reads=6 writes=9; used at $C194, C2BE, C640, C65A, +7 more
|
||||
Zp07 = $07 ; 4 refs; reads=2 writes=2; used at $EC1F, EC29, EC38
|
||||
Zp08 = $08 ; 10 refs; reads=6 writes=4; used at $C1F7, C202, C208, C20F, +6 more
|
||||
Zp09 = $09 ; 3 refs; reads=1 writes=2; used at $C1FD, C6A8, C6CE
|
||||
Zp0A = $0A ; 35 refs; reads=21 writes=14; used at $C212, C21A, C509, C520, +30 more
|
||||
Zp0B = $0B ; 5 refs; reads=0 writes=5; used at $C50D, C524, C536, C5DA, +1 more
|
||||
Zp0C = $0C ; 13 refs; reads=4 writes=9; used at $C511, C528, C53A, C5D6, +5 more
|
||||
Zp0D = $0D ; 3 refs; reads=1 writes=2; used at $C515, C53E, C6D7
|
||||
Zp0E = $0E ; 2 refs; reads=1 writes=1; used at $C501, C8A7
|
||||
Zp10 = $10 ; 2 refs; reads=1 writes=1; used at $C6B1, D7BE
|
||||
Zp11 = $11 ; 2 refs; reads=1 writes=1; used at $C6B5, D7C4
|
||||
Zp1C = $1C ; 13 refs; reads=8 writes=5; used at $C56E, C577, C57A, C57D, +7 more
|
||||
Zp1D = $1D ; 9 refs; reads=5 writes=4; used at $C567, C570, C580, C5A1, +5 more
|
||||
Zp1E = $1E ; 12 refs; reads=6 writes=6; used at $C14D, C1E7, C305, C30A, +7 more
|
||||
Zp1F = $1F ; 4 refs; reads=1 writes=3; used at $C308, C310, D776, D794
|
||||
Zp40 = $40 ; 2 refs; reads=1 writes=1; used at $C073, C275
|
||||
Zp41 = $41 ; 2 refs; reads=1 writes=1; used at $C05B, C284
|
||||
Zp42 = $42 ; 2 refs; reads=1 writes=1; used at $C05F, C27A
|
||||
Zp43 = $43 ; 2 refs; reads=1 writes=1; used at $C063, C27F
|
||||
Zp44 = $44 ; 2 refs; reads=1 writes=1; used at $C2F1, C2FB
|
||||
Zp46 = $46 ; 2 refs; reads=1 writes=1; used at $C095, C2F7
|
||||
Zp48 = $48 ; 7 refs; reads=6 writes=1; used at $C083, C09B, C547, C556, +2 more
|
||||
Zp49 = $49 ; 2 refs; reads=1 writes=1; used at $C087
|
||||
Zp4A = $4A ; 4 refs; reads=2 writes=2; used at $C077, C079, C0CD, C0D2
|
||||
Zp4B = $4B ; 4 refs; reads=3 writes=1; used at $C06C, C091, C0D4, C18C
|
||||
Zp4E = $4E ; 7 refs; reads=4 writes=3; used at $C11A, C128, C1C4, C1D3, +3 more
|
||||
Zp4F = $4F ; 3 refs; reads=1 writes=2; used at $C151, C1C6, C234
|
||||
Zp50 = $50 ; 1 refs; reads=1 writes=0; used at $C587
|
||||
Zp51 = $51 ; 2 refs; reads=1 writes=1; used at $C56A, C56C
|
||||
Zp52 = $52 ; 2 refs; reads=1 writes=1; used at $C572, C574
|
||||
Zp5B = $5B ; 3 refs; reads=2 writes=1; used at $C08D, C0AD, EB0E
|
||||
Zp62 = $62 ; 2 refs; reads=2 writes=0; used at $C089, EB0A
|
||||
Zp6E = $6E ; 4 refs; reads=3 writes=1; used at $C317, C31C, C31E, C332
|
||||
Zp6F = $6F ; 6 refs; reads=4 writes=2; used at $C320, C324, C32E, C330
|
||||
ZpB0 = $B0 ; 5 refs; reads=2 writes=3; used at $EB18, EB3A, EB41, EB47, +1 more
|
||||
ZpB1 = $B1 ; 1 refs; reads=0 writes=1; used at $EB1A
|
||||
ZpB2 = $B2 ; 1 refs; reads=0 writes=1; used at $EB1C
|
||||
ZpB3 = $B3 ; 1 refs; reads=0 writes=1; used at $EB1E
|
||||
ZpDE = $DE ; 1 refs; reads=0 writes=1; used at $C042
|
||||
ZpDF = $DF ; 1 refs; reads=0 writes=1; used at $C03E
|
||||
ZpEC = $EC ; 1 refs; reads=0 writes=1; used at $EC61
|
||||
ZpFA = $FA ; 1 refs; reads=0 writes=1; used at $C03A
|
||||
ZpFF = $FF ; 3 refs; reads=2 writes=1; used at $C014, C032, C036
|
||||
@@ -0,0 +1,203 @@
|
||||
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙Line truncated
|
||||
F | ||||