( minesweeper ) |00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1 |20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 |80 @Controller &vector $2 &button $1 &key $1 &func $1 |90 @Mouse &vector $2 &x $2 &y $2 &state $1 &pad $3 &scrollx $2 &scrolly $2 |c0 @DateTime &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 |a0 @File &vector $2 &success $2 &stat $2 &delete $1 &append $1 &name $2 &length $2 &read $2 &write $2 |0000 @game &started $1 &timer $2 &dead $1 @pointer &x $2 &y $2 @grid &x $2 &y $2 &x2 $2 &y2 $2 ( program ) |0100 ( -> ) ( theme ) #cf80 .System/r DEO2 #cf80 .System/g DEO2 #cf80 .System/b DEO2 ( DOS resolution ) #00a0 .Screen/width DEO2 #00d0 .Screen/height DEO2 prng-init load-theme ( place grid ) #0010 DUP2 .grid/x STZ2 #007f ADD2 .grid/x2 STZ2 #0040 DUP2 .grid/y STZ2 #007f ADD2 .grid/y2 STZ2 ( draw frames ) #0008 DUP2 #1004 draw-frame #0008 #0038 #1010 draw-frame draw-grid draw-progress draw-status draw-timer ( vectors ) ;on-mouse .Mouse/vector DEO2 ;on-frame .Screen/vector DEO2 ;on-button .Controller/vector DEO2 BRK @on-frame ( -> ) .game/started LDZ #00 NEQ [ JMP BRK ] [ LIT &f $1 ] #3c NEQ ,&no-second JCN #00 ,&f STR .game/timer LDZ2k INC2 ROT STZ2 draw-timer &no-second ,&f LDR INC ,&f STR BRK @on-button ( -> ) .game/dead LDZ #00 EQU ,&alive JCN reset &alive BRK @on-mouse ( -> ) ( clear last cursor ) .pointer/x LDZ2 .Screen/x DEO2 .pointer/y LDZ2 .Screen/y DEO2 #40 .Screen/sprite DEO ;pointer-icn .Screen/addr DEO2 ( draw new cursor ) .Mouse/x DEI2 DUP2 .pointer/x STZ2 .Screen/x DEO2 .Mouse/y DEI2 DUP2 .pointer/y STZ2 .Screen/y DEO2 #43 .Mouse/state DEI #00 NEQ DUP ADD SUB .Screen/sprite DEO .Mouse/state DEI #00 NEQ [ JMP BRK ] .Mouse/x DEI2 .Mouse/y DEI2 OVR2 OVR2 .grid within-rect ;touch-grid JCN2 POP2 POP2 .game/dead LDZ #00 EQU ,&alive JCN reset &alive #00 .Mouse/state DEO BRK @touch-grid ( x* y* -> ) .grid/y LDZ2 SUB2 #04 SFT2 NIP STH .grid/x LDZ2 SUB2 #04 SFT2 NIP STHr ( skip on death ) .game/dead LDZ ,&skip JCN .Mouse/state DEI #01 GTH ,touch-grid-flag JCN DUP2 reveal &skip POP2 #00 .Mouse/state DEO BRK @touch-grid-flag ( x y -> ) ( unset ) DUP2 #30 SFT ADD #00 SWP ;world/flags ADD2 LDA #00 EQU ,&add-flag JCN #00 ,&set-flag JSR BRK &add-flag ( add flag if have flags left ) count-flags ,&has-flags JCN POP2 BRK &has-flags ( can set ) #01 ,&set-flag JSR ( test victory ) count-left ,&no-victory JCN victory &no-victory BRK &set-flag ( x y value -- ) STH #30 SFT ADD #00 SWP ;world/flags ADD2 STHr ROT ROT STA draw-progress draw-grid #00 .Mouse/state DEO JMP2r ( @|core ) @reset ( -- ) #0000 .game/timer STZ2 #00 .game/started STZ #00 .game/dead STZ ;world #0100 mclr draw-status draw-progress draw-timer draw-grid JMP2r @explode ( -- ) #01 .game/dead STZ #00 .game/started STZ draw-status draw-grid JMP2r @victory ( -- ) #02 .game/dead STZ #00 .game/started STZ draw-status draw-grid JMP2r @start ( x y -- ) #01 .game/started STZ prng-init #1000 &while #01 prng #003f AND2 ;world ADD2 STA INC GTHk ,&while JCN POP2 ( remove mine on first click ) #00 ROT ROT #30 SFT ADD #00 SWP ;world/mines ADD2 STA update-values JMP2r @reveal ( x y -- ) ( start on idle ) .game/started LDZ ,&started JCN DUP2 start &started ( ignore already revealed ) DUP2 get-revealed #00 EQU ,&unrevealed JCN POP2 JMP2r &unrevealed ( ignore flagged ) DUP2 #30 SFT ADD #00 SWP ;world/flags ADD2 LDA #00 EQU ,&unflagged JCN POP2 JMP2r &unflagged ( test if killing ) DUP2 get-mine #00 EQU ,&survive JCN POP2 explode JMP2r &survive open draw-grid draw-progress JMP2r @open ( x y -- ) DUP2 set-revealed STH2 #0800 &loop #00 OVRk ADD2 ;neighbors ADD2 LDA2 STH2kr ROT ADD ROT ROT ADD SWP DUP2 get-revealed ,&continue JCN DUP2 get-value ,&continue JCN DUP2 open-zone &continue POP2 INC GTHk ,&loop JCN POP2 POP2r JMP2r @open-zone ( x y -- ) STH2 #0800 &loop #00 OVRk ADD2 ;neighbors ADD2 LDA2 STH2kr ROT ADD ROT ROT ADD SWP set-revealed INC GTHk ,&loop JCN POP2 STH2r open JMP2r @get-value ( x y -- value ) OVR #08 LTH ,&in-x JCN POP2 #ff JMP2r &in-x DUP #08 LTH ,&in-y JCN POP2 #ff JMP2r &in-y #30 SFT ADD #00 SWP DUP2 ;world/mines ADD2 LDA #00 EQU ,&no-mine JCN POP2 #ff JMP2r &no-mine ;world/values ADD2 LDA JMP2r @get-revealed ( x y -- value ) OVR #08 LTH ,&in-x JCN POP2 #ff JMP2r &in-x DUP #08 LTH ,&in-y JCN POP2 #ff JMP2r &in-y #30 SFT ADD #00 SWP ;world/revealed ADD2 LDA JMP2r @set-revealed ( x y -- ) OVR #08 LTH ,&in-x JCN POP2 JMP2r &in-x DUP #08 LTH ,&in-y JCN POP2 JMP2r &in-y #30 SFT ADD #00 SWP ;world/revealed ADD2 #01 ROT ROT STA JMP2r @update-values ( -- ) #0800 &ver STHk #0800 &hor DUP STHkr ,count-mines-neighbors JSR OVR STHkr #30 SFT ADD #00 SWP ;world/values ADD2 STA INC GTHk ,&hor JCN POP2 POPr #0010 .Screen/x DEO2 .Screen/y DEI2k #0010 ADD2 ROT DEO2 INC GTHk ,&ver JCN POP2 JMP2r @count-mines-neighbors ( x y -- count ) ,&origin STR2 LITr 00 #0800 &loop ( load neighbor ) #00 OVRk ADD2 ;neighbors ADD2 LDA2 ( add positions ) [ LIT2 &origin $2 ] ROT ADD ROT ROT ADD SWP ( incr counter ) ,get-mine JSR STH ADDr INC GTHk ,&loop JCN POP2 STHr JMP2r @get-mine ( x y -- flag ) OVR #08 LTH ,&in-x JCN POP2 #00 JMP2r &in-x DUP #08 LTH ,&in-y JCN POP2 #00 JMP2r &in-y #30 SFT ADD #00 SWP ;world/mines ADD2 LDA JMP2r @count-flags ( -- flags ) LITr 00 #4000 &loop #00 OVR ;world/mines ADD2 LDA STH ADDr #00 OVR ;world/flags ADD2 LDA STH SUBr INC GTHk ,&loop JCN POP2 STHr JMP2r @count-left ( -- mines ) LITr 00 #4000 &loop #00 OVR ;world/mines ADD2 LDA STH #00 OVR ;world/flags ADD2 LDA STH LIT2r 0100 EQU2r ADDr INC GTHk ,&loop JCN POP2 STHr JMP2r ( drawing ) @draw-frame ( x* y* w h -- ) DUP ,&h2 STR ,&h1 STR DUP ,&w2 STR ,&w1 STR DUP2 .Screen/y DEO2 OVR2 .Screen/x DEO2 #01 .Screen/auto DEO ;frame-chrs/tl .Screen/addr DEO2 #81 .Screen/sprite DEO ;frame-chrs/tc .Screen/addr DEO2 [ LIT &w1 $1 ] ,&repeat JSR #02 .Screen/auto DEO ;frame-chrs/tr .Screen/addr DEO2 #81 .Screen/sprite DEO ;frame-chrs/mr .Screen/addr DEO2 [ LIT &h1 $1 ] ,&repeat JSR ( left ) #0008 ADD2 .Screen/y DEO2 .Screen/x DEO2 ;frame-chrs/ml .Screen/addr DEO2 [ LIT &h2 $1 ] ,&repeat JSR #01 .Screen/auto DEO ;frame-chrs/bl .Screen/addr DEO2 #81 .Screen/sprite DEO ;frame-chrs/bc .Screen/addr DEO2 [ LIT &w2 $1 ] ,&repeat JSR ;frame-chrs/br .Screen/addr DEO2 #81 .Screen/sprite DEO JMP2r &repeat #00 &repeat-loop #81 .Screen/sprite DEO INC GTHk ,&repeat-loop JCN POP2 JMP2r @draw-grid ( -- ) #05 .Screen/auto DEO #0010 .Screen/x DEO2 #0040 .Screen/y DEO2 #0800 &ver STHk #0800 &hor #00 OVR STHkr #30 SFT ADD ,get-tile JSR #81 draw-tile INC GTHk ,&hor JCN POP2 POPr #0010 .Screen/x DEO2 .Screen/y DEI2k #0010 ADD2 ROT DEO2 INC GTHk ,&ver JCN POP2 #00 .Screen/auto DEO JMP2r @get-tile ( id* -- sprite* ) ( mine ) .game/dead LDZ #00 EQU ,&alive JCN DUP2 ;world ADD2 LDA #00 EQU ,&no-mine JCN POP2 ;tile-chrs/mine JMP2r &no-mine &alive ( flag ) DUP2 ;world/flags ADD2 LDA #00 EQU ,&no-flag JCN POP2 ;tile-chrs/flagged JMP2r &no-flag ( revealed ) DUP2 ;world/revealed ADD2 LDA ,&no-seen JCN POP2 ;tile-chrs/untouched JMP2r &no-seen ( digits ) ;world/values ADD2 LDA #00 SWP #60 SFT2 ;tile-chrs/digits ADD2 JMP2r @draw-tile ( addr* color -- ) STH .Screen/addr DEO2 STHkr .Screen/sprite DEOk DEO .Screen/x DEI2k #0010 SUB2 ROT DEO2 .Screen/y DEI2k #0008 ADD2 ROT DEO2 STHr .Screen/sprite DEOk DEO .Screen/y DEI2k #0008 SUB2 ROT DEO2 JMP2r @draw-status ( -- ) #05 .Screen/auto DEO #0048 .Screen/x DEO2 #0018 .Screen/y DEO2 ;status-chrs/alive #00 .game/dead LDZ #60 SFT2 ADD2 #81 ,draw-tile JSR #00 .Screen/auto DEO JMP2r @draw-progress ( -- ) #0018 .Screen/x DEO2 #0018 .Screen/y DEO2 #00 count-flags ,draw-display JSR JMP2r @draw-timer ( -- ) #0058 .Screen/x DEO2 #0018 .Screen/y DEO2 .game/timer LDZ2 ,draw-display JSR JMP2r @draw-display ( value* -- ) #05 .Screen/auto DEO DUP2 #0064 DIV2 NIP ,draw-display-char JSR DUP2 #000a DIV2 NIP ,draw-display-char JSR NIP @draw-display-char ( addr* color -- ) #0a ( MOD ) DIVk MUL SUB #00 SWP #60 SFT2 ;digits-chrs ADD2 #85 draw-tile JMP2r ( stdlib ) @mclr ( addr* len* -- ) OVR2 ADD2 SWP2 &loop STH2k #00 STH2r STA INC2 GTH2k ,&loop JCN POP2 POP2 JMP2r @prng-init ( -- ) ( seed ) #00 .DateTime/second DEI #00 .DateTime/minute DEI #60 SFT2 EOR2 #00 .DateTime/hour DEI #c0 SFT2 EOR2 ,prng/x STR2 #00 .DateTime/hour DEI #04 SFT2 #00 .DateTime/day DEI DUP2 ADD2 EOR2 #00 .DateTime/month DEI #60 SFT2 EOR2 .DateTime/year DEI2 #a0 SFT2 EOR2 ,prng/y STR2 JMP2r @prng ( -- number* ) LIT2 &x $2 DUP2 #50 SFT2 EOR2 DUP2 #03 SFT2 EOR2 LIT2 &y $2 DUP2 ,&x STR2 DUP2 #01 SFT2 EOR2 EOR2 ,&y STR2k POP JMP2r @within-rect ( x* y* rect -- flag ) STH ( y < rect.y1 ) DUP2 STHkr INC INC LDZ2 LTH2 ,&skip JCN ( y > rect.y2 ) DUP2 STHkr #06 ADD LDZ2 GTH2 ,&skip JCN SWP2 ( x < rect.x1 ) DUP2 STHkr LDZ2 LTH2 ,&skip JCN ( x > rect.x2 ) DUP2 STHkr #04 ADD LDZ2 GTH2 ,&skip JCN POP2 POP2 POPr #01 JMP2r &skip POP2 POP2 POPr #00 JMP2r ( theme ) @load-theme ( -- ) ;&path .File/name DEO2 #0002 .File/length DEO2 ;&r .File/read DEO2 ;&g .File/read DEO2 ;&b .File/read DEO2 .File/success DEI2 ORA #01 JCN JMP2r LIT2 &r $2 .System/r DEO2 LIT2 &g $2 .System/g DEO2 LIT2 &b $2 .System/b DEO2 JMP2r &path ".theme $1 ( @|assets ) @neighbors ffff 00ff 01ff ff00 0100 ff01 0001 0101 @pointer-icn 80c0 e0f0 f8e0 1000 @tile-chrs &untouched ffff c0c0 c0c0 c0c0 0000 0000 0000 0000 fefc 0000 0000 0000 0001 0303 0303 0303 c0c0 c0c0 c0c0 8000 0000 0000 0000 3f7f 0000 0000 0000 0000 0303 0303 0303 ffff &mine 0001 0117 0f1f 1f7f 0001 0117 0b15 1b7f 0000 00d0 e0f0 f0fc 0100 01d0 e1f0 f1fc 1f1f 0f17 0101 0000 1f1f 0f17 0101 00aa f0f0 e0d0 0000 0000 f1f0 e1d0 0100 01ab &flagged ffff c0c0 c1c1 c1c1 0000 0000 0103 0703 fefc 0000 0000 0000 0001 0303 0303 0303 c1c0 c7cf c0c0 8000 0101 070f 0000 3f7f 0000 c0e0 0000 0000 0303 c3e3 0303 ffff &digits 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0100 0100 0100 0000 0000 0000 0000 0000 0000 0000 00aa 0000 0000 0000 0000 0100 0100 0100 01ab ( 1 ) 0000 0003 0301 0101 0000 0003 0301 0101 0000 0080 8080 8080 0100 0180 8180 8180 0101 0101 0100 0000 0101 0101 0100 00aa 8080 8080 8000 0000 8180 8180 8100 01ab ( 2 ) 0000 001f 1f00 000f 0000 001f 1f00 000f 0000 00f0 f818 18f8 0100 01f0 f918 19f8 1f18 181f 1f00 0000 1f18 181f 1f00 00aa f000 00f8 f800 0000 f100 01f8 f900 01ab ( 3 ) 0000 001f 1f00 001f 0000 001f 1f00 001f 0000 00f0 f818 18f0 0100 01f0 f918 19f0 1f00 001f 1f00 0000 1f00 001f 1f00 00aa f018 18f8 f000 0000 f118 19f8 f100 01ab ( 4 ) 0000 0018 1818 181f 0000 0018 1818 181f 0000 0018 1818 18f8 0100 0118 1918 19f8 0f00 0000 0000 0000 0f00 0000 0000 00aa f818 1818 1800 0000 f918 1918 1900 01ab ( 5 ) 0000 001f 1f18 181f 0000 001f 1f18 181f 0000 00f8 f800 00f0 0100 01f8 f900 01f0 0f00 001f 1f00 0000 0f00 001f 1f00 00aa f818 18f8 f000 0000 f918 19f8 f100 01ab ( 6 ) 0000 000f 1f18 181f 0000 000f 1f18 181f 0000 00f8 f800 00f0 0100 01f8 f900 01f0 1f18 181f 0f00 0000 1f18 181f 0f00 00aa f818 18f8 f000 0000 f918 19f8 f100 01ab ( 7 ) 0000 001f 1f00 0000 0000 001f 1f00 0000 0000 00f0 f818 1838 0100 01f0 f918 1938 0000 0000 0000 0000 0000 0000 0000 00aa 3818 1818 1800 0000 3918 1918 1900 01ab ( 8 ) 0000 000f 1f18 180f 0000 000f 1f18 180f 0000 00f0 f818 18f0 0100 01f0 f918 19f0 0f18 181f 0f00 0000 0f18 181f 0f00 00aa f018 18f8 f000 0000 f118 19f8 f100 01ab @frame-chrs &tl 0000 0000 0000 0000 0000 0000 0000 0303 &tc 0000 0000 0000 0000 0000 0000 0000 ffff &tr 0000 0000 0000 0040 0000 0000 0000 8000 &ml 0000 0000 0000 0000 0303 0303 0303 0303 &mr c0c0 c0c0 c0c0 c0c0 0000 0000 0000 0000 &bl 0001 0000 0000 0000 0200 0000 0000 0000 &bc ffff 0000 0000 0000 0000 0000 0000 0000 &br c0c0 0000 0000 0000 0000 0000 0000 0000 @status-chrs &alive 0007 1f3f 3f7f 7f7f 0007 1820 2040 4044 00e0 f8fc fcfe fefe 00e0 1804 0402 0222 7f7f 7f3f 3f1f 0700 4048 4720 2018 0700 fefe fefc fcf8 e000 0212 e204 0418 e000 &dead 0007 1f3f 3f7f 7f7f 0007 1820 2040 4a44 00e0 f8fc fcfe fefe 00e0 1804 0402 5222 7f7f 7f3f 3f1f 0700 4a40 4728 2018 0700 fefe fefc fcf8 e000 5202 e214 0418 e000 &victory 0007 1f3f 3f7f 7f7f 0007 1820 2040 444a 00e0 f8fc fcfe fefe 00e0 1804 0402 2252 7f7f 7f3f 3f1f 0700 4040 4221 2018 0700 fefe fefc fcf8 e000 0202 4284 0418 e000 @digits-chrs ( 0 ) ffff ffff ffff ffe0 ffc0 a09f 9f9f 9fbf ffff ffff ffff ff07 ff03 05f9 f9f9 f9fd f0ff ffff ffff ffff 9f9f 9f9f 9fa0 c0ff 0fff ffff ffff ffff f9f9 f9f9 f905 03ff ( 1 ) ffc0 a09f 9f9f 9fa0 ffff ffff ffff ffff ff03 07ff ffff ff07 ffff fdf9 f9f9 f9fd 909f 9f9f 9fa0 c0ff ffff ffff ffff ffff 0fff ffff ff07 03ff f9f9 f9f9 f9fd ffff ( 2 ) ffff bf9f 9f9f 9fbf ffc0 e0ff ffff ffe0 ffff ffff ffff ffff ff03 05f9 f9f9 f905 ffff ffff ffff ffff 909f 9f9f 9fa0 c0ff f9f9 f9f9 f9fd ffff 0fff ffff ff07 03ff ( 3 ) ffff bf9f 9f9f 9fbf ffc0 e0ff ffff ffe0 ffff ffff ffff ffff ff03 05f9 f9f9 f905 9f9f 9f9f 9fbf ffff f0ff ffff ffe0 c0ff ffff ffff ffff ffff 09f9 f9f9 f905 03ff ( 4 ) ffc0 e0ff ffff ffff ffff bf9f 9f9f 9fa0 ff03 07ff ffff ffff ffff fdf9 f9f9 f905 9f9f 9f9f 9fa0 c0ff f0ff ffff ffff ffff ffff ffff ff07 03ff 09f9 f9f9 f9fd ffff ( 5 ) ffff ffff ffff ffff ffc0 a09f 9f9f 9fa0 ffff fdf9 f9f9 f9fd ff03 07ff ffff ff07 9f9f 9f9f 9fbf ffff f0ff ffff ffe0 c0ff ffff ffff ffff ffff 09f9 f9f9 f905 03ff ( 6 ) ffc0 e0ff ffff ffff ffff bf9f 9f9f 9fa0 ff03 05f9 f9f9 f9fd ffff ffff ffff ff07 ffff ffff ffff ffff 909f 9f9f 9fa0 c0ff ffff ffff ffff ffff 09f9 f9f9 f905 03ff ( 7 ) ffff bf9f 9f9f 9fa0 ffc0 e0ff ffff ffff ffff ffff ffff ff07 ff03 05f9 f9f9 f9fd 909f 9f9f 9fa0 c0ff ffff ffff ffff ffff 0fff ffff ff07 03ff f9f9 f9f9 f9fd ffff ( 8 ) ffff ffff ffff ffff ffc0 a09f 9f9f 9fa0 ffff ffff ffff ffff ff03 05f9 f9f9 f905 ffff ffff ffff ffff 909f 9f9f 9fa0 c0ff ffff ffff ffff ffff 09f9 f9f9 f905 03ff ( 9 ) ffff ffff ffff ffff ffc0 a09f 9f9f 9fa0 ffff ffff ffff ffff ff03 05f9 f9f9 f905 9f9f 9f9f 9fa0 c0ff f0ff ffff ffff ffff ffff ffff ff07 03ff 09f9 f9f9 f9fd ffff @world &mines $40 &revealed $40 &values $40 &flags $40