-
Notifications
You must be signed in to change notification settings - Fork 8
/
Bank31_fixed_bank.asm
5441 lines (4633 loc) · 313 KB
/
Bank31_fixed_bank.asm
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
990
991
992
993
994
995
996
997
998
999
1000
.ORG $C000
VBLANKS_TO_WAIT_AFTER_RESET = $02
SIZE_OF_SRAM_TO_CLEAR_ON_RESET = WEEK_TO_SKIP_TO - SRAM_START + 1 ; CLEAR SRAM UP skip WEEK
PRIME_NUMBER_FOR_RANDOM_1 = $83
PRIME_NUMBER_FOR_RANDOM_2 = $0D
PRIME_NUMBER_FOR_RANDOM_3 = $11
PPU_BUSY_BITFLAG = $80
;BANK_JUMP_GAME_START = $8000 ; *** can remove later
;BANK_JUMP_DRAW_METATILE_COLLUMN = $8000 ; *** can remove later
; BANK 24
;BANK_JUMP_DO_DRAW_EVENT = $8000 ; *** can remove later
;BANK_JUMP_DRAW_BG_METATILE = $8006
;BANK_JUMP_INIT_SPRITE_SCRIPTS = $8009
;BANK_JUMP_START_CHANGING_PALLETE_TASK = $8012
; BANK_JUMP_DRAW_PLAYER_FACE = $800F
_F{_RESET_CLEAR_RAM
; RESET
RESET_START: ; RESET
LDA #$08 ; SET GENERATE NMI ON VBLANK OF PPUCONTROL == ON
STA NES_PPU_CTRL ;
CLD ; SET DECIMAL MODE TO OFF
SEI ; SET INTERRUPT DISABLE
MMC3_SRAM_CHIP_DISABLE ; DISABLE SRAM AND DENY WRITES
SET_STACK: ;
SET_STACK[loc] FIXED_BANK_STACK_INDEX
LDA #$00 ; CLEAR MEMORY START
STA $00 ;
STA $01 ; SET RAM CLEAR COUNTER = 0
TAY ;
LDX #$08 ; SET NUMBER OF $100 SIZED BANKS TO CLEAR = 8
@reset_clear_ram: ; CLEAR RAM LOOP (0 to $800),SET SPRITES TO OFFSCREEN
STA ($00),Y ;
INY ;
BNE @reset_clear_ram ; DONE FIRST $100? NO->LOOP BACK TO CLEAR RAM LOOP
INC $01 ;
DEX ;
BNE @reset_clear_ram ; ALL DONE NO->LOOP BACK TO CLEAR RAM LOOP
STA $01 ; CLEAR COUNTER
JSR SET_ALL_SPR_OFFSCREEN ; SET SPRITE Y POSITIONS TO OFFSCREEN ()
_F}_RESET_CLEAR_RAM
_F{_RESET_SET_BG_CHR_ENAMBLE_NMI
RESET_SET_IRQ_BG_CHR: ; SET BRG CHR BANK, ENABLE NMI, WAIT FOR PPU TO WARM UP WITH 2 VBLANKS
LDA #$18 ; SET IRQ BRG CHAR BANK
STA IRQ_0_BG_0000 ;
RESET_ENABLE_NMI:
LDA #$00 ; SET GENERATE NMI ON VBLANK OF PPUCONTROL == OFF
STA NES_PPU_CTRL ;
STA NES_PPU_MASK ; SET PPUMASK = DEFAULT
_F}_RESET_SET_BG_CHR_ENAMBLE_NMI
_F{_RESET_WAIT_FOR_VBLANK
RESET_WAIT_FOR_VBLANK_START:
LDX #VBLANKS_TO_WAIT_AFTER_RESET ; SET NUMBER OF V-BLANKS TO WAIT == 2
@vblank_started_chk: ; WAIT FOR VBLANK TO START
LDA NES_PPU_STATUS ; DOES PPUSTATUS = VBLANK STARTED?
BPL @vblank_started_chk ; NO->WAIT FOR VBLANK TO START
_WHILE MINUS ; WAIT FOR VBLANK TO FINISH
LDA NES_PPU_STATUS ; DOES PPUSTATUS = IN VBLANK ?
_END_WHILE
DEX ; VLBANK COUNTER--
BNE @vblank_started_chk ; DONE? NO->WAIT FOR VBLANK STARTED LOOP
_F}_RESET_WAIT_FOR_VBLANK
_F{_RESET_SET_SPR_PAT_TABLE_TURN_ON_BG_SPR
SET_SPR_PATTERN_TABLE:
LDA #$08 ; SET PPUCTRL = SPR PATTERN TABLE ADDR AT $1000
STA NES_PPU_CTRL ;
TURN_ON_SPR_BG: ; TURN ON SPRITES AND BACKGROUND
LDA #$18 ; SET PPUMASK = SHOW SPRITES AND SHOW BACKGROUND
STA NES_PPU_MASK ;
_F}_SET_SPR_PAT_TABLE_TURN_ON_BG_SPR
_F{_RESET_DISABLE_IRQS_SET_VERT_MIRRORING
DISABLE_ALL_IRQS: ; DISABLE ALL IRQS
LDA #$00 ; SET DMC IRQ = DISABLED
STA APU_DMC_IRQ_FREQ ; INTIALIZE DMC CHANNEL REGISTER
LDA #$40 ; CLEAR FRAME INTTERUPT
STA APU_FRAME_COUNTER ;
STA IRQ_DISABLE_MMC3 ; DISABLE MMC3 INTERRUPTS
LDA NES_PPU_STATUS ; CLEAR PPU ADDRESS LATCH
LDA #$10 ; **** THINK THIS IS UNDEEDED****
TAX ;
DUMMY_WRITES_PPU: ; SET MMC3 MIRRORING TO VERTICAL AND CLEAR SRAM $6000-$669B
STA NES_PPU_ADDR ; DUMMY WRITES TO PPUADDR
STA NES_PPU_ADDR ;
EOR #$10 ;
DEX ;
BNE DUMMY_WRITES_PPU ; **** THINK THIS IS UNDEEDED****
RESET_MMC3_VERT:
MMC3_SET_VERT_MIRRORING
_F}_RESET_DISABLE_IRQS_SET_VERT_MIRRORING
_F{_RESET_CLEAR_SRAM_NAMETABLES
sram_addr = LOCAL_7
RESET_CLEAR_SRAM:
MMC3_SRAM_WRITE_ENABLE
LDA #<SIZE_OF_SRAM_TO_CLEAR_ON_RESET ; SET SRAM SIZE TO CLEAR == 0X069B
LDX #>SIZE_OF_SRAM_TO_CLEAR_ON_RESET ;
LDY #<SRAM_START ; SET SRAM START ADDRESS == $6000
STY sram_addr ;
LDY #>SRAM_START ;
JSR CLEAR_RAM ; CLEAR RAM ( [X * 0x100] + A , $44,Y=START ADDRESS)
RESET_MMC3_SRAM_NOT_WRITE:
MMC3_SRAM_WRITE_DISABLE
LDA #$00 ;
STA NES_PPU_MASK ; CLEAR PPUMASK
LDA #>NAMETABLE1_START ; SET PPUADDR REGISTER = $2000
STA NES_PPU_ADDR ;
LDA #<NAMETABLE1_START ; ASLO SET TILE DATA TO 00 = BLANK TILE
STA NES_PPU_ADDR ;
LDX #$10 ; SET NUMBER OF BYTES TO CLEAR = =0XFF0
LDY #$00 ;
RESET_CLEAR_NAMETABLES: ; CLEAR NAMETABLES ($2000-$2FFF), SET PPU MODES
STA NES_PPU_DATA ;
DEY ;
BNE RESET_CLEAR_NAMETABLES ;
DEX ;
BNE RESET_CLEAR_NAMETABLES ;
LDA #%00011110 ; SET BACKGROUND ==ENABLED, SPRITES== ENABLED, NO CLIPPING, COLOR MODE==COLOR
STA SOFT_PPU_MASK ; SAVE IN RAM_PPUMASK
LDA #%10101000 ; SET GENERATE NMI= ON, SPRITE SIZE = 8X16, BG TABLE= $0000, SPRITE TABLE= $1000, INCREMENT ACROSS, NAMETABLE= $2000
STA SOFT_PPU_CTRL ; SAVE IN RAM PPUCTRL
STA NES_PPU_CTRL ; SAVE IN MMC3 PPUCTRL
CLI ;
LDX #$01 ; LOAD 1 FRAME
JSR WAIT_NUM_FRAMES_RESET ; WAIT FOR NUMBER OF FRAMES RESET(X= FRAMES)
LDA #$00 ; SET MMC3 PATTERN TABLE to 1KB CHR BANK at PPU $0000-07FF
STA BANK_SELECT_MMC3 ;
LDA #$18 ; SET MMC3 CHR BANK TO CHR BANK 25
STA BANK_DATA_MMC3 ;
_F}_RESET_CLEAR_SRAM_NAMETABLES
_F{_RESET_SRAM_CORRUPT_CHECK
LENGTH_OF_SRAM_CHECK_TEXT = $07
sram_addr = LOCAL_7
LDX #(LENGTH_OF_SRAM_CHECK_TEXT -1) ; SET SRAM VALUES TO CHECK = 7. 0 indexed
SRAM_CORRUPT_CHECK: ; CHECK FOR SRAM CORRUPTED LOOP
LDA SRAM_CHECK_VAL,X ; DOES SRAM VALUE= CHECK VALUE
CMP CHECK_VAL_TO_SAVE_TO_SRAM,X ;
BNE SRAM_CORRUPTED_CLEAR ;
DEX ; SRAM VALUES TO CHECK--
BPL SRAM_CORRUPT_CHECK ; ALL VALUES CHECKED? NO> LOOP BACK TO CHECK FOR SRAM CORRUPTED LOOP
JSR CALCULATE_CHECKSUM ; CALCULATE SRAM CHECKSUM
CPY SRAM_CHECKSUM ; DOES CURRENT CHECKSUM = LAST CHECKSUM
BNE SRAM_CORRUPTED_CLEAR ; NO-> BRANCH TO SRAM BAD, CLEAR (6000-7FFF), RESET SEASON STATS AND PLAYBOOK
CPX SRAM_CHECKSUM +1 ;
BEQ SRAM_RAND_TO_RAM_RAND ; YES-> BRANCH TO TRANSFER SRAM RANDOMS TO RAM RANDOMS AND START MAIN GAME LOOP TASK
SRAM_CORRUPTED_CLEAR: ; SRAM BAD, CLEAR (6000-7FFF), RELOAD DEFAULT SEASON SRAM DATA
MMC3_SRAM_WRITE_ENABLE
LDA #<$1FFF ; SET SRAM SIZE TO CLEAR == 0X1FFF
LDX #>$1FFF ;
LDY #<SRAM_START ; SET SRAM START ADDRESS == $6000
STY sram_addr ;
LDY #>SRAM_START ;
JSR CLEAR_RAM ; CLEAR RAM ( [X * 0x100] + A , $44,Y=START ADDRESS)
CLEAR_SEASON_STATS_RELOAD_TEAM_DEFAULTS
LDX #CLEAR_SEASON_STATS_BANK ; LOAD BANK26
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
JSR BANK_JUMP_CLEAR_SEASON_INFO ; CLEAR SEASON STATS AND RELOAD TO DEFAULT() *** can use actual addr
JSR BANK_JUMP_RESET_SCHEDULE_RANDOMIZE_ORDER ; CLEAR TEAM PLAYBOOK AND RELOAD TO DEFAULT() *** can use actual addr
MMC3_SRAM_WRITE_ENABLE
@copy_check_value_from_rom_to_sram:
COPY_SOURCE_TO_DEST_Y_INDEX[source_dest_length] CHECK_VAL_TO_SAVE_TO_SRAM, SRAM_CHECK_VAL, LENGTH_OF_SRAM_CHECK_TEXT
MMC3_SRAM_WRITE_DISABLE
SRAM_RAND_TO_RAM_RAND: ; TRANSFER SRAM RANDOMS TO RAM RANDOMS AND START MAIN GAME LOOP TASK
LDA SAVED_RANDOM_1 ; TRANSFER SAVED RAND1 TO RAND1
STA RANDOM_1 ;
LDA SAVED_RANDOM_2 ; TRANSFER SAVED RAND2 TO RAND2
STA RANDOM_2 ;
LDA SAVED_RANDOM_3 ; TRANSFER SAVED RAND3 TO RAND3
STA RANDOM_3
LDA #MAIN_GAME_BANK_1 ; SET TASK0 BANK ADRESS = BANK 17
STA (GAME_MENU_TASK + TASK_BANK)
LDY #<(BANK_JUMP_GAME_START-1) ; SET TASK0 TASK ADDRESS = START GAME MAIN LOOP() *** can use actual addr
LDA #>(BANK_JUMP_GAME_START-1) ;
LDX #GAME_MENU_TASK ; SET TASK INDEX = TASK 0
JSR CREATE_TASK ; CREATE TASK (X= TASK INDEX, Y,A= TASK ADDRESS)
JMP CHECK_TASKS ; CHECK TASKS RUNNING, WAITING, CREATED ()
CHECK_VAL_TO_SAVE_TO_SRAM: ; SRAM CHECK VALUE
.DB "AKIHIKO"
_F}_RESET_SRAM_CORRUPT_CHECK
_F{_NMI_SAVE_REGS_TASK_CHECK ; NMI DONE ONCE PER FRAME
NMI_START: ; NMI (NON-MASKABLE INTERRUPT) ROUTINE
STA NMI_A ; SET NMI_PRESERVE_A = A
STX NMI_X ; SET NMI_PRESERVE_X = X
STY NMI_Y ; SET NMI_PRESERVE_Y = Y
BIT TASK_BUSY_FLAG ; DOES TASK STATUS = BUSY?
BPL NMI_TASK_NOT_BUSY ; NO->NMI TASK NOT BUSY
NMI_TASK_BUSY: ; NMI TASK IS BUSY
LDA #$00 ; SET IRQ SPLIT INDEX = FIRST IRQ SPLIT
STA CUR_IRQ_INDEX ;
LDY CURR_Y_SCROLL ; LOAD Y SCROLL
LDA CURR_Y_SCROLL+1 ;
JSR UPDATE_IRQ_CHR_BANKS_SCROLL_LOC ; UPDATE SCREEN(Y= Y SCROLL, A=IRQ SPLIT SCREEN INDEX)
JMP RETURN_FROM_NMI_TASK_BUSY ; JUMP -> RETURN FROM NMI WITH NO BANK SWAP, RESTORE REGISTERS
NMI_TASK_NOT_BUSY: ; NMI TASK NOT BUSY
SET_SPRITE_DMA SPRITE_DMA_ADDR ; TRANSFER SPRITES VIA DMA
LDA SOFT_PPU_MASK ; SET MMC3_PPUMASK = RAM_PPUMASK
STA NES_PPU_MASK ;
LDA NES_PPU_STATUS ; READ MMC3_PPUSTATUS TO ACKNOWLEDGE INTERUPT
LDA METATILE_HEIGHT ; DOES COLUMN HEIGHT = 0
BEQ NMI_CHECK_PPU_BUFFER_BUSY ; YES->CHECK FOR BUFFER BUSY
LDA #$06 ; SET BANK TO SWAP = $8000 *** COULD USE BUILT IN ROUTINE BUt mayeb faster unrolled
STA BANK_SELECT_MMC3 ;
LDA #DRAW_METATILE_BANK ; SET $8000 BANK TO SWAP TO = BANK 23
STA BANK_DATA_MMC3 ;
JSR BANK_JUMP_DRAW_METATILE_COLLUMN ; DRAW METATILE(A= HEIGHT) *** can use actual addr
JMP UPDATE_BG_AND_SPR_BANKS ; JUMP-> UPDATE PPU CTRL, CHR BANKS, SOUND, GET JOYPAD, UPDATE TASK
_F}_NMI_SAVE_REGS_TASK_CHECK
_F{_NMI_PPU_BUFFER_CHECK_TRANSFER
NMI_CHECK_PPU_BUFFER_BUSY: ; CHECK FOR BUFFER BUSY
BIT PPU_BUFFER_FLAG ; DOES BUFFER TRANSFER STATUS = BUSY
BPL NMI_CHECK_IF_BUFFER_HAS_DATA ; NO-> CHECK IF BUFFER HAS DATA FOR TRANSFER TO PPU
JMP UPDATE_BG_AND_SPR_BANKS ; YES-> UPDATE PPU CTRL, CHR BANKS, SOUND, GET JOYPAD, UPDATE TASK
NMI_CHECK_IF_BUFFER_HAS_DATA: ; CHECK IF BUFFER HAS DATA FOR TRANSFER TO PPU
LDA BG_BUFFER_LENGTH ; IS PPU BUFFER LENGTH = EMPTY
BNE NMI_CHECK_PPU_TRANSFER_DIRECTION ; NO->CHECK FOR TRANSER PPU TO BUFFER OR BUFFER TO PPU
JMP UPDATE_BG_AND_SPR_BANKS ; YES->UPDATE PPU CTRL, CHR BANKS, SOUND, GET JOYPAD, UPDATE TASK
NMI_CHECK_PPU_TRANSFER_DIRECTION: ; CHECK FOR TRANSER PPU TO BUFFER OR BUFFER TO PPU
BMI TRANSFER_PPU_TO_BUFFER ; IS PPU BUFFER STATUS = PPU TO BUFFER? YES->TRANSFER PPU DATA TO BUFFER
TRANSFER_BUFFER_TO_PPU:
LDX #$00 ; SET BUFFER INDEX = BUFFER START
_WHILE NOT_EQUAL ; TRANSFER BUFFER TO PPU LOOP
LDA BG_BUFFER_SEGMENT_LENGTH,X ; DOES CURRENT BUFFER SEGMENT LENGTH = ZERO?
BEQ NMI_BUFFER_TO_PPU_EXIT ; YES->TRANSFER BUFFER TO PPU EXIT
AND #$40 ; SET PPU ADDRESS INCREMENT TYPE (ACROSS/COL = +1 OR DOWN/ROW = +20) FLAG SET = ROW, NOT SET = COL
LOG_SHIFT_RIGHT_4
STA NES_PPU_CTRL ; SAVE IN PPUCTRL
LDA BG_BUFFER_SEGMENT_LENGTH,X ; SET PPU DATA LENGTH = BUFFER LENGTH
AND #$3F ; MASK OUT INCREMENT TYPE FLAG
TAY ;
LDA BG_BUFFER_ADDR+1,X ; Set PPU ADDR = BUFFER ADDR
STA NES_PPU_ADDR ;
LDA BG_BUFFER_ADDR,X ;
STA NES_PPU_ADDR ;
@transfer_segment_loop: ; TRANSFER CURRENT BUFFER DATA SEGMENT TO PPU
LDA BG_BUFFER_DATA,X ; TRANSFER BUFFER DATA TO PPU DATA
STA NES_PPU_DATA ;
INX ; BUFFER INDEX++
DEY ; BUFFER LENGTH--
BNE @transfer_segment_loop ; DONE? NO-> TRANSFER BUFFER DATA TO PPU
INX ; SET TO NEXT BUFFER START
INX ;
INX ;
_END_WHILE ; END OF BUFFER? NO->TRANSFER BUFFER TO PPU LOOP
NMI_BUFFER_TO_PPU_EXIT: ; TRANSFER BUFFER TO PPU EXIT
LDA #$00 ; SET BUFFER LENGTH/TYPE = unlocked, empty
STA BG_BUFFER_DIR_LOCK_STATUS ;
LDA #>PPU_PALLETE_START ; SET PPU ADDRESS TO $3F00 = PAL RAM? * UNEEDED *
STA NES_PPU_ADDR ;
LDA #<PPU_PALLETE_START ;
STA NES_PPU_ADDR ; SET ADDRESS BACK TO 0 FOR RENDERING
STA NES_PPU_ADDR ; SET PPU ADDRESS TO $0000 = PATTERN TABLE?
STA NES_PPU_ADDR ;
JMP UPDATE_BG_AND_SPR_BANKS ; JUMP-> UPDATE PPU CTRL, CHR BANKS
TRANSFER_PPU_TO_BUFFER: ; TRANSFER PPU DATA TO BUFFER
BIT BG_BUFFER_DIR_LOCK_STATUS ; IS BUFFER LOCKED ?
BVS UPDATE_BG_AND_SPR_BANKS ; YES-> UPDATE PPU CTRL, CHR BANKS, SOUND, GET JOYPAD, UPDATE TASK
LDA BG_BUFFER_SEGMENT_LENGTH ; IS BUFFER SEGMENT LENGTH/PPU INC FLAG = 0 = EMPTY
BEQ UPDATE_BG_AND_SPR_BANKS ; YES-> UPDATE PPU CTRL, CHR BANKS, SOUND, GET JOYPAD, UPDATE TASK
LDA #%00001000 ; SET PPUCTRL PPU ADDRESS INCREMENT = GOING DOWN BY ONE ROW
STA NES_PPU_CTRL ;
LDX #$00 ; SET BUFFER INDEX = START
_WHILE NOT_EQUAL ; TRANSFER PPU DATA TO BUFFER LOOP
LDY BG_BUFFER_SEGMENT_LENGTH,X ; DOES CURRENT BUFFER SEGMENT = 0 = EMPTY
BEQ NMI_PPU_TO_BUFFER_EXIT ; YES->PPU TO BUFFER EXIT
LDA BG_BUFFER_ADDR+1,X ; SET PPU ADDRESS TO TRANSFER DATA FROM = BUFFER ADDRESS
STA NES_PPU_ADDR ;
LDA BG_BUFFER_ADDR,X ;
STA NES_PPU_ADDR ;
LDA NES_PPU_DATA ; DUMMY DATA READ
@transfer_segment_loop: ; TRANSFER PPU DATA INTO BUFFER LOOP
LDA NES_PPU_DATA ; STORE PPU DATA INTO BUFFER
STA BG_BUFFER_DATA,X ;
INX ; BUFFER INDEX++
DEY ; NUMBER OF BYTES TO TRANSFER--
BNE @transfer_segment_loop ; DONE? NO-> TRANSFER PPU DATA INTO BUFFER LOOP
INX ; BUFFER INDEX= BUFFER INDEX + OFFSET TO NEXT BUFFER
INX ;
INX ;
_END_WHILE ; LOOP BACK TO TRANSFER PPU DATA TO BUFFERS
NMI_PPU_TO_BUFFER_EXIT: ; PPU TO BUFFER EXIT
LDA #%11000000 ; SET BUFFER STATUS = ppu to buffer ,BUFFER locked
STA BG_BUFFER_DIR_LOCK_STATUS ;
_F}_NMI_PPU_BUFFER_CHECK_TRANSFER
_F{_NMI_UPDATE_BG_SPR_BANKS
UPDATE_BG_AND_SPR_BANKS: ; UPDATE PPU CTRL, CHR BANKS
LDA SOFT_PPU_CTRL ; SET PPU CTRL = SOFT PPU CTRL
STA NES_PPU_CTRL ;
LDA #$00 ; SET IRQ SCREEN SPLIT INDEX = FIRST SPLIT
STA CUR_IRQ_INDEX ;
LDY CURR_Y_SCROLL ; LOAD Y SCROLL LOCATION
LDA CURR_Y_SCROLL+1 ;
JSR UPDATE_IRQ_CHR_BANKS_SCROLL_LOC ; UPDATE SCREEN(Y= Y SCROLL, A=IRQ SPLIT SCREEN INDEX)
@transfer_soft_spr_chr_banks_to_ppu ; TRANSFER SOFT CHR BANKS TO CHR BANKS
LDA SOFT_CHR_1000_BANK ; LOAD SOFT $1000 CHR BANK
LDX #$02 ; SET BANK SELECT MODE =CHR $1000
STX BANK_SELECT_MMC3 ;
STA BANK_DATA_MMC3 ;
INX ; SET BANK SELECT MODE = CHR $1400
LDA SOFT_CHR_1400_BANK ; LOAD SOFT $1400 CHR BANK
STX BANK_SELECT_MMC3 ;
STA BANK_DATA_MMC3 ;
INX ; SET BANK SELECT MODE =CHR $1800
LDA SOFT_CHR_1800_BANK ; LOAD SOFT $1800 CHR BANK
STX BANK_SELECT_MMC3 ;
STA BANK_DATA_MMC3 ;
INX ; SET BANK SELECT MODE =CHR $1C00
LDA SOFT_CHR_1C00_BANK ; LOAD SOFT $1C00 CHR BANK
STX BANK_SELECT_MMC3 ;
STA BANK_DATA_MMC3 ;
LDA SOFT_BANK_SELECT ; SAVE SOFT BANK SELECT IN NMI TEMP
STA NMI_BANK_SELECT ;
LDA SOFT_MODE_8000 ; SET BANK SELECT MODE = $8000 PRG BANK
ORA #$06
STA BANK_SELECT_MMC3 ;
LDA #SOUND_ENGINE_BANK ; SET $8000 PRG BANK = BANK 28
STA BANK_DATA_MMC3 ;
CLI ; CLEAR INTERRUPT
JSR SOUND_ENGINE_START ; DO SOUND UPDATE()
LDA NMI_BANK_SELECT ; RESTORE PREVIOUS SOFT BANK SELECT
STA SOFT_BANK_SELECT
_F}_NMI_UPDATE_BG_SPR_BANKS
_F{_NMI_READ_JOYPAD
READ_JOYPAD_START: ; READ JOYPADS
LDX #$02 ; SET JOYPAD INDEX = PLAYER 2
LDA #TIMES_TO_CHECK_JOYPAD ; SET MAX TIMES TO CHECK JOYPAD = 4
STA JOY_CHECK ;
_WHILE NOT_EQUAL ; JOYPAD READ LOOP
LDA CURR_JOY_RAW-$01,X ; SET LAST JOYPAD BUTTON STATUS = JOYPAD BUTTON STATUS
@strobe_and_reset_num_buttons: ;
STA LAST_JOY ; SAVE LAST JOYPAD READ
STROBE_JOYPAD ;
LDY #NUM_BUTTONS_TO_READ ; SET NUMBER OF BUTTONS TO READ = 8
@joy_read_loop: ; READ BUTTONS LOOP
LDA JOYPAD_1-$01,X ; READ BUTTON
LSR ; SAVE BUTTON IN JOYPAD DATA
ROL TEMP_JOY_DATA ;
AND #$01 ;
ORA TEMP_JOY_DATA ;
STA TEMP_JOY_DATA ;
DEY ; NUMBER OF BUTTONS TO READ--
BNE @joy_read_loop ; ALL BUTTONS READ? NO-> READ BUTTONS LOOP
CMP LAST_JOY ; DOES LAST JOYPAD STATUS = PREVIOUS
BEQ @save_cur_joy_data ; YES-> SAVE BUTTON DATA
DEC JOY_CHECK ; MAX TIMES TO CHECK JOYPAD--
BNE @strobe_and_reset_num_buttons ; CHECKED MAX TIMES? NO->JOYPAD READ LOOP
JMP @check_done_both_joy ; JUMP-> CHECK FOR BOTH JOYPAD READ,SAVE BOTH JOYPAD RAW AND PRESS IF DONE
@save_cur_joy_data: ; SAVE BUTTON DATA
LDA CURR_JOY_RAW-$01,X ; DOES LAST BUTTON VALUE = NEW BUTTON VALUE? YES = PRESS OCCURRED, NO= NO PRESS
EOR TEMP_JOY_DATA ;
AND TEMP_JOY_DATA ;
STA CURR_JOY_PRESS-$01,X ; SET CURRENT PLAYER BUTTON PRESS = NEW JOYPAD PRESS VALUE
LDA TEMP_JOY_DATA ; SET CURRENT PLAYER JOYPAD RAW = NEW JOYPAD RAW VALUE
STA CURR_JOY_RAW-$01,X ;
@check_done_both_joy: ; CHECK FOR BOTH JOYPAD READ,SAVE BOTH JOYPAD RAW AND PRESS IF DONE
DEX ; JOYPAD INDEX--
_END_WHILE ; DONE? NO-> JOYPAD READ LOOP
@or_both_buttons:
LDA JOY_RAW_1 ; SET JOYPAD RAW = JOYPAD 1 RAW || JOYPAD 2 RAW
ORA JOY_RAW_2 ;
STA JOY_RAW_BOTH ;
LDA JOY_PRESS_1 ; SET JOYPAD PRESS = JOYPAD 1 PRESS || JOYPAD 2 PRESS
ORA JOY_PRESS_2 ;
STA JOY_PRESS_BOTH ;
_F}_NMI_READ_JOYPAD
_F{_NMI_UPDATE_RANDOMS_SLOW_MOTION_PAUSE_CHECK
NMI_UPDATE_RANDOM_NUMS: ; UPDATE RANDOM NUMBERS AND CHECK FOR SLOW MOTION/PAUSE ENABLED
JSR UPDATE_ALL_RANDOMS ; UPDATE RANDOM NUMBERS $3B,$3C,$3D()
INC FRAME_COUNTER ; FRAME COUNTER ++
LDA SLOW_MOTION_PAUSE_DEBUG ; IS SLOW MOTION/STOP DEBUG MODE = ENABLED
CMP #$07 ;
BNE @update_tasks ; NO-> JUMP TO UPDATE TASKS
LDA JOY_RAW_1 ; IS P1 RAW = SELECT
AND #SELECT_BUTTON ;
BEQ @update_tasks ; NO-> JUMP TO UPDATE TASKS
BIT JOY_RAW_1 ; LOAD P1 RAW = A?
BMI @pause_gameplay ; IS SELECT+A HELD? YES-> RETURN WITHOUT UPDATING TASKS = PAUSE GAMEPLAY
BVC @update_tasks ; IS B HELD NO-> JUMP TO UPDATE TASKS
LDA FRAME_COUNTER ; SETS GAME SPEED = 50%
AND #$07 ;
BEQ @update_tasks ;
@pause_gameplay: ; RETURN WITHOUT UPDATING TASKS = PAUSE GAMEPLAY
JMP RETURN_FROM_NMI_ENABLE_INT_RESTORE_BANKS ; RETURN FROM NMI TO PREVIOUS 8000/A000 BANKS
@update_tasks: ; JUMP TO UPDATE TASKS
JMP UPDATE_ALL_TASKS ; UPDATE ALL TASKS()
_F}_NMI_UPDATE_RANDOMS_SLOW_MOTION_PAUSE_CHECK
_F{_IRQ ; IRQ ROUTINE 2-3 SCANLINES
IRQ_START: ; IRQ ROUTINE
STA IRQ_A ; SET IRQ_A = A
STX IRQ_X ; SET IRQ_X = X
STY IRQ_Y ; SET IRQ_Y = Y
STA IRQ_DISABLE_MMC3 ; ACKNOWLEDGE IRQ INTERRUPT AND DISABLE IRQS
STA IRQ_ENABLE_MMC3 ; RE-ENABLE IRQS
LDA #$00 ; SET Y SCROLL =0
TAY ;
JSR UPDATE_IRQ_CHR_BANKS_SCROLL_LOC ; UPDATE SCREEN(Y= Y SCROLL, A=IRQ SPLIT SCREEN INDEX)
LDA SOFT_BANK_SELECT ; SET BANK $8000 SELECT = SOFT BANK SELECT
STA BANK_SELECT_MMC3 ;
LDY IRQ_Y ; RESTORE Y FROM IRQ_Y
LDX IRQ_X ; RESTORE X FROM IRQ_X
LDA IRQ_A ; RESTORE A FROM IRQ_A
RTI ; RETURN FROM INTERRUPT
UPDATE_IRQ_CHR_BANKS_SCROLL_LOC: ; UPDATE SCREEN (Y= Y SCROLL, A=IRQ SPLIT SCREEN INDEX)
DEY ; Y SCROLL LOCATION--
AND #$01 ;
ASL ;
STA IRQ_NAMETABLE ;
LDX CUR_IRQ_INDEX ; SET INDEX= CURRENT SPLIT SCREEN INDEX
LDA CURR_IRQ_NAMETABLE,X ; IS VERTICAL SCROLLING SET
CMP #$20 ;
BCS UPDATE_PPU_CTRL_VERT_SCROLL ; YES-> OTHER SPLIT SCREEN (USED DURING TOUCHDOWNS)
STY IRQ_Y_SCROLL ; SAVE Y SCROLL LOCATION
LDA SOFT_PPU_CTRL ; CHECK IF WE'VE REACHED NEXT NAME TABLE IN X OR Y DIRECTION
AND #%11111100 ; UPDATE NAME TABLE ADDRESS IF SO
ORA CURR_IRQ_NAMETABLE,X ;
ORA IRQ_NAMETABLE ;
STA SOFT_PPU_CTRL ;
TAY ;
LDA CURR_IRQ_XSCROLL,X ; SET X SCROLL LOC = SPLIT SCREEN X LOW BYTE
STA NES_PPU_SCROLL ;
LDA IRQ_Y_SCROLL ; SET Y SCROLL LOCATION
STA NES_PPU_SCROLL ;
STY NES_PPU_CTRL ; SET PPUCTRL = SOFT PPU CTRL
JMP UPDATE_BG_CHR_BANKS ; JUMP-> UPDATE BG CHR BANKS
UPDATE_PPU_CTRL_VERT_SCROLL: ; VERTICAL BG SCROLLING
LSR ; SET PPU ADDRESS MODE
LSR ;
LSR ;
LDA SOFT_PPU_CTRL ; SET SOFT PPU CTRL
AND #%11111100 ; RESET NAMETABlE TO $2000
ADC #$00 ;
STA SOFT_PPU_CTRL ;
LDY #$04 ; LOAD NUMBER OF CYCLES TO WAIT
@tiny_wait_loop: ; TINY WAIT LOOP
DEY ; NUMBER OF CYCLES TO WAIT--
BNE @tiny_wait_loop ;
@transfer_irq_addr_to_ppu: ; UPDATE PPU CTRL, PPU ADDR, PPU SCROLL
LDA CURR_IRQ_PPU_ADDR+1,X ; SET PPU ADDRESS = SPLIT SCREEN PPU ADDR
STA NES_PPU_ADDR ;
LDA CURR_IRQ_PPU_ADDR,X ;
STA NES_PPU_ADDR ;
@reset_scroll:
LDA #$00 ; SET CAMERA POSITION OF SPLIT SCREEN = 0,0 (X,Y)
STA NES_PPU_SCROLL ;
STA NES_PPU_SCROLL ;
LDA SOFT_PPU_CTRL ; SET PPU CTRL = SOFT PPU CTRL
STA NES_PPU_CTRL ; SAVE IN PPUCTRL
UPDATE_BG_CHR_BANKS: ; UPDATE BG CHR BANKS
LDY #$00 ; SET BANK SELECT = LOWER BG CHR BANK $0000
STY BANK_SELECT_MMC3 ;
LDA CURR_IRQ_BG_0000,X ; SET $0000 CHR BANK = SPLIT SCREEN $0000 CHR BANK
STA BANK_DATA_MMC3 ;
INY ; SET BANK SELECT = BG CHR BANK $0800
STY BANK_SELECT_MMC3 ;
LDA CURR_IRQ_BG_0800,X ; SET $0800 CHR BANK = SPLIT SCREEN $0800 CHR BANK
STA BANK_DATA_MMC3 ;
CPX #$0F ; DOES CURRENT SPLIT SCREEN INDEX = LAST CURRENT SPLIT SCREEN INDEX
BCS DISABLE_IRQ_REMAINDER_FRAME ; YES-> SPLIT SCREENS EXIT()
LDA CURR_IRQ_COUNTER,X ; LOAD IRQ SPLIT COUNTER
BEQ DISABLE_IRQ_REMAINDER_FRAME ; EQUAL ZERO? Y-> SPLIT SCREENS EXIT()
STA IRQ_COUNTER_MMC3 ; SAVE IRQ COUNTER VALUE TO BE RELOADED ON NEXT SCANLINE
STA IRQ_RELOAD_MMC3 ; CLEAR IRQ COUNTER AND SET IRQ RELOAD FLAG = TRUE
STA IRQ_ENABLE_MMC3 ; ENABLE INTERRUPT
LDA CUR_IRQ_INDEX ; = CURRENT IRQ SPLIT INDEX
CLC ;
ADC #$05 ; + OFFSET TO NEXT IRQ SPLIT
STA CUR_IRQ_INDEX ;
RTS ; RETURN
DISABLE_IRQ_REMAINDER_FRAME: ; SPLIT SCREENS EXIT()
STA IRQ_DISABLE_MMC3 ; ACKNOWLEDGE INTERRUPT
LDA #$FF ; SET CURRENT IRQ SPLIT INDEX = DONE
STA CUR_IRQ_INDEX ;
RTS ; RETURN
_F}_IRQ
_F{_DISABLE_INTERRUPTS_UPDATE_PPUCTRL
DISABLE_INTERRUPTS_RENDERING: ; DISABLE NMI, DISABLE MMC3 INTERRUPTS, TURN OFF RENDERING
STA IRQ_DISABLE_MMC3 ; DISABLE MMC3 INTERRUPTS
LDA SOFT_PPU_CTRL ; SET SOFT_PPUCTRL = DISABLE NMI
AND #%01111111 ;
STA NES_PPU_CTRL ; SAVE IN PPUCTRL
LDA SOFT_PPU_MASK ; SET SOFT_PPUMASK = DONT SHOW SPRITES AND DONT SHOW BACKGROUND
AND #%11100111 ;
STA NES_PPU_MASK ; SAVE IN PPUMASK
RTS ; RETURN
UPDATE_PPUCTRL: ; UPDATE PPUCTRL()
LDA SOFT_PPU_CTRL ; SET PPUCTRL = SOFT_PPUCTRL
STA NES_PPU_CTRL ; SAVE IN PPUCTRL
RTS ; RETURN
_F}_DISABLE_INTERRUPTS_UPDATE_PPUCTRL
_F{_DRAW_SCRIPT_BALL_MOVEMENT_FUNCTIONS ; START CUTSCENES, MENUS, BALL ANIMATION, BLINK STARTER
END_OLD_SCENE_DRAW_NEW_SCENE: ; START DRAWING TASK (A= DRAW EVENT, X = BANK)
STA DRAW_SCRIPT_ID ; SAVE DRAW EVENT INDEX IN C2
STX DRAW_SCRIPT_BANK ; SAVE DRAW COMMANDS BANK IN C3
LDA #DRAW_SCRIPT_PROCESSING_BANK ; SET TASK 2 BANK = BANK 24
STA (DRAW_SCRIPT_TASK + TASK_BANK )
LDY #<(BANK_JUMP_DO_DRAW_EVENT_THEN_END_DRAW_TASKS-1) ; *** can use actual addr
LDA #>(BANK_JUMP_DO_DRAW_EVENT_THEN_END_DRAW_TASKS-1)
LDX #DRAW_SCRIPT_TASK ; SET TASK INDEX =TASK 2 = DRAW TASK
JSR CREATE_TASK ; CREATE TASK (X= TASK INDEX, Y,A= TASK ADDRESS)
RTS ; RETURN
DRAW_SCENE_UNTIL_ENDED: ; START DRAWING TASK AND DO UNTIL THREAD DESTROYED (A= SCREEN ID, X = BANK)
JSR END_OLD_SCENE_DRAW_NEW_SCENE ; START DRAWING TASK (A= DRAW EVENT INDEX, X = BANK)
@check_draw_script_task_killed: ; CHECK FOR DRAW TASK DESTROYED
RETURN_1_FRAME
LDA (DRAW_SCRIPT_TASK+TASK_STATUS) ; DOES DRAW TASK (TASK 2) STATUS = EMPTY
BNE @check_draw_script_task_killed: ; NO-> LOOP BACK TO CHECK FOR DRAW TASK DESTROYED
RTS ; RETURN
DRAW_SCENE_RETURN_PREV_8000_BANK: ; DO DRAWING TASK SWAP $A000 BANKS AND SET TO 8X8 TEXT (A= SCREEN ID, X = BANK)
STA DRAW_SCRIPT_ID ; SAVE SCREEN ID
STX DRAW_SCRIPT_BANK ; SET BANK = SCREEN SCRIPT BANK
LDA SOFT_8000_BANK ; SAVE CURRENT $8000 BANK
PHA ;
LDX #DRAW_SCRIPT_PROCESSING_BANK ; LOAD BANK 24
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
LDA DRAW_SCRIPT_ID ; LOAD SCREEN ID
LDX DRAW_SCRIPT_BANK ;
JSR BANK_JUMP_DO_DRAW_EVENT ; DO DRAW EVENT() *** can use actual addr
PLA ; RESTORE PREVIOUS $8000 BANK
TAX ;
JMP SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
DRAW_4X4_METATILE_BG: ; DRAW 4X4 METATILE BG
STA DRAW_SCRIPT_ID ; SET DRAW EVENT INDEX
LDA SOFT_8000_BANK ; SAVE CURRENT $8000 BANK TO STACK
PHA ;
LDX #DRAW_SCRIPT_PROCESSING_BANK ; LOAD BANK 24
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
LDA DRAW_SCRIPT_ID ;
LDX #$00 ; SET NAME TABLE =$2000?
JSR BANK_JUMP_DRAW_BG_METATILE ; DRAW 4X4 METATILES BG() *** can use actual addr
PLA ;
TAX ;
JMP SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
L_C3DD: ; *** UNUSED
STA $C5 ;
LDA #$01 ;
STA $C4 ;
DRAW_SPRITE_SCRIPT_NAMETABLE_0: ; DRAW LOGO AND FACEMASK
LDA #>$C300 ; *** awkward way to do it
STA $C2 ;
LDA #<$C300 ;
STA $C3 ;
LDA SOFT_8000_BANK ; SAVE CURRENT $8000 BANK TO STACK
PHA ;
LDX #DRAW_SCRIPT_PROCESSING_BANK ; LOAD BANK 24
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
JSR BANK_JUMP_INIT_SPRITE_SCRIPTS ; DO DRAW LOGO AND FACEMASK() *** can use actual addr
PLA ;
TAX ; RESTORE PREVIOUS $8000 BANK
JMP SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
BANK_SWAP_DO_BLINKING_PALLETE: ; BLINK OFFENSIVE STARTER SELECTED IN IMAGE
TAY ;
LDA SOFT_8000_BANK ; SAVE CURRENT $8000 BANK TO STACK
PHA ;
LDX #DRAW_SCRIPT_PROCESSING_BANK ; LOAD BANK 24
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
TYA ;
JSR BANK_JUMP_START_CHANGING_PALLETE_TASK ; DO BLINK STARTER SELECTED() *** can use actual addr
PLA ;
TAX ; RESTORE PREVIOUS $8000 BANK
JMP SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
SET_BALL_STATUS_MOVING_START_BALL_TASK: ; SET BALL INFO TO BALL MOVING, START BALL TASK
ORA #BALL_MOVING ; SET BALL INFO TO BALL MOVING
STA BALL_COLLISION ;
LDA #BALL_ANIMATION_BANK ; SET TASK 4 BANK TO BANK 23
STA (BALL_MOVEMENT_TASK + TASK_BANK) ;
LDY #<(BANK_JUMP_START_BALL_ANIMATION-1) ; SET TASK ADDRESS = DO BALL MOVEMENT *** can use actual addr
LDA #>(BANK_JUMP_START_BALL_ANIMATION) ;
LDX #BALL_ANIMATION_BANK ; LOAD TASK PRG BANK #
JSR CREATE_TASK ; CREATE TASK (X= INDEX, Y,A= TASK ADDRESS)
RTS ; RETURN
_F}_DRAW_SCRIPT_BALL_MOVEMENT_FUNCTIONS
_F{_PLAY_SOUND ; SETS NEXT SOUND EFFECT/SONG TO PLAY
PLAY_SOUND: ; LOAD SOUND ID ONCE CURRENT SOUND IS DONE(A= SOUND ID)
TAX
_WHILE ALWAYS ; WAIT FOR SOUND ID TO PLAY = NONE LOOP
LDA SOUND_ID_TO_PLAY ; DOES SOUND ID PLAYING = NONE
BEQ @save_sound_id ; YES-> LOAD SOUND ID
RETURN_1_FRAME
_END_WHILE ; JUMP-> WAIT FOR SOUND ID TO PLAY = NONE LOOP
@save_sound_id: ;
STX SOUND_ID_TO_PLAY ; SAVE NEW SOUND ID IN SOUND ID TO PLAY
RTS ; RETURN
_F}_PLAY_SOUND
_F{_SWAP_DRAW_METATILE_BACKGROUND_COL
SWAP_8000_DRAW_METATILE_RETURN: ; SAVE $8000 BANK AND DO DRAW COLUMN() BANK 23 THEN RETURN
current_8000_bank = LOCAL_2
@save_bank:
LDA SOFT_8000_BANK ; SAVE CURRENT $8000 BANK IN $3F
STA current_8000_bank ;
@do_routine:
LDX #DRAW_METATILE_BANK ; LOAD BANK 23
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
JSR BANK_JUMP_DRAW_METATILE_COLLUMN ; DRAW METATILE()
@restore_bank:
LDX current_8000_bank ; RESTORE CURRENT $8000 BANK
JMP SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
_F}_SWAP_DRAW_METATILE_BACKGROUND_COL
_F{_SWAP_DRAW_PLAYER_FACE
SWAP_8000_DRAW_PLAYER_FACE_RETURN: ; DRAW PLAYER FACE()
TAY ; SAVE FACE ID
LDA SOFT_8000_BANK ; SAVE CURRENT $8000 BANK TO STACK
PHA ;
LDX #DRAW_SCRIPT_PROCESSING_BANK ; LOAD BANK 24
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
TYA ; RESTORE FACE ID
JSR BANK_JUMP_DRAW_PLAYER_FACE ; DRAW PLAYER FACE(A= FACE ID)
PLA ; RESTORE PREVIOUS $8000 BANK AND TRANSFER TO X
TAX ;
JMP SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
_F}_SWAP_DRAW_PLAYER_FACE
_F{_SWAP_8000_BANK_JUMP
jump_addr = LOCAL_7
SWAP_8000_BANK_AND_JUMP_RETURN: ; SWAP $8000 BANK AND JUMP(X,Y= ADDRESS, A= BANK TO SWAP TO)
STY jump_addr ; SAVE ADDRESS TO JUMP TO
STX jump_addr+1 ;
TAX ; SET BANK TO SWAP
LDA SOFT_8000_BANK ; SAVE CURRENT $8000 BANK TO STACK
PHA ;
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
LDA #>(@swap_8000_jump_return) ; SAVE BANK SWAP AND JUMP RETURN TO OLD BANK -1 ON STACK
PHA ;
LDA #<(@swap_8000_jump_return-1) ;
PHA ;
JMP (jump_addr) ; JUMP TO SAVED ADDRESS
@swap_8000_jump_return: ; BANK SWAP AND JUMP RETURN TO OLD BANK
PLA ; RESTORE CURRENT $8000 BANK
TAX ;
JMP SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
_F}_SWAP_8000_BANK_JUMP
_F{_UPDATE_ALL_RANDOMS
UPDATE_ALL_RANDOMS: ; UPDATE RANDOMS 3B,3C,3D()
LDA RANDOM_1 ; = RAND3B + 0x83
CLC ;
ADC #$83 ;
STA RANDOM_1 ;
LDA RANDOM_2 ; = RAND3C + 0x0D +C
ADC #$0D ;
STA RANDOM_2 ;
LDA RANDOM_3 ; = RAND3D + 0x11 +C
ADC #$11 ;
STA RANDOM_3 ;
RTS ; UPDATE RANDOMS RETURN
_F}_UPDATE_ALL_RANDOMS
_F{_LOAD_SPLIT_SCREEN
irq_data_addr = LOCAL_7
LOAD_IRQ_SPLIT_DATA: ; LOAD IRQ SPLIT INFO (5 DATA POINTS)
STY irq_data_addr ; SAVE IRQ DATA RAM ADDRESS in $44,45
STX irq_data_addr+1 ;
STA IRQ_DISABLE_MMC3 ; DISABLE MMC3 INTERRUPTS
LDY #$00 ;
@set_irq_data_length: ; LOAD IRQ SPLIT LOOP
_WHILE NOT_EQUAL
LDX #$04 ; SET SCREEN SPLIT DATA LENGTH = 5
@irq_load_loop:
LDA (irq_data_addr),Y ; STORE SCREEN SPLIT XSCROLL AND SPLIT SCREEN BG CHAR
STA CURR_IRQ_START,Y ;
INY ;
DEX ;
BNE @irq_load_loop ;
@check_done
CPY #$13 ; HAVE WE LOADED ALL IRQS
BCS @load_irq_exit ; YES-> DONE LOADING IRQ SPLIT INFO
LDA (irq_data_addr),Y ; SAVE COUNTER IN IRQ SPLIT COUNTER
STA CURR_IRQ_START,Y ;
INY ; SCREEN SPLIT DATA SET++
TAX ; COUNTER = ZERO?
_END_WHILE ; NO-> LOAD IRQ SPLIT LOOP
@load_irq_exit: ; DONE LOADING IRQ SPLIT INFO
RTS ; RETURN
_F}_LOAD_SPLIT_SCREEN
_F{_GET_SEASON_TEAM_TYPES
GET_P1_SEASON_TEAM_TYPE: ; LOAD P1 SEASON TEAM TYPE (SKP, MAN COA, COM) NOT USED?
LDX P1_TEAM ; LOAD P1 TEAM
LDA TEAM_TYPE_SEASON,X ; LOAD TEAM TYPE
AND #$03 ; MASK OUT UNEEDED INFO
RTS ; RETURN
GET_P2_SEASON_TEAM_TYPE: ; LOAD P2 SEASON TEAM TYPE (SKP, MAN COA, COM) NOT USED?
LDX P2_TEAM ; LOAD P2 TEAM
LDA TEAM_TYPE_SEASON,X ; LOAD TEAM TYPE
AND #$03 ; MASK OUT UNEEDED INFO
RTS ; RETURN
_F}_GET_SEASON_TEAM_TYPES
_F{_CHECKSUM_FUNCTIONS ; *** fix magic number references
sram_addr = LOCAL_1
sram_size = LOCAL_3
temp_check_sum = LOCAL_7
CHECK_SUM_CONSTANT = $3412
SIZE_OF_SEASON_INFO_PART_ONE = EMPTY_SEASON_INFO - TEAM_SEASON_INFO_START
GET_SAVE_CHECKSUM: ; CALCULATE AND STORE SRAM CHECKSUM
JSR CALCULATE_CHECKSUM ; CALCULATE SRAM CHECKSUM(), RET= CHECKSUM= Y,X
STY SRAM_CHECKSUM ; SAVE CHECKSUM
STX SRAM_CHECKSUM+1 ;
RTS ; RETURN
CALCULATE_CHECKSUM: ; CALCULATE SRAM CHECKSUM(), RET= CHECKSUM= Y,X
LDA #$00 ; CLEAR CHECK SUM VARIABLES
STA temp_check_sum ;
STA temp_check_sum +1 ;
LDA #<SEASON_INFO_START ; SET SRAM START ADDRESS == $66C0
STA sram_addr ;
LDA #>SEASON_INFO_START ;
STA sram_addr+1 ; SET SIZE == 0X083E
LDA #<$083E ;
STA sram_size ;
LDA #>$083E ;
STA sram_size+1 ; SUM FROM $66C0 TO $6EFE
JSR @check_sum_add_routine ; ADD ALL LOCATIONS (3E,3F= START ADDRESS, 40,41= LENGTH)
LDA #<TEAM_10_SEASON_INFO ; SET SRAM START ADDRESS == $7002-$7F71
STA sram_addr ;
LDA #>TEAM_10_SEASON_INFO ;
STA sram_addr+1 ;
LDA #<$0F70 ; SET SIZE == 0X0F70
STA sram_size ;
LDA #>$0F70 ;
STA sram_size+1 ; SUM FROM $7002 TO $7F71
JSR @check_sum_add_routine ; ADD ALL LOCATIONS (3E,3F= START ADDRESS, 40,41= LENGTH)
LDA temp_check_sum ; TOTAL + 0x3412
CLC ;
ADC #<CHECK_SUM_CONSTANT ;
TAY ;
LDA temp_check_sum +1 ;
ADC #>CHECK_SUM_CONSTANT ;
TAX ;
RTS ; RETURN
@check_sum_add_routine: ; ADD ALL VALUES (3E,3F= START ADDRESS, 40,41= LENGTH)
LDY #$00 ; SET INDEX = FIRST LOCATION
@add_location: ; ADD VALUES LOOP
LDA (sram_addr),Y ; SUM = SUM + NEXT VALUE
CLC ;
ADC temp_check_sum ;
STA temp_check_sum ;
LDA #$00 ;
ADC temp_check_sum +1 ;
STA temp_check_sum +1 ;
INC sram_addr ; CURRENT ADDRESS ++
BNE @next ;
INC sram_addr+1 ;
@next:
SUBTRACT_16BIT_MEM_BY_ONE sram_size ; ;
ORA sram_size ;
BNE @add_location ; ALL VALUES ADDED? NO-> DD VALUES LOOP
RTS ; RETURN
_F}_CHECKSUM_FUNCTIONS
_F{_DRAW_BANNER_SCORE
DRAW_BANNER_SCORE: ; DRAW BANNER SCORE
LDY #<P1_BANNER_SCORE_PPU_ADDR ; SET P1 SCORE PPU ADDRESS = $206D
LDX #>P1_BANNER_SCORE_PPU_ADDR ;
LDA P1_TOTAL_SCORE ; LOAD P1 TOTAL SCORE
JSR CONVERT_2_DIG_NUM_TILES ; CONVERT SINGLE BYTE NUMBER TO TILES AND SAVE IN BUFFER(A= NUMBER)
LDY #<P2_BANNER_SCORE_PPU_ADDR ;
LDX #>P2_BANNER_SCORE_PPU_ADDR ; SET P2 SCORE PPU ADDRESS = $2070
LDA P2_TOTAL_SCORE ; LOAD P2 TOTAL SCORE
JSR CONVERT_2_DIG_NUM_TILES ; CONVERT SINGLE BYTE NUMBER TO TILES AND SAVE IN BUFFER(A= NUMBER)
LDA (CURRENT_BG_BUFFER_LOC-$02),X ; SHIFT DIGIT OVER IF THERE ARE TWO DIGITS
BNE @banner_score_exit ;
SEC ;
ROR PPU_BUFFER_FLAG ; SET NMI PPU BUFFER STATUS = BUSY
LDA (CURRENT_BG_BUFFER_LOC-$01),X ;
STA (CURRENT_BG_BUFFER_LOC-$02),X ;
LDA #$00 ;
STA (CURRENT_BG_BUFFER_LOC-$01),X ;
LSR PPU_BUFFER_FLAG ; SET NMI PPU BUFFER STATUS = READY
@banner_score_exit: ;
RTS ; RETURN
_F}_DRAW_BANNER_SCORE
_F{_STATS_CPU_SKP_INJURY_SCOREBOARD_ROUTINES
SWAP_AND_DO_SKP_MODE: ; DO SKP MODE STATS()
JSR SAVE_A_X_PREV_BANKS_SWAP_TO_12_13 ; SAVE CURRENT BANKS, SAVE A,X, SWAP TO BANK 12,13()
JSR SIMULATION_SKIP_MODE_SEASON_START ; CALCULATE SKIP MODE STATS()
JMP RETURN_PREVIOUS_8000_A000_BANKS ; SWAP TO PREVIOUS( 8000,A000 BANKS)
SWAP_AND_DO_CPU_PLAY_CALL: ; CPU PLAY CALL
JSR SAVE_A_X_PREV_BANKS_SWAP_TO_12_13 ; SAVE CURRENT BANKS, SAVE A,X, SWAP TO BANK 12,13()
JSR BANK_JUMP_COM_PLAY_CALL_LOGIC_START ; DO COMPLAY CALL LOGIC() *** can replace with actual addr
JMP RETURN_PREVIOUS_8000_A000_BANKS ; SWAP TO PREVIOUS( 8000,A000 BANKS)
CPU_ONSIDE = LOCAL_8
SWAP_AND_CHECK_CPU_ONSIDE: ; CHECK FOR CPU ONSIDE
JSR SAVE_A_X_PREV_BANKS_SWAP_TO_12_13 ; SAVE CURRENT BANKS, SAVE A,X, SWAP TO BANK 12,13()
JSR BANK_JUMP_CHECK_FOR_COM_ONSIDES_KICK ; CHECK FRO CPU ONSIDE() *** can replace with actual addr
ROR ;
STA CPU_ONSIDE ; SAVE CPU PLAY CALL
JMP RETURN_PREVIOUS_8000_A000_BANKS ; SWAP TO PREVIOUS( 8000,A000 BANKS)
SWAP_AND_GET_PLAYER_SEASON_STATS: ; GET SEASON PLAYER STATS()
JSR SAVE_A_X_PREV_BANKS_SWAP_TO_12_13 ; SAVE CURRENT BANKS, SAVE A,X, SWAP TO BANK 12,13()
JSR BANK_JUMP_GET_PLAYER_SEASON_STAT ; GET SEASON PLAYER STATS() *** can replace with actual addr
JMP RETURN_PREVIOUS_8000_A000_BANKS ; SWAP TO PREVIOUS( 8000,A000 BANKS)
SWAP_AND_GET_CURRENT_GAME_STATS: ; GET CURRENT GAME PLAYER STATS()
JSR SAVE_A_X_PREV_BANKS_SWAP_TO_12_13 ; SAVE CURRENT BANKS, SAVE A,X, SWAP TO BANK 12,13()
JSR BANK_JUMP_GET_CURRENT_GAME_STATS ; GET CURRENT GAME() *** can replace with actual addr
JMP RETURN_PREVIOUS_8000_A000_BANKS ; SWAP TO PREVIOUS( 8000,A000 BANKS)
SWAP_AND_ADD_STATS_TO_SEASON_STATS: ; ADD GAME STATS TO SEASON STATS()
JSR SAVE_A_X_PREV_BANKS_SWAP_TO_12_13 ; SAVE CURRENT BANKS, SAVE A,X, SWAP TO BANK 12,13()
JSR BANK_JUMP_ADD_STAT_TO_SEASON_STAT ; TRANSFER IN GAME STATS TO SEASON STATS() *** can replace with actual addr
JMP RETURN_PREVIOUS_8000_A000_BANKS ; SWAP TO PREVIOUS( 8000,A000 BANKS)
SWAP_AND_ADD_STATS_TO_CURRENT_GAME_IF_VALID: ; UPDATE IN GAME STATS
JSR SAVE_A_X_PREV_BANKS_SWAP_TO_12_13 ; SAVE CURRENT BANKS, SAVE A,X, SWAP TO BANK 12,13()
JSR BANK_JUMP_UPDATE_IN_GAME_STATS_WITH_ERROR_CHECK ; UPDATE PLAYER STATS IF VALID(A= PLAYER ID, 6F= P1/P2, X= STAT TO UPDATE) *** can replace with actual addr
JMP RETURN_PREVIOUS_8000_A000_BANKS ; SWAP TO PREVIOUS( 8000,A000 BANKS)
SWAP_AND_ADD_ALL_CURRENT_STATS_TO_SEASON_STATS: ; SAVE STATS IN SRAM AND RETURN TO PREVIOUS BANKS
JSR SAVE_A_X_PREV_BANKS_SWAP_TO_12_13 ; SAVE CURRENT BANKS, SAVE A,X, SWAP TO BANK 12,13()
JSR BANK_JUMP_ADD_ALL_GAME_STATS_TO_SEASON_STATS ; SAVE STATS IN SRAM() *** can replace with actual addr
JMP RETURN_PREVIOUS_8000_A000_BANKS ; SWAP TO PREVIOUS( 8000,A000 BANKS)
temp_x_reg = LOCAL_1
temp_a_reg = LOCAL_2
SAVE_A_X_PREV_BANKS_SWAP_TO_12_13: ; SAVE CURRENT BANKS, SAVE A,X, SWAP TO BANK 12,13()
STA temp_a_reg ; SAVE A,X IN 3E,3F
STX temp_x_reg ;
LDA SOFT_8000_BANK ; SAVE CURRENT 8000 BANK IN $393
STA PREV_8000_BANK_TEMP ;
LDA SOFT_A000_BANK ; SAVE CURRENT A000 BANK IN $394
STA PREV_A000_BANK_TEMP ;
LDX #SIM_LOGIC_STATS_1_BANK ; LOAD BANK 12
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
LDX #SIM_LOGIC_STATS_2_BANK ; LOAD BANK 13
JSR SWAP_A000_BANK ; SWAP $A000 BANK(X= $A000 BANK TO SWAP)
LDA temp_a_reg ;
LDX temp_x_reg ;
RTS ; RETURN
RETURN_PREVIOUS_8000_A000_BANKS: ; SWAP TO PREVIOUS( 8000,A000 BANKS)
LDX PREV_8000_BANK_TEMP ; LOAD PREVIOUS 8000 BANK
JSR SWAP_8000_BANK ; SWAP $8000 BANK(X= $8000 BANK TO SWAP)
LDX PREV_A000_BANK_TEMP ; LOAD PREVIOUS A000 BANK
JSR SWAP_A000_BANK ; SWAP $A000 BANK(X= $A000 BANK TO SWAP)
RTS ; RETURN
SWAP_TO_BANKS_12_13: ; SWAP TO BANKS 12/13 (8000/A000)
LDX #SIM_LOGIC_STATS_1_BANK ; LOAD BANK 12