diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/1.s | 5 | ||||
| -rw-r--r-- | src/2.s | 5 | ||||
| -rw-r--r-- | src/3.s | 713 |
3 files changed, 721 insertions, 2 deletions
@@ -110,7 +110,10 @@ @end: ;; Run tests now that everything has been done. - CALL_TESTS_ON_DONE +.ifdef RUN_TESTS + @test: + nop +.endif @halt: jmp @halt .endproc @@ -138,7 +138,10 @@ @end: ;; Run tests now that everything has been done. - CALL_TESTS_ON_DONE +.ifdef RUN_TESTS +@test: + nop +.endif @halt: jmp @halt .endproc @@ -0,0 +1,713 @@ +;;; +;; Day 3 https://adventofcode.com/2023/day/3 +;; +;; The enunciate has two parts, but I have only implemented the first one +;; because I didn't have the time, and for it I'd need to build up some memory +;; management code that gets out of hand fast on the poor NES. Maybe in the +;; future I'd revisit this, but I was feeling the enjoyment out of the puzzle, +;; which is kind of the whole point... +;; +;; Note also that this will not print the result in a similar fashion as the +;; second part from day 2, because printing 24-bit numbers needs its own code +;; which I have not yet implemented. Maybe in the near future. For now just look +;; at the 32-bit integer at $0C. + +.segment "HEADER" + .byte 'N', 'E', 'S', $1A + + .byte $02 + .byte $01 + + .byte $00 + .byte $00 + +.segment "VECTORS" + .addr nmi, reset, irq + +.segment "CHARS" + .incbin "../assets/alphanum.chr" + +.segment "STARTUP" +.segment "CODE" + +.include "../include/apu.s" +.include "../include/oam.s" +.include "../include/ppu.s" +.include "../include/reset.s" +.include "../include/globals.s" +.include "../include/print.s" + +.include "../test/defines.s" + +;; "Variables" used by this program. +.scope Vars + ;; The address pointing to the previous row. + ;; + ;; NOTE: 16 bit. + m_address_prev = $00 + + ;; The address pointing to the current row. + ;; + ;; NOTE: 16 bit. + m_address_cur = $02 + + ;; The address pointing to the next row. + ;; + ;; NOTE: 16 bit. + m_address_next = $04 + + ;; The number of bytes separating the beginning of a row and the other. + ;; Used when advancing to the next iteration. + m_address_step = $06 + + ;; Numeric values being used when parsing numbers, and also sometimes for + ;; temporary values when the number represented by these three bytes has + ;; already been consumed. + m_num_1 = $07 + m_num_2 = $08 + m_num_3 = $09 + + ;; The last number that has been parsed. + ;; + ;; NOTE: 16-bit. + m_num_16 = $0a + + ;; The number being accumulated over different iterations and giving the end + ;; result. + ;; + ;; NOTE: this could have been just a 24-bit number, but we are reserving to + ;; it 32 bits because FCEUX goes from 16 bit to 32 bits. + m_num_32 = $0c + + ;; The index pointing to the left edge of the last evaluated number. + m_num_left = $10 + + ;; The index pointing to the right edge of the last evaluated number. + m_num_right = $11 + + ;; Address iterator. This is to be set before calling `check_address`, + ;; because this subroutine will consume this address. + ;; + ;; NOTE: 16 bit. + m_address_it = $12 + + ;; Initialize some of the variables. + .proc init + lda #0 + sta Vars::m_address_prev + sta Vars::m_address_prev + 1 + + sta Vars::m_num_16 + sta Vars::m_num_16 + 1 + + sta Vars::m_num_32 + sta Vars::m_num_32 + 1 + sta Vars::m_num_32 + 2 + sta Vars::m_num_32 + 3 + + lda #.LOBYTE(data) + sta Vars::m_address_cur + lda #.HIBYTE(data) + sta Vars::m_address_cur + 1 + + jsr set_step + lda #.LOBYTE(data) + clc + adc Vars::m_address_step + sta Vars::m_address_next + lda #0 + adc #.HIBYTE(data) + sta Vars::m_address_next + 1 + + rts + .endproc +.endscope + +;; Copy the given pointer to Vars::m_address_it. +.macro ADDRESS_PTR_TO_IT address + lda address + sta Vars::m_address_it + lda address + 1 + sta Vars::m_address_it + 1 +.endmacro + +;; The main function will be called at the end of the `reset` vector as defined +;; in `include/reset.s`. +.proc main + ;; Initialize palettes and variables being used for this program. + jsr Print::load_basic_palettes + jsr Vars::init + + ;; This program uses two flags: + ;; - 7 (`render`): whether NMI-code can render stuff on screen. + ;; - 6 (`done`): whether the computation has been done. + ;; + ;; Note that we are setting the render flag so the initial message is + ;; shown. + lda #%10000000 + sta Globals::m_flags + + cli + + lda #%10010000 + sta PPU::CONTROL + lda #%00011110 + sta PPU::MASK + +@loop: + ;; Skip everything if the `done` flag is set. + bit Globals::m_flags + bvs @end + + jsr compute_next + jmp @loop + +@end: + ;; Run tests now that everything has been done. +.ifdef RUN_TESTS +@test: + nop +.endif +@halt: + jmp @halt +.endproc + +;; Initialize `Vars::m_address_step` with the step as computed by measuring the +;; length of the first row. That is, we assume that all rows have the same +;; number of columns, which is cool by the enunciate. +.proc set_step + ldy #0 +@loop: + lda (Vars::m_address_cur), y + beq @done + iny + jmp @loop +@done: + iny + sty Vars::m_address_step + rts +.endproc + +;; Compute the next iteration of the exercise. Note that this subroutine assumes +;; that we are not done yet. Hence, do not call this subroutine if the `done` +;; flag has already been set. +.proc compute_next + jsr compute_row + + ;; + ;; Ready address pointers for the next iteration. + + ;; current -> previous. + lda Vars::m_address_cur + sta Vars::m_address_prev + lda Vars::m_address_cur + 1 + sta Vars::m_address_prev + 1 + + ;; next -> current + lda Vars::m_address_next + sta Vars::m_address_cur + lda Vars::m_address_next + 1 + sta Vars::m_address_cur + 1 + + ;; Wait, does the first byte on the current address contain the guard value? + ;; If so, then we are done. + ldy #0 + lda (Vars::m_address_cur), y + cmp #$ED + beq @done + + ;; next = next + step. + lda Vars::m_address_step + clc + adc Vars::m_address_next + sta Vars::m_address_next + lda #0 + adc Vars::m_address_next + 1 + sta Vars::m_address_next + 1 + + rts + +@done: + ;; Mark the `done` flag so future iterations don't go through all of this. + ;; We are also setting the `render` flag so the last message is also shown. + lda #%11000000 + ora Globals::m_flags + sta Globals::m_flags + rts +.endproc + +;; Compute a given row of the exercise. +.proc compute_row + ldy #0 + + ;; This loop is rather simple: + ;; + ;; 1. Fetch the current byte. If this is the zero byte, then we are done. + ;; If it's not numeric, skip it and go to @next. + ;; 2. If this is a numeric value, parse the number. + ;; 3. Then check the edges on the prev, cur, and next addresses. + ;; 4. If any of them left a `1` on `Vars::m_num_1`, then we have found a + ;; symbol between the two edges and we have to add the value of our + ;; number on @sum. +@loop: + lda (Vars::m_address_cur), y + beq @done + sec + sbc #48 + bcc @next + cmp #10 + bcs @next + + lda #0 + sta Vars::m_num_16 + sta Vars::m_num_16 + 1 + + jsr parse_number + + ADDRESS_PTR_TO_IT Vars::m_address_prev + jsr check_address + lda Vars::m_num_1 + bne @sum + + ADDRESS_PTR_TO_IT Vars::m_address_cur + jsr check_address + lda Vars::m_num_1 + bne @sum + + ADDRESS_PTR_TO_IT Vars::m_address_next + jsr check_address + lda Vars::m_num_1 + bne @sum + jmp @loop + +@sum: + ;; We have to add the number on `Vars::m_num_16` into the accumulator + ;; `Vars::m_num_32`. That is, we only need to add the first 16 bits and then + ;; carry over the carry bit into the other 16 bits. + lda Vars::m_num_16 + clc + adc Vars::m_num_32 + sta Vars::m_num_32 + lda Vars::m_num_16 + 1 + adc Vars::m_num_32 + 1 + sta Vars::m_num_32 + 1 + lda #0 + adc Vars::m_num_32 + 2 + sta Vars::m_num_32 + 2 + lda #0 + adc Vars::m_num_32 + 3 + sta Vars::m_num_32 + 3 + jmp @loop + +@next: + iny + jmp @loop + +@done: + rts +.endproc + +;; Parse the number being pointed by `Vars::m_address_cur` and the `y` register. +.proc parse_number + ;; Initialize with a guard value. + lda #$FF + sta Vars::m_num_1 + sta Vars::m_num_2 + sta Vars::m_num_3 + + ;; Now it's a good time to set the left edge. Note that `y` is pointing + ;; right at the first numeric value, and the edge is -1 of that. Hence, we + ;; have to decrease this value unless we are already at 0. + sty Vars::m_num_left + cpy #0 + beq @loop + dec Vars::m_num_left + +@loop: + ;; Load the given byte. If this is not a numerical value, just go to @done. + lda (Vars::m_address_cur), y + sec + sbc #48 + bcc @done + cmp #10 + bcs @done + + ;; This is a numerical value! At this point we will set the number on + ;; `Vars::m_num_{1, 2, 3}` in order. + ldx Vars::m_num_1 + cpx #$FF + beq @first + ldx Vars::m_num_2 + cpx #$FF + beq @second + sta Vars::m_num_3 + iny + jmp @done +@first: + sta Vars::m_num_1 + iny + jmp @loop +@second: + sta Vars::m_num_2 + iny + jmp @loop + + ;; There are no more numerical digits, let's evaluate what we have parsed. +@done: + ;; The `y` register is already pointing at the right edge. + sty Vars::m_num_right + + ;;; + ;; From here forward the code seems more comboluted that it actually is. We + ;; basically track how many `Vars::m_num_{1, 2, 3}` we have set. Depending + ;; on that, each variable will contain either a hundredth, a tenth or a + ;; unit. Either way, we just multiply at the proper values and add things up + ;; to get our numeric value into `Vars::m_num_16`. + + lda Vars::m_num_2 + cmp #$FF + beq @just_unit + lda Vars::m_num_3 + cmp #$FF + beq @tenth_and_unit + + ;; This is the case in which we have found three digits. Hence, `m_num_1` + ;; contains the hundredth (used by `mul_by_100`), `m_num_2` the tenth and + ;; `m_num_3` the unit. See that for simplicity we first go with the + ;; hundredth, then we add the unit, and we prepare into the `a` register the + ;; digit for the tenth, since `@tenth` will take care of it regardless of + ;; the branch of the code. + + jsr mul_by_100 + + lda Vars::m_num_3 + clc + adc Vars::m_num_16 + sta Vars::m_num_16 + lda #0 + adc Vars::m_num_16 + 1 + sta Vars::m_num_16 + 1 + + lda Vars::m_num_2 + jmp @tenth +@tenth_and_unit: + ;; Two digits were found. Here we only need to initialize our number with + ;; the unit and then go to `@tenth` to get the tenth which is in `m_num_1` + ;; this time around. + lda Vars::m_num_2 + clc + adc Vars::m_num_16 + sta Vars::m_num_16 + lda #0 + adc Vars::m_num_16 + 1 + sta Vars::m_num_16 + 1 + + lda Vars::m_num_1 +@tenth: + ;; Similarly to day 2, multiplying by 10 is done by n*2 + n*8. + asl + sta Vars::m_num_3 + asl + asl + clc + adc Vars::m_num_3 + + ;; And add this tenth (regardless if we came from the three or two digits + ;; cases) and we have it already. + clc + adc Vars::m_num_16 + sta Vars::m_num_16 + lda #0 + adc Vars::m_num_16 + 1 + sta Vars::m_num_16 + 1 + + rts +@just_unit: + ;; This is the most simple case: only one digit was found. Then we have it + ;; on `m_num_1`, and we can just set it into our number. + lda Vars::m_num_1 + sta Vars::m_num_16 + lda #0 + sta Vars::m_num_16 + 1 + rts +.endproc + +;; Multiply the value on `Vars::m_num_1` by 100 and set it into +;; `Vars::m_num_16`. +.proc mul_by_100 + ;; What's the algorithm on poor 6502 with no decimal mode? Well, you guessed + ;; it, just accumulate the value 100 times :D + ldx #100 +@loop: + lda Vars::m_num_16 + clc + adc Vars::m_num_1 + sta Vars::m_num_16 + lda #0 + adc Vars::m_num_16 + 1 + sta Vars::m_num_16 + 1 + + dex + bne @loop + rts +.endproc + +;; Sets the `Vars::m_num_1` variable to `1` if there is a symbol between the +;; left and the right edges as can be seen on the data indexed by +;; `Vars::m_address_it`. The `y` register is preserved during all of this. +.proc check_address + ;; We set it now, and we will only set it again when we find a symbol. + lda #0 + sta Vars::m_num_1 + + ;; If the 16-bit pointer is null, then just leave. + lda Vars::m_address_it + bne @proceed + lda Vars::m_address_it + 1 + bne @proceed + rts + +@proceed: + ;; Save the `y` register, since the caller is definitely interested on + ;; preserving it. + tya + pha + + ;; The loop is pretty straighforward: we will iterate over + ;; `Vars::m_address_it` from the left edge until the right one. On each + ;; iteration we will call `is_symbol` and set `Vars::m_num_1` to `1` if this + ;; call returns true. + ldy Vars::m_num_left + dey +@loop: + iny + lda (Vars::m_address_it), y + beq @done + jsr is_symbol + beq @next + lda #1 + sta Vars::m_num_1 + jmp @done +@next: + ;; The register `y` contains the index of the last evaluated position. If + ;; this turns out to be either the right edge or, by any bug, greater than + ;; that, then we are done. Otherwise, we will loop if `y` is lesser than the + ;; right edge. + cpy Vars::m_num_right + bcc @loop +@done: + ;; And restore the `y` register before leaving. + pla + tay + rts +.endproc + +;; Sets the `a` register to `1` if the current value of `a` corresponds to a +;; symbol as defined by the enunciate. Otherwise it will set it to 0. +.proc is_symbol + ldx #0 +@loop: + cmp symbols, x + beq @found + inx + cpx #$0A + bne @loop + lda #0 + rts +@found: + lda #1 + rts +symbols: + .asciiz "#%&*+-/=@$" +.endproc + +;; Non-Maskable Interrupts handler. +nmi: + bit PPU::STATUS + + ;; Skip rendering if the `render` flag is not set. + bit Globals::m_flags + bpl @nmi_next + + ;; Backup registers. + pha + txa + pha + tya + pha + + ;; If the result is not there yet, then we just print an initial message. + ;; Otherwise print a done message. + bit Globals::m_flags + bvs :+ + jsr Print::show_wait_message + jmp :++ +: + jsr Print::show_done_message +: + + ;; Reset the scroll. + bit PPU::STATUS + lda #$00 + sta PPU::SCROLL + sta PPU::SCROLL + + ;; And unset the render flag so the `main` code is unblocked. + UNSET_RENDER_FLAG + + ;; Restore registers. + pla + tay + pla + tax + pla +@nmi_next: + rti + +;; Unused. +irq: + rti + +.segment "RODATA" +data: + .asciiz "..............423....688..934............970................................95.728..........896...113..................153..972............." + .asciiz "...122..................*.....*..........................919..509*..........&...@.........../...........................+.......*..........." + .asciiz "....+..........259....698..373.992.52.674.........................781...22........130.584.....-...%399.......777.................266........" + .asciiz "......148..+....*........................*.....357.123.......................812.........*756.143...........*..............................." + .asciiz "..691*.....700..708................-...357........*........$177......%..244.............................762.453....477-.707..-168..359*....." + .asciiz ".......................394.443....456......750..................71.160.....*..183.........835..74.........*.............../............129.." + .asciiz "....578$....................%........................362..1......*.......661....*...........=.....730......744..294..........247............" + .asciiz "..............415...306*....../.452.................+.....*......375.............76....186*....../...............*..........@.......-..441.." + .asciiz ".....*152......#........75.757.......204%..................605.............................77.......%405.......957..324...........404......." + .asciiz "..545.............../...........................................*....618......%...599...............................&....43.............=..." + .asciiz "..............902...145............170..............568..741.285.592..........54./.......%.......923......522+..........*..../...128....602." + .asciiz ".......697.16*................322...........$............*............+339..........633.56............$..............792..751..............." + .asciiz ".......*.........................*..752..826.......*...104..861......................................144.....883...............+..778.892..." + .asciiz "......968..690.......#.....769#.718...*.........326..........*..............493..123..........362...........*.........757....570..@....*...." + .asciiz "..681.................242............806................509...307..../.....*......./.350..942...*..614@...511........+.................151.." + .asciiz "........*....../..256.......................235.....923....*..........28..264........*......&..316..............945....522........*823......" + .asciiz ".....961.136.567....................944.......*..........500..-.......................504................765$..........=.......563.........." + .asciiz "..................837..823......480.....627....984.#.........136....969..........-289......$757............................107........593..." + .asciiz ".74.924....../.............+110....*...............511................+....564......................389%.....989*305....@...*.........*....." + .asciiz ".......+......110..735..........647....658.509*378..........-999............*....#225....937.............147.........778...868.....871..611." + .asciiz ".........$...........*.....3............*...........................608..842..............*.......589.......*....842...................*...." + .asciiz "......$.963.....634.....................569....&..........177................*..........774.........*..132.153..*.............=.......13...." + .asciiz "...723.........=.......@..324......455#.......417....849$.*.........*372..747.87............./358...35..*.......974..453...811...990........" + .asciiz ".....................174...%............949...............182....684.............414...................201.......................*...../...." + .asciiz "........@.......................62.....*.....-.@669.....................487......*................943.........740*...10.......298....384...." + .asciiz "....446.711.........20.674...........343..806.....................&.574.*........965..............*......776...........*.867................" + .asciiz "......*............&.......705.804.............................374....+.307............&.......683...830...*....625..530....*837...272*....." + .asciiz ".......791....................*.......&.................108...........................533..............*...966.*.......................515.." + .asciiz "............412...../................764....................658.+292.635.674..337.................98..814......263.......720*..............." + .asciiz "..............*...469..162.....23......................*64..*...............*.............+.........*.....*552...............990......942..." + .asciiz "790.536.......365.......*..587..=..........................313.....512....983....953.......348.....617.982.................................." + .asciiz "........580............227...*....673.808....66......595............./........*............................$..........21..989..............." + .asciiz ".....#.....*.781...........688...*..../........=.........865...............316.162.440.............&......482.663....*.............529......" + .asciiz "...357...182.@......359=..........553.......#....33....................323.........*............702...........*....200........&.....*......." + .asciiz "...............733....................957.22..........815.........................57..657@..................792..........%.....678.305......" + .asciiz "..701..246........*238....553..107......*...................301..........649.555..............70....................610.233.&..............." + .asciiz "....#...*..&.................$.*....$.......$......438.....*.......943......*.....&675..955*....*..........183...=....%.....595............." + .asciiz "......719.857...640*299............202...125...802..#...786...........*.....................277.424..........*.790./...............984......" + .asciiz "...@......................368.....................*...............323..587.479....553.272.................843.......518.............*......." + .asciiz "...382..........892...46..........359..372+.611..585...............*.......*........*...+........&.............................487...35....." + .asciiz "........&692.......*..*..............@.......-.......*697.......656.....155....34..681............64..641......................*............" + .asciiz "....495..........885..964................993......685................%........*....................../..........543.........863............." + .asciiz "..........*408................&....244.....*..........................893....339........................109.....................777........." + .asciiz "...521.985..................677......*......734........18....925#................352...843*74.......&....*.............260.......*.........." + .asciiz "...$........445.$..................802...................#..........=........533...@.................228..612......724....*................." + .asciiz ".............*..504............=.......*.....177...................502.....+..*.............395......................$.....274.....396......" + .asciiz "......................417....274.....61.504..*........36*..................34..801..........%............224......................*........." + .asciiz "......789.........139......&.....*............802........674....&..332..............675............819.............814............883..+915." + .asciiz "...@.....*.....-..*.....970...279.117...............984@.....878..........231*168.*..................*.........793*........................." + .asciiz "..33..875.....483.433....................*.........................................148.675...581*.....544.........................*537......" + .asciiz "......................884............671..839.....31..........685..@...899....350*...............621........*509............./.913.........." + .asciiz "....947......=742..........*.......................*...............712....*.......722...159............378........438.....300...........381." + .asciiz "...*....................548..-................*..638.....................827...........*......714/...../...867....$..................%.-...." + .asciiz "998.....966.693..............694...........781...........764......584...............233....58......-......*............67=........161......." + .asciiz "...........*.....................509..-851.........&.846..#........../...199.................*.443..658..976.130..489..................594.." + .asciiz "243....413.........499-...384.......*............352.+.............................752....298..*...............$..$...............577...*..." + .asciiz "......*......................*......378.335.................*.........+...813.120.*....................654..........$........325...*...984.." + .asciiz "...847..496....151*...........741.......*............624.116....767.988..&.....*...87............807...*.........127....997+......621......." + .asciiz "........*..........227....345......*........@.....................*............699....566..604...*...760....290............................." + .asciiz "......526..................*..500..799...761...413*......277....101........$..........*.........342..........*.......589..997......=........" + .asciiz ".............+....379....549............................*............*97.647.779....$.655..975......216...............*.......51..307./496.." + .asciiz "...........485.......&...............................55...........509............825......+.....43.....*...554......36...678+.$............." + .asciiz "..........................73.....419.....314../...........311...........$....946.....272............351...*........................968../..." + .asciiz ".....786.................*........-..824.$...478......908....*.....455.254.....*.........615....760.....60...$......&.....*562.........102.." + .asciiz ".......*......43.....&...808........*.............267.*...985.....*..........616.........../......*...........189....977........616........." + .asciiz "......45.932...*.....502..........805...943.840%...*..270......764......680......................750..415*184......................*606....." + .asciiz "..768....*.....941............%.......8.&..................*................248&..105..745...633...........................584..........692." + .asciiz ".......684............115....88...396*..................494.354...88...58.....................*.........956......809...53.......615........." + .asciiz "................*391.............................................$....%.....&64.............488...........$.........*.....*.......*........." + .asciiz "......440.459...........637...*....866...412.519.183..../.......................*82..963.........*307..=......715.408..421.292....626..*...." + .asciiz ".........*......$..........#...769............./..*....470.939.+......*.....257.....*.........257.....109.578..*.......................290.." + .asciiz "......+.......-..897...............................629.....-...834.254.798..*.......411....................*....411.......309....218........" + .asciiz ".......960..744..............384............................................433................$301.....848.................*.......#..144.." + .asciiz "..746............$....../...........38$...536.....-....@.............*..................-............................320...471..........*..." + .asciiz "....*.............720...59......................260..852...........633.........714...510......256.173.23...850........*........#.....691...." + .asciiz "..294..434...264......................422../639..........378.493...........388*................-....*...*..../.141..............539........." + .asciiz "........../.&........790..........@....*....................*..........&............$.............16....633.....=.....................458..." + .asciiz "..678...............&.......184....186.934..652...741%.........=887...980.425../....485.732...502...........%........745..............*....." + .asciiz "...*..........98.......@......*.................+...........................*...989.....$........*......838.9..........-...........464......" + .asciiz ".975..768....*.....*..702.....979....511$....161....645..............44.....18............721.695...348.........400......./.543*............" + .asciiz "........*.769....320......724......................&.....330&........*...................*...........$...188.....*.....977......618...%....." + .asciiz "......879.....79............*....658..............................601................701..490....#......*........478.......166.........892.." + .asciiz "..844.............706....472....*...........113.........-765..217........267....../.*..........648....973....285............................" + .asciiz ".....*.482..........*...........853....408.....*................&........*.......59.265.........................*.......364....45.......@..." + .asciiz "..164..*...........309....472............#..478...40.......356........328....706..............$...............149.526.....%.....*.....27...." + .asciiz "...........................*.......&..................612...*..58.64%........*...766.......953......488............=.../.......152.........." + .asciiz "...*73....872.............347....27...22......552@.........559.*............435.....*679.............*...13.774......177.#250.......8*......" + .asciiz "977......#.........=....................=.......................56...508......................139.747.....*..*................861.....666..." + .asciiz "..............703...102....../........&....637..448......%..951........*...175.552*235...@.....*.......486..693............................." + .asciiz "........944..*....@...........590..42.738...*..........861.....&....919.....*............108.837................#....963.530...831..&...251." + .asciiz "........#.....93.103....708................54.342....+......................496.......................&.........278.....*.....*....162......" + .asciiz "..........860............@.......$167..............431.683......=496....858.........422.............662.154.405..............635.%.........." + .asciiz ".....882/.*.............................%......611..........766.......-...*.....755..@.....................*..........608.........951......." + .asciiz "..........513......................274...226......*........@.......&..556.151....*.............229...681..............*.....911............." + .asciiz "..............445....375.....774....*...........348..............643.............302...........*........*.......-...88......*........975...." + .asciiz "....*664.........*...&........@.........................893..........523....13...............825.........558...733.....769...991.....*......" + .asciiz ".328......821....935...................&.......@...457.....*.....+..*.........=..................341..................#............384......" + .asciiz ".........*...........164..........251..756....23...........912.532..879..................459........*...=..................................." + .asciiz "219.....71..821..............654.....................684........................@2....................931...........910....................." + .asciiz "............&...425+..-.............207........*.....%...360...........190..........69.....................43..........$...................." + .asciiz ".....................116....................127.214.........*..181........@..%...49*....444....57.........*.....................715........." + .asciiz "............$....*.............-..859.................=..248......*..........82........*.......@.......246..376.........#........*.........." + .asciiz "...726...898...-..772...223.712....%........%464.....342.........442..447.........461..102.....................*355...537....313..596...584." + .asciiz "....*.........189........@...............................................*187........*...............*....807.............+.....*..........." + .asciiz ".....181.+..........197......530.653+.383...293.........461%.22*..............394....769..104...$.818.36.$....=.......&....860...333........" + .asciiz "..........827..........*................-....*..................110.883..................%.....56............111......872..................." + .asciiz "........................8.321....-............209.....578...583.....$.....948..548#..................868*678......871......................." + .asciiz "......658...264...........&....105......132............./...................*..................640..................*...........714........." + .asciiz ".........+.*.....................................................................608..............*....963*565.....472.......93...*........." + .asciiz "...*717....14.......................702............604.608......................*.....12....689..599.............................423........" + .asciiz "999.........................764......*.......$780.....*.......+.......%........406....*...............278*........600*23.....407.....964...." + .asciiz "...........%....308................183................../......758..&..360..........127.#696...50........................839*.....&.....$..." + .asciiz "......277..449....*............881.......822.....905...205.........345.......572@................../733....=..61...................796......" + .asciiz ".......#..........659...*.....=..........................................................................665...................292.........." + .asciiz "......................887.711.....560..........................11...213*434...................949....761......*856...233*996......%.965....." + .asciiz ".....699..../.............&....%......103...518...............................673......=.........*....@....149.............................." + .asciiz "............894......=......292..425.....#........@259....787..995..................927..813..326..............439.....379.547..292........." + .asciiz "....901............678.217......*..............................*.......289.346..875.........*.........653+......*......*....=.....$........." + .asciiz "......#........................56..887....&540..200...........824............&.....*.414=....629..............893..34.334................731" + .asciiz "...............476.......338........@..#............592..573*.....759...........598........$.........692..474.......*................304...." + .asciiz "..........................*..263*93...541....138......*..........*.....................260.187.......%...*.........436.................*...." + .asciiz ".....#..895............744.....................%.473...92........23..................$..#........853.....443......................12..339..." + .asciiz "...284...*...59*...131...............................................=....354.792...679.....649....*.......................994...%.........." + .asciiz ".......267............*...............176..............=.............743.........*......631......856................166.......*............." + .asciiz ".....................684.................@...........773....108...........617...965....*........................958............777.....767.." + .asciiz "..........572................#....&.............................51........@..........190..............694..882.#......511..788.............." + .asciiz "...96........%.....119..4.954....81..836....@.....671....161.................*.........................#..*.......730.%...*................." + .asciiz "....................@.................*...68..924...........*...644.......654.842..473.....449.............936.....*......305............980" + .asciiz "..........188....7..........672......596.........@........473......*..................*418....&.......302.........7...621.....476...938.*..." + .asciiz ".......@...*...........#824..*...303...........................%....486..........290..................*.....-907.....*.......*......*...686." + .asciiz "....869....976...478*.......56..*...........*..................415......97.@605.....................129............701....626....157........" + .asciiz ".....................455.......306.876......829............430..................956.15@.......302..........938.............................." + .asciiz "..........................43.......*..............$.......-.....998...106.......=.......486*....&.......+......................982.........." + .asciiz ".554......................*.......50.231.........409..............+...$.....*........72.....716.........51..445.....*284........*........350" + .asciiz ".........425............*.94..836......&..............#516..............775.701.....*............................744..........541......-...." + .asciiz "....*810..............34....................&....297..........#........*....................#.............899=..........972..........27....." + .asciiz "960........762.....................*........394........&355.401........347.....+853.....&...967............................*86..663........." + .asciiz "............*..........991......686.25.286.......&...................................653...........914........$.....580...........*........." + .asciiz "...#.....784......-.......*............*......498......*..........*..316........................&.&..........691.2.....*........91.........." + .asciiz "..791..............462....193..........8.............57.685.......90..........201............371.....242............996................579.." + .byte $ED |
