;;; ;; 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