File: efp.asm

package info (click to toggle)
efp 1.4-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 88 kB
  • ctags: 110
  • sloc: asm: 692; makefile: 37; perl: 23
file content (989 lines) | stat: -rw-r--r-- 20,075 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
; Escape from Pong rev 4
; by Halley's Comet Software
; An Entry into the 2003 MiniGame Compo (http://www.ffd2.com/minigame/)

; rev 1: set interrupt flag, now works on Nintendulator
; rev 2: don't activate bg/spr until in vblank, fixes flicker after death/
;        between levels
; rev 3: released under a BSD license, some clarifications to comments
; rev 4: better speed limiting, added level 13, optimized palette loading,
;        gravity can now be signed

; http://here.is/halleyscomet
; http://hcs.freeshell.org/efp.html

; Copyright (c) 2004 Halley's Comet Software
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions
; are met:
; 1. Redistributions of source code must retain the above copyright
;    notice, this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
;    notice, this list of conditions and the following disclaimer in the
;    documentation and/or other materials provided with the distribution.
; 3. The name of the author may not be used to endorse or promote products
;    derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    processor 6502

VRAMCN0 equ $2000
VRAMCN1 equ $2001
VRAMSTAT equ $2002
SPRADR  equ $2003
SPRIO   equ $2004
VRAMADR equ $2006
VRAMIO  equ $2007
BGPAL   equ $3F00
SPPAL   equ $3F10
PT      equ $0000
NT      equ $2000
AT      equ $23C0
SPRDMA  equ $4014
JOY1    equ $4016
ARENA   equ $0200   ; describes the structure of the arena

#ifndef REVTHRUST
THRUST  equ $000a    ; standard control
#else
THRUST  equ -$000a   ; "intuitive" control (accelerate in direction pressed)
#endif
MAXX_   equ $7c
MAXY_   equ $74
PADLIMX_ equ $0c
PADLIMY_ equ $21

; ********* iNES header (after Joe Nahmias)
;   SEG     header
;   org     $8000-16
; iNES magic
    BYTE    $4e,$45,$53,$1a   ; "NES",$1a

; Number of PRG-ROM blocks
    BYTE $01

; Number of CHR-ROM blocks
    BYTE $00

; ROM control bytes: Horizontal mirroring, no SRAM or trainer, Mapper #0
    BYTE $00, $00

; Padding
    BYTE $00, $00, $00, $00, $00, $00, $00, $00

; *********** DATA SEGMENT

    SEG zero
    org $0000

; Rules for using temp vars:
; 1) only use within a subroutine
; 2) don't expect any subroutine call to leave them unmodified
TEMP    BYTE
TEMP2   BYTE
TEMP3   BYTE
LLCOORDX BYTE
LLCOORDY BYTE
LLCOORDSPEC BYTE
DBX     BYTE    ; drawblock
DBY     BYTE
IBALLX  WORD    ; two bytes for finer control
IBALLY  WORD
IBALLVX WORD
IBALLVY WORD
IGRAV   BYTE    ; gravity y...
IPADDLEX BYTE
IPADDLEY BYTE
BALLCOARSEX BYTE    ; actual sprite pos
BALLCOARSEY BYTE
BALLX   WORD
BALLY   WORD
BALLVX  WORD
BALLVY  WORD
GRAV    BYTE
PADDLEX BYTE
PADDLEY BYTE
PADDLES BYTE    ; speed
INPADDLE BYTE
BALLPX  BYTE    ; previous position
BALLPY  BYTE
CON1    BYTE
DEADFLAG BYTE
LEVFLAG  BYTE
LEVSIZE BYTE
ILLPROPS BYTE
POSTHRUST WORD
NEGTHRUST WORD
MAXX    WORD
MAXY    WORD
LLCOUNT WORD
LLPROPS BYTE
PADLIMX BYTE
PADLIMY BYTE
LASTV

; ************ TEXT SEGMENT
; why is the code segment always called text?

    SEG     text

    org $8000

start
    ; initialize
    cld
    sei
    ldx #$ff    ; init stack
    txs

    ; fill palette
    ldx #[BGPAL >> 8]
    ldy #[BGPAL & $FF]
    jsr setvramadr

    ldy #$07   ; fill all palettes
palloop2
    ldx #$04
palloop
    lda allpalette-1,x
    sta VRAMIO
    dex
    bne palloop
    dey
    bne palloop2

    sty PADDLES ; zero, from above loop

restart_from_level_1
    inc PADDLES
    ; load initialized data into the uninitialized segment
    ldx #$0c
initloadloop
    lda initdata,x
    sta POSTHRUST,x
    dex
    bpl initloadloop

level_start

    lda #$00
    sta VRAMCN0
    sta VRAMCN1

; **************** START LOADLEVEL
loadlevel subroutine
    lda #$00
    tax
    sta DEADFLAG    ; Lazarus mode
    sta LEVFLAG
    sta SPRADR
.loop2
    sta SPRIO       ; clear sprites
    dex
    bne .loop2

    lda #$40    ; end of game
    and LLPROPS
    bne restart_from_level_1

    lda #$20
    and LLPROPS
    bne .leavearena

    lda #$00    ; clear arena
    ldx #$00
.loop
    sta ARENA,x
    dex
    bne .loop

    ; clear VRAM pt,nt,at
    lda #$00
    sta VRAMADR
    sta VRAMADR

    ldy #$30    ; clear $3000 bytes
.ntloop2
    ldx #$00
.ntloop
    sta VRAMIO
    inx
    bne .ntloop
    dey
    bne .ntloop2
.leavearena

    ldy #$00    ; no header
    lda #$10
    and LLPROPS
    bne .skipheader

    ldy #$01
    ldx #$02
.coordloop
    lda (LLCOUNT),y
    lsr
    sta IBALLX+1,x
    lda #$00
    ror
    sta IBALLX,x
    dey
    dex
    dex
    beq .coordloop

    ; these pairs can be copied directly into the registers, same order
    ldy #$08
    ldx #$07
.pairloop
    lda (LLCOUNT),y
    dey
    dex
    sta IBALLVX,x
    bne .pairloop

    ldy #$09
.skipheader
    
ll_arenaloop
    lda (LLCOUNT),y
    sta ILLPROPS
    and #$0f
    asl ; WORD!
    tax
    lda ll_tbl,x
    sta TEMP
    lda ll_tbl+1,x
    sta TEMP+1
    iny ; this restricts a level to 256 bytes
    jmp (TEMP)

ll_hline
    lda #$00    ; X
    sta LLCOORDSPEC
    beq ll_line   ; saving a byte here and there

ll_vline
    lda #$01    ; Y
    sta LLCOORDSPEC
    bne ll_line   ; also always true

ll_end
    sty LEVSIZE

    ; initialize ball and paddle position
    ldx #$0a
.initloop
    lda IBALLX,x
    sta BALLX,x
    dex
    bpl .initloop

; **************** END LOADLEVEL

    jsr initpat

    ; wait a few vblanks
    ldx #$40
vblankwait
    lda VRAMSTAT
    bmi vblankwait
vblankwait2
    lda VRAMSTAT
    bpl vblankwait2
    lda #$1e       ; sprites, bg visible, no clipping (only after 1st vblank!)
    sta VRAMCN1
    dex
    bne vblankwait

    lda #$80        ; vblank interrupt
    sta VRAMCN0

    ; *********** START WAIT LOOP ***********
deadend
    lda DEADFLAG
    bne lev_s
    lda LEVFLAG
    beq deadend

    lda ILLPROPS
    sta LLPROPS
    lda LLCOUNT
    clc
    adc LEVSIZE
    sta LLCOUNT
    lda LLCOUNT+1
    adc #$00
    sta LLCOUNT+1
lev_s
    jmp level_start

    ; *********** END WAIT LOOP ***********

ll_tbl WORD ll_end,ll_hline,ll_vline

ll_line
    lda (LLCOUNT),y
    iny
    tax
    jsr denibbulize
    sta LLCOORDX
    txa
    and #$0F
    sta LLCOORDY

    lda (LLCOUNT),y
    iny
    tax
    tya
    pha         ; y
    txa
    jsr denibbulize
    clc
    adc #$01    ; in level is len-1
    pha         ; len
    txa
    and #$0F
    pha       ; type

ll_lineloop
    ldx LLCOORDX
    ldy LLCOORDY

; write a 2x2 tile in nt and arena
; a = data to write
; x = x coord (screen x / 2)
; y = y coord (screen y / 2)

drawblock subroutine
    pha
    stx DBX
    sty DBY
    sty TEMP
    ldy #$00
    sty TEMP2
    ldy #$04
.multloop
    asl TEMP
    dey
    bne .multloop
    lda TEMP
    sta TEMP3
    asl TEMP
    rol TEMP2
    txa
    ora TEMP3
    tay
    pla
    pha
    sta ARENA,y
    txa
    ora TEMP
    asl
    php
    tay
    lda TEMP2
    plp
    rol
    ora #$20
    tax
    jsr setvramadr
    pla
    pha
    sta VRAMIO  ; write NT byte #0
    sta VRAMIO  ; write NT byte #1
    tya
    clc
    adc #$20
    tay
    txa
    adc #$00    ; in case of carry...
    tax
    jsr setvramadr
    pla
    sta VRAMIO  ; write NT byte #2
    sta VRAMIO  ; write NT byte #3

    ; END OF DRAWBLOCK

    ldx LLCOORDSPEC
    inc LLCOORDX,x
    pla ; type
    tay
    pla ; len
    tax
    dex
    txa
    pha ; len
    tya
    pha ; type
    cpx #$00
    bne ll_lineloop
    pla ; type
    pla ; len
    pla ; y
    tay
    jmp ll_arenaloop

initpat subroutine
    ; fill pattern table (with solid blocks of three colors)
    ; (saved 13 bytes with subs)
    lda #$00
    sta VRAMADR
    sta VRAMADR

    tax
    jsr patblk

    lda #$ff
    jsr patblk

    lda #$00
    ldx #$ff
    jsr patblk

    jsr patblk  ; rely on txa in patblk

    ; write ball graphic to pat tbl
    ldx #$08
chrloop
    lda ballchr-1,x
    sta VRAMIO
    dex
    bne chrloop

    ;ldx #$00   ; x already 0 (from above loop)
    jsr patblkhalf  ; fill in high bytes with zeroes
    rts

; ************************* MAIN LOOP START *********************
mainloop

    ldx #$00
    jsr dimensional_manipulation
    ldx #$02
    jsr dimensional_manipulation

    lda BALLX
    asl
    lda BALLX+1
    rol
    sta BALLCOARSEX
    lda BALLY
    asl
    lda BALLY+1
    rol
    sta BALLCOARSEY

; get controller and accelerate appropriately
; By combining the controller read and acclelerate loops I was able to
; save 20 bytes. The side effect is that the start, a, b, and select buttons
; can be used to accelerate, too.
; When this was before dimensional_manipulation it was possible to
; accelerate through walls

; **************** START CONTROL
control subroutine

    ldy #$00
    ldx #$02

    lda #$01
    sta JOY1
    stx JOY1    ; strobe

.bizzareloop
    pha
    lda JOY1
    and #$01
    beq .notthisway
    lda BALLVX,x
    clc
    adc POSTHRUST,y
    pha
    lda BALLVX+1,x
    adc POSTHRUST+1,y

    ; speed regulation
    ; y: 0=pos, 2=neg
    ;cpy #$02
    ;beq .noposclip
    cmp #$04
    bpl .noupdate
;.noposclip
    ;cpy #$00
    ;beq .nonegclip
    cmp #$fc
    bmi .noupdate
;.nonegclip

    sta BALLVX+1,x
    pla
    sta BALLVX,x
    pha
.noupdate
    pla
.notthisway
    tya
    eor #$02
    tay
    bne .notchgx
    txa
    eor #$02
    tax
.notchgx
    pla
    asl
    bne .bizzareloop


; **************** END CONTROL

    ; Gravity
    ;ldy #$00
    tay  ; zero from above loop
    lda GRAV
    bpl notneg
    dey
notneg
    clc
    adc BALLVY
    sta BALLVY
    tya
    adc BALLVY+1
    sta BALLVY+1

; **************** START ARENAL_PROCESSING
; process collision with arena elements (not adjustible)
arenal_processing subroutine
    lda #$00
    sta TEMP2   ; x collision?
    sta TEMP3   ; y collision?

    lda BALLY+1     ; %01111111->%11110000
    clc
    adc #$02
    asl
    and #$f0
    sta TEMP
    pha ; y coord
    lda BALLX+1     ; %01111111->%00001111
    clc
    adc #$02
    lsr
    lsr
    lsr
    pha ; x coord
    ora TEMP
    tax
    lda ARENA,x
    ; wall type test
    cmp #$00    ; air
    beq .noprob
    cmp #$03    ; killer wall
    bne .notkill
    sta DEADFLAG
.notkill
    pla
    pha
    cmp BALLPX
    beq .noxcollide
    ; The ball has made a transition from one tile to another along the x
    ; axis. *If* there is nothing in the arena in the space (BALLPX,Y) then
    ; there is an edge here and the ball is free to reflect on the x axis.
    ; Current x and y within x reg (from tax; lda ARENA,x;)
    txa
    and #$f0
    sta TEMP
    lda BALLPX
    ora TEMP
    tay
    lda ARENA,y
    bne .noxcollide
    lda #$01
    sta TEMP2   ; yes, there has been an x collision
.noxcollide
    pla
    tay
    pla
    pha
    cmp BALLPY
    beq .noycollide
    ; ditto, if nothing in (X,BALLPY)
    txa
    and #$0f
    sta TEMP
    lda BALLPY
    ora TEMP
    tax
    lda ARENA,x
    bne .noycollide
    lda #$02
    sta TEMP3   ; yes, there has been a y collision
.noycollide
    tya
    pha

    lda TEMP2
    pha
    ora TEMP3
    bne .noconcave  ; if neither, do both (concave corner)
    pla
    lda #$02
    pha
    sta TEMP3
.noconcave
    pla
    jsr bouncer
.noprob
    pla
    sta BALLPX
    pla
    sta BALLPY
; **************** END ARENAL_PROCESSING

; **************** START DRAWBALL
drawball subroutine
    lda #$00    ; ball is sprite 0
    sta SPRADR
    lda BALLCOARSEY
    sta SPRIO       ; y coord

    lda #$04
    sta SPRIO       ; tile #

    lda #$20
    sta SPRIO       ; attributes

    lda BALLCOARSEX
    sta SPRIO       ; x coord
; **************** END DRAWBALL

;    lda PADDLEY    ; never used, but good to have on hand
;    cmp #$ff
;    bne dopaddle
;    jmp nopaddle
dopaddle

; **************** START DRAWPADDLE
; not only draw paddle but also do processing
drawpaddle subroutine
    ldx PADDLEY
    lda BALLCOARSEY
    sec
    sbc PADDLEY

    bcc .less
    cmp #$07
    bcc .less
    cmp #$10
    bcc .noproblem
    txa
    clc
    adc PADDLES
    jmp .lessend
.less
    txa
    sec
    sbc PADDLES
.lessend
    sta PADDLEY
.noproblem

    ldy #$04
    lda PADDLEY
.loop
    sta SPRIO       ; y
    clc
    adc #$08
    ldx #$01
    stx SPRIO       ; tile #
    ldx #$00
    stx SPRIO       ; atr
    ldx PADDLEX
    stx SPRIO       ; x
    dey
    bne .loop

; **************** END DRAWPADDLE

; **************** START PADELIC_PROCESSING
; process collision with paddle
; x = offset of paddle to consider
padelic_processing subroutine

    ldx #$01
    ldy #$00
.loop
    lda BALLCOARSEX,x
    clc
    adc #$05
    sec
    sbc PADDLEX,x
    sta TEMP,x
    bcc .notin  ; above
    cmp PADLIMX,x
    bcs .notin  ; below
    dex
    bpl .loop

    lda INPADDLE
    sta DEADFLAG

    lda #$01
    jsr bouncer ; x collision
    ldy #$01
.notin
    sty INPADDLE

; **************** END PADELIC_PROCESSING

nopaddle

    lda #$00
    sta VRAMADR
    sta VRAMADR
    rti

; ************************* MAIN LOOP END *********************

; Draw a block in pat tbl
; a = low byte
; x = high byte
patblk subroutine
    clc ; carry flag used to alternate between low and high byte
ploop2
    ldy #$08
ploop
    sta VRAMIO
    dey
    bne ploop
    bcs pend
patblkhalf
    txa
    sec
    bcs ploop2 ; always true
pend
    rts

; Many of these manipulations can be applied anywhere in memory...
; It would be easy (and space-efficient) to add another ball.
; Two players?

; applys velocity
; x = which dimension (0=x,2=y)

dimensional_manipulation subroutine
    lda BALLVX,x
    clc
    adc BALLX,x
    sta BALLX,x
    lda BALLVX+1,x
    adc BALLX+1,x
    sta BALLX+1,x

    bvs .offscr
    bmi .offscr

    cmp MAXX,x

    bmi dmend
.offscr
    lda #$01    ; set level flag
    sta LEVFLAG
dmend
    rts

; x = dimension to reflect across (0=x, 2=y)
dm_reflect
    sec
    lda #$0
    sbc BALLVX,x
    sta BALLVX,x
    lda #$0
    sbc BALLVX+1,x
    sta BALLVX+1,x
    rts

bouncer subroutine
    beq .nox
    ldx #$00
    jsr dm_reflect
    ldx #$00
    jsr dimensional_manipulation
.nox
    ldx TEMP3
    beq .noy
    jsr dm_reflect ;TEMP3 set to $02 when active
    ldx #$02
    jsr dimensional_manipulation
.noy
    rts

; x = adr hi
; y = adr lo

setvramadr subroutine
    stx VRAMADR
    sty VRAMADR
    rts

denibbulize subroutine
    and #$f0
    lsr
    lsr
    lsr
    lsr
    rts

ballchr

    BYTE %00000000
    BYTE %00011000
    BYTE %00111100
    BYTE %01111110
    BYTE %01111110
    BYTE %00111100
    BYTE %00011000
    BYTE %00000000

; level format:
; 0x00: Initial X coordinate (actual screen coord)
; 0x01: Initial Y coordinate (actual screen coord)
; 0x02-0x03: Initial X velocity
; 0x04-0x05: Initial Y velocity
; 0x06: gravity (signed)
; 0x07: Paddle initial x
; 0x08: Paddle initial y
; 0x09-....: arena specification

; arena commands:
; 0x?0: end of level data (?=properties of next level)
;       bit 0: 0 = use new header; 1 = use previous header (this has none)
;       bit 1: 0 = clear arena; 1 = use old arena
;       bit 2: 1 = end of game!
; 0x01: draw horizontal line
;       parameters: Initial x coordinate (NIBBLE) (2x2 tile fmt)
;                   Initial y coordinate (NIBBLE) (2x2 tile fmt)
;                   Length-1 (NIBBLE) (2x2 tile fmt)
;                   Type (NIBBLE) (color/type to draw in)
; 0x02: draw vertical line
;       parameters: Initial x coordinate (NIBBLE) (2x2 tile fmt)
;                   Initial y coordinate (NIBBLE) (2x2 tile fmt)
;                   Length-1 (NIBBLE) (2x2 tile fmt)
;                   Type (NIBBLE) (tile # to use in drawing)

level
; level 1 (easy)
 BYTE $80,$60
 WORD -$0100,$0080
 BYTE $00
 BYTE $10,$50
 BYTE $01,%00000000,%11110001
 BYTE $01,%00001110,%11110001
 BYTE $02,%11110000,%11100001
 BYTE $30
; level 2 (small hole, trickier)
 BYTE $02,%00000010,%11000001
 BYTE $30
; level 3 (small hole in wall of death)
 BYTE $02,%00000010,%10110011
 BYTE $30
; level 4 (larger hole in wall of death, but in middle (no banking))
 BYTE $02,%00000001,%00000011
 BYTE $02,%00000111,%00010000
 BYTE $30
; level 5 (small hole in wall of death (pretty hard!))
 BYTE $02,%00001000,%00000011
 BYTE $20 ; new header
; level 6 (new experience: gravity)
 BYTE $12,$60
 WORD $0100,$0000
 BYTE $08
 BYTE $e8,$00
 BYTE $02,%00000000,%11100001
 BYTE $02,%11110001,%00000000
 BYTE $30
; level 7 (gravity w/ killer floor (pretty hard!))
 BYTE $01,%00011110,%11010011
 BYTE $30
; level 8 (killer floor higher up)
 BYTE $01,%00011000,%11010011
 BYTE $30
; level 9 (exit in line w/ killer floor)
 BYTE $01,%11101000,%00010000
 BYTE $01,%11110001,%00000001
 BYTE $30
; level 10 (tighter, but with killer floor mostly covered...)
 BYTE $01,%00010010,%11010011
 BYTE $01,%00010111,%10110001
 BYTE $30
; level 11 (w/ a small killer patch)
 BYTE $01,%00110111,%00010011
 BYTE $30
; level 12 (and a killer wall sticking up in front) (really hard!)
 BYTE $02,%01000101,%00010011
; BYTE $40
 BYTE $20
; level 13 (grav reversed and lower) (ultra hard!)
 BYTE $12,$60
 WORD $0100,$0000
 BYTE $FA	; work-around for xa65 problem with -$06
 BYTE $e8,$00
 BYTE $40

; After all levels are exhausted the speed increases. There is no end.

allpalette
    BYTE $16    ; killer walls (red)    ; 0x03
    BYTE $10    ; unused                ; 0x02
    BYTE $20    ; normal walls (white)  ; 0x01
    BYTE $0f    ; background (black)    ; 0x00

initdata
    WORD THRUST
    WORD -THRUST
    WORD MAXX_
    WORD MAXY_
    WORD level
    BYTE 0
    BYTE PADLIMX_
    BYTE PADLIMY_

DSB ($bffa - *)  ; THIS LINE SUPPLIES FILLER!

 WORD mainloop ; NMI
 WORD start ; RESET
 WORD 0     ; THIS LINE SUPPLIES FILLER!

; Outstanding OC Remixes listened to while writing this program:

; Secret of Mana FearOfTheFlava - McVaffe
; Metroid To Brinstar - Avien
; Super Metroid Zebesian Midnight - Vigilante
; DKC2 Assembly line Apparitions - Protrocity
; Castlevania Memblers Reaper - Memblers
; Zelda 64 Gerudo Interlude - djpretzel
; MM4 LetThereBeLight - AmIEvil
; Mega Man Cutman Sonata - McVaffe
; DKC2 Mechanical Swamp - Protrocity
; Final Fantasy 6 Terra In Black - Ailsean
; Final Fantasy 9 Black Magic Synthesis - SysteManiac
; Final Fantasy 7 CidSendsaDreamtotheUnderseaPalace - Star Salzman
; Final Fantasy 4 A Chocobo's Mystic Life - MexieuS
; Final Fantasy 4 Tororian Love Song - silent
; Final Fantasy 4 Rydia (Clean Mix) - Kaijin

; http://www.ocremix.org