-
Notifications
You must be signed in to change notification settings - Fork 3
/
disassembly.asm
3364 lines (2981 loc) · 98.7 KB
/
disassembly.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
; Disassembly of the code of the MSX-1 BOOGA-BOO game.
; Under GNU-GPL by Miguel Colom. See LICENSE file for details.
;
; Disassembly of the original work of Steve & Ann Haigh (Quicksilva).
; -------------------------------------------------------------------
; During play, VDP mode 1 (mode 0, BASIC SCREEN 1, VDP GRAPHIC 1)
; During title, VDP mode 2 (BASIC SCREEN 2, VDP GRAPHIC 2)
; Pulga, Bicho, and plants are sprites
; Include MSX BIOS and system variables definitions
include 'headers/bios.asm'
include 'headers/video.asm'
VDP_VRAM_PORT: equ 0x98
CURSOR_OFFSET_IN_ROW: equ 0xfcb3
CURSOR_ROW: equ 0xfcb4
PLANT_BASE_CHR: equ 0x3F
; Tiles whose value belongs to [0, ..., 24] are not compressed.
; Tiles over 24 are compressed
MAX_WITH_COMPRESSION: equ 24
org 08000h
; *********************************************************************
; * Print the string @DE with white foreground and black background *
; * Used in SCREEN 2 (title) *
; *********************************************************************
PRINT_LOCATE_WHITE:
ld a,COLOR_WHITE_BLACK ;8000
; *********************************************************************
; * Print the string @DE with the color in A at position DE *
; * Used in SCREEN 2 (title) *
; *********************************************************************
PRINT_LOCATE_COLOR:
ld (FORE_AND_BACK_COLORS),a
ld (CURSOR_OFFSET_IN_ROW),hl ;8005
; Print string @DE
l8008h:
ld a,(de) ;8008
inc de ;8009
or a ;800a
ret z ; Return if finished printing
call PRINT_CHAR ;800c
jr l8008h ;800f
; *********************************************************************
; * Print the 5-digit number in HL *
; * Used in SCREEN 2 (title) *
; *********************************************************************
PRINT_NUMBER:
ld de, 10000 ;8011
call PRINT_NUMBER_DIGIT ;8014
ld de, 1000 ;8017
call PRINT_NUMBER_DIGIT ;801a
ld de, 100 ;801d
call PRINT_NUMBER_DIGIT ;8020
ld de, 10 ;8023
call PRINT_NUMBER_DIGIT ;8026
ld a,l ;8029
call PRINT_DIGIT ;802a
xor a ;802d
jp PRINT_DIGIT ;802e
; *********************************************************************
; * Print the digit of the number in HL given the decimal position DE *
; * For example, if HL = 12345 and DE = 100, print '3'. *
; * Used in SCREEN 2 (title) *
; *********************************************************************
PRINT_NUMBER_DIGIT:
; Obtain HL \ DE
xor a ;8031 af .
l8032h:
inc a ;8032 3c <
sbc hl,de ;8033 ed 52 . R
jr nc,l8032h ;8035 30 fb 0 .
add hl,de ;8037 19 .
dec a ;8038 3d =
PRINT_DIGIT:
add a,030h ;8039 Convert digit to ASCII code
; ***********************************************************
; * Print the character given in A in position CURSOR with *
; * foreground/background color in (FORE_AND_BACK_COLORS). *
; * Used in SCREEN 2 (title) *
; ***********************************************************
PRINT_CHAR:
push hl ;803b
push de ;803c
push bc ;803d
ld de,(CGTABL) ; MSX Character Set address in Main-ROM
or a ;8042
jp p,l8049h ;8043
ld de,BOOGABOO_TITLE_PATTERNS ; If A > 127 use addr DE=0x9233 (BOOGA-BOO patterns) instead of DE=CGT
l8049h:
ld l,a ;8049
ld h,000h ; HL = A
add hl,hl
add hl,hl
add hl,hl ; HL = 8*A
add hl,de ; HL = 8*A + CGT. It points to the character definition of A.
; It might use DE=0x9233 instead of CGT.
ld de,(CURSOR_OFFSET_IN_ROW) ; DE = CURSOR
push de ; Save CURSOR
; Have a look at the organization of SCREEN 2 in, for example, the MSX Red Book, Figure 20.
; CURSOR_ROW chooses the row ([0..23])
; CURSOR_OFFSET_IN_ROW is the line offset within the row
;
; For example, if DE = 0x0f68 then CURSOR_ROW = 0x0f = 15 and CURSOR_OFFSET_IN_ROW = 104 (13*8).
; The offset within a row refers to the number of lines.
; Thus, CURSOR = 0x0F68 ==> [X, Y] = [13, 15]
ld bc,00008h ; Copy 8 rows of the character
; Now we have in HL the address of character #A as HL = 8*A + CGT.
; The following call will copy its 8 rows to VRAM to position CURSOR.
call LDIRVM ; Move BC=8 bytes from RAM @HL to VRAM @DE=CURSOR
pop hl ; Recover HL = CURSOR
push hl ; Save CURSOR
; Set HL to the Color Table.
; As pointed out in the MSX Red Book:
; "There is an exact byte-to-byte mapping from the Character Pattern Table to the Colour Table."
; Since the CT start at 0x2000, we need to add 0x20 to H (this is, activating bit 5).
set 5,h ; HL = CURSOR + 0x2000 (CT)
ld a,(FORE_AND_BACK_COLORS) ; Get color in A
ld bc,00008h ; 8062
call FILVRM ; Copy value A BC=8 times to VRAM @HL (fill color)
pop de ; Recover DE = CURSOR
ld hl,00008h ; 8069
add hl,de ; HL = CURSOR + 8 = CURSOR Y, CURSOR_OFFSET_IN_ROW + 8
ld (CURSOR_OFFSET_IN_ROW),hl ; CURSOR_OFFSET_IN_ROW += 8 (increments cursor for next character)
pop bc
pop de
pop hl
ret ;8073
; *******************************************************
; * Wait until a key stroke or joystick trigger pressed *
; *******************************************************
; User when entering the name in the score
WAIT_KEY: ; 8074
ld a,001h
call GTTRIG
or a
ld a,00dh
ret nz ; Joystick trigger pressed
call CHSNS
jr z,WAIT_KEY ; Wait until keyboard not empty...
call BEEP
jp CHGET ; Return pressed key
; *********************************************************************
; * Switch to screen 2. Set back and border colors to black (1) *
; *********************************************************************
SCREEN2:
ld a, COLOR_TRANSPARENT_BLACK
ld (BAKCLR),a
ld (BDRCLR),a
call CHGCLR
call INIGRP ; Screen 2
call SETGRP ; VDP Screen 2
ret
; *********************************************************
; * Write scenario and the plant, if any. *
; * It draws the scenario from (SCROLL_X) and (SCROLL_Y). *
; *********************************************************
WRITE_SCENARIO:
; Input: DE = SCROLL
ld hl,NAME_TABLE ;809a
xor a ;809d
ld (PLANT_IS_VISIBLE),a ;809e Clear presence of plant. It'll be set if any found.
call SETWRT ;80a1 VRAM write in HL == NAME_TABLE = 0x1800
ex de,hl ;80a4 HL = DEo, DE = NAME_TABLE
; DE = 0x1800, HL = 0
ld (SCROLL_X),hl ;80a5 SCROLL = DEo
ld c,l ;80a8 C = SCROLL_X
ld a,h ;80a9 A = SCROLL_Y
; C = SCROLL_X
; A = SCROLL_Y
; It needs to multiply by two because each pointer is 2 bytes long
add a,a ;80aa A = 2*SCROLL_Y
ld h,000h ;80ab
ld l,a ;80ad HL = 2*SCROLL_Y
ld de, GAME_MAP_POINTERS ;80ae
add hl,de ;80b1 HL = GAME_MAP_POINTERS + 2*SCROLL_Y = GAME_MAP_POINTERS[SCROLL_Y]
ld d, 22 ;80b2 D = rows left
l80b4h:
; Using HL as a GAME_MAP_POINTERS pointer (pointer to the rows)
ld a,(hl) ;80b4 A = GAME_MAP_POINTERS[SCROLL_Y]
inc hl ;80b5
ld e,(hl) ;80b6 E = GAME_MAP_POINTERS[SCROLL_Y+1]
inc hl ;80b7
; A, E = two reads of (HL)
; AE = GAME_MAP_POINTERS[SCROLL_Y] (a word)
; A = 8B, E = 96 (this is what's in GAME_MAP_POINTERS). Address 0x968B
push hl ;80b8
ld h,e ;80b9
ld l,a ;80ba HL = EA = GAME_MAP_POINTERS[SCROLL_Y]
ld a,(hl) ;80bb A = *GAME_MAP_POINTERS[SCROLL_Y]. This read a tile
or a ;80bc tile == 0? Termination mark.
jr z,l80d7h ;80bd Yes, get out
ld e,000h ;80bf No
; Skip row data until it reaches the visible start (SCROLL_X)
; It takes into account the codes indicating repetition of blanks (when tile <= MAX_WITH_COMPRESSION)
; Input E: current column (COL)
l80c1h:
ld a,e ;80c1
sub c ;80c2 A = COL - SCROLL_X
jr z,l80deh ;80c3 Done if COL == SCROLL_X
jr nc,l80d3h ;80c5 Jump if COL > SCROLL_X
; Here COL < SCROLL_X
ld a,(hl) ;80c7
inc hl ;80c8 Read tile and increment pointer
inc e ;80c9 next COL
cp MAX_WITH_COMPRESSION ;80ca Is it a compression code?
jr nc,l80c1h ;80cc No, keep skipping
; It's a repetition code
; A: number of repetitions of the blank
dec e ;80ce
add a,e ;80cf A = NUM_DUPS + COL - 1;
ld e,a ;80d0 Add the number of repetitions to the current COL
jr l80c1h ;80d1 Keep iterating...
l80d3h:
ld b, 32 ;80d3 06 20 .
jr l80e6h ;80d5 18 0f . .
l80d7h:
ld b, 32 ;80d7 06 20 .
ld e,b ;80d9 58 X
ld a,02bh ;80da 3e 2b > +
jr loop_write_vram_E_times ;80dc 18 0b . .
; Write a row
l80deh:
ld b, 32 ;80de Columns left
loop_write_HL_vram_B_times:
ld a,(hl) ;80e0
inc hl ;80e1
cp MAX_WITH_COMPRESSION ;80e2
jr nc,tile_write ;80e4 if (HL) <= MAX_WITH_COMPRESSION then tile_write (normal write, no repetitions)
; (HL) <= 24
; This is used the draw the large empty spaces between flying rocks
l80e6h:
ld e,a ;80e6 E = (HL). This is the number of iterations to ...
ld a, ' ' ;80e7 ... write ' '. Compressed data!
; Loop to write the value A to VRAM E times (or when ended, B == 0)
loop_write_vram_E_times:
out (VDP_VRAM_PORT),a ;80e9 Write VRAM
dec b ;80eb
jr z,draw_plant ;80ec DEC B. If B==0 then done. Then draw the plant.
dec e ;80ee
jr nz,loop_write_vram_E_times ;80ef If E != 0 then keep iterating.
jr loop_write_HL_vram_B_times ;80f1 E == 0, then done
tile_write:
out (VDP_VRAM_PORT),a ;80f3
cp PLANT_BASE_CHR ;80f5
jr nz,l8108h ;80f7
ld (PLANT_IS_VISIBLE),a ;80f9 Set PLANT_IS_VISIBLE = PLANT_BASE_CHR
; We've drawn the base of a plan
; It gets the plant column as 32 - cols_left and the
; current row as 22 - rows_left
ld a, 32 ;80fc
sub b ;80fe
ld (PLANT_X),a ;80ff
ld a, 22 ;8102
sub d ;8104
ld (PLANT_Y),a ;8105
l8108h:
djnz loop_write_HL_vram_B_times ;8108
; Draw the plant
draw_plant:
pop hl ;810a Recover HL (current row)
dec d ;810b Decrement plant row
jp nz,l80b4h ;810c If PLANT_Y != current_row, get out. Keep drawing scenario rows
ld d,0c0h ;810f
ld a,(PLANT_IS_VISIBLE) ;8111
or a ;8114
jr z,draw_plants_scroll ;8115
ld hl,(PLANT_X) ;8117
add hl,hl ;811a
add hl,hl ;811b
add hl,hl ;811c ; HL = 8 * PLANT_X
ld a,l ;811d
or a ;811e
; Draw plants with Early Clock if 8 * PLANT_X == 0
jr z,draw_plants_scroll_EC ;811f
ld de,0eefbh ;8121 -18, -5
add hl,de ;8124 19 .
ld (PLANT_X),hl ;8125 22 46 bf " F .
ex de,hl ;8128 eb .
draw_plants_scroll:
; Set position and color of the plants
ld hl,SPRITE_ATTRIBUTE_TABLE + 4*4 ;8129 Sprite #4
call WRITE_DE_VRAM_FROM_HL_INC ;812c Set position
inc hl ;812f Skip sprite pattern
ld a, COLOR_DARK_YELLOW ;8130
jp WRTVRM ;8132 Set color
draw_plants_scroll_EC:
ld de,0ee1bh ;8135 -18, 27
add hl,de ;8138 19 .
ld (PLANT_X),hl ;8139 22 46 bf " F .
ex de,hl ;813c eb .
; Set position and color of the plants
ld hl,SPRITE_ATTRIBUTE_TABLE + 4*4 ;813d Sprite #4
call WRITE_DE_VRAM_FROM_HL_INC ;8140 Set position
inc hl ;8143 Skip sprite pattern
ld a, COLOR_DARK_YELLOW_WITH_EC ;8144
jp WRTVRM ;8146 Set yellow color and activate Early Clock
; *******************************************************
; * Write two bytes (D and E) in VRAM @HL. Increment HL *
; *******************************************************
WRITE_DE_VRAM_FROM_HL_INC: ;8149
ld a,d
call WRTVRM
inc hl
ld a,e
call WRTVRM
inc hl
ret
; ************************************************************************
; * Print the digit of the number in HL given the decimal position DE *
; * For example, if HL = 12345 and DE = 100, print '3'. *
; * It won't write anything to (BC). Since it uses PRINT_STORE_NUMBER_S1 *
; * it sets BC = 0 (in the ROM), which has no effect. *
; * Used in SCREEN 2 (title) *
; ************************************************************************
PRINT_NUMBER_S1: ;8154
ld bc, 0
; *********************************************************************
; * Print the digit of the number in HL given the decimal position DE *
; * For example, if HL = 12345 and DE = 100, print '3'. *
; * It stores the 4 digits in (BC) too. *
; * Used in SCREEN 2 (title) *
; *********************************************************************
PRINT_STORE_NUMBER_S1: ;8157
ld de, 1000 ;8157
call PRINT_STORE_BC_DIGIT_S1 ;815a
ld de, 100 ;815d
call PRINT_STORE_BC_DIGIT_S1 ;8160
ld de, 10 ;8163
call PRINT_STORE_BC_DIGIT_S1 ;8166
ld a,l ;8169
out (VDP_VRAM_PORT),a ;816a
ld (bc),a ;816c
ret ;816d
; **********************************************************************
; * Print the digit of the number in HL given the decimal position DE. *
; * It also stores the digit in @BC in RAM and increments BC. *
; * For example, if HL = 12345 and DE = 100, print '3'. *
; * Used in SCREEN 1 (game). *
; **********************************************************************
PRINT_STORE_BC_DIGIT_S1: ;816eh
xor a
l816fh:
inc a
sbc hl,de
jr nc,l816fh
add hl,de
dec a ; A = HL \ DE
out (VDP_VRAM_PORT),a ; 8176 Write A to VRAM
; Previously the programmer put the characters '0', '1', ... at
; position 0, 1, ... in the CGT. This way they can now simply
; write the number and OUT it to VRAM
ld (bc),a ;8178 Store A in (BC)
inc bc ;8179 Next BC
ret ;817a
DELAY_HL:
dec hl ;817b 2b +
ld a,l ;817c 7d }
or h ;817d b4 .
jr nz,DELAY_HL ;817e 20 fb .
ret ;8180 c9 .
; Simulated jump
; Input HL: length of jump (how many ticks the simulated key is pressed)
SIMULATED_JUMP:
push hl ;8181 e5 .
call STOP_JUMP_ERASE_BAR ;8182 cd d9 8b . . .
pop hl ;8185 e1 .
; Change LD A,0; NOP ;89fc to NOP; LD A,3 (3=jump_right)
; This changes the user input by a jump_right
ld a,003h ;8186 INC BC opcode
ld (l89fch+2),a ;8188 32 fe 89 2 . .
l818bh:
push hl ;818b
call GAME_MOVE_CYCLE ;818c
ld b,06eh ;818f
l8191h:
djnz l8191h ;8191 A small delay
pop hl ;8193
dec hl ;8194 Done tick: decrement
ld a,l ;8195
or h ;8196
jr nz,l818bh ;8197 If not all ticks done, loop
xor a ;8199
ld (l89fch+2),a ;819a Auto-modification: release the jump key
ld hl,00500h ;819d For 500 ticks
l81a0h:
push hl ;81a0 e5 .
call GAME_MOVE_CYCLE ;81a1 cd 12 89 . . .
ld b,06eh ;81a4
l81a6h:
djnz l81a6h ;81a6 Same small delay
pop hl ;81a8
dec hl ;81a9
ld a,l ;81aa
or h ;81ab
jr nz,l81a0h ;81ac If not done, keep looping the key released simulation
ret ;81ae Done
; ***************************************
; * ENTRY POINT *
; ***************************************
; The program starts here
START:
di
ld sp,0ffffh
call ERAFNK ; Erase functionkey display
; Set sprite size to 16x16
ld hl, RG1SAV ; Mirror of VDP register 1 (Basic: VDP(1))
set 1,(hl)
ld b,(hl)
ld c,001h
call WRTVDP
; Reset score table
; 5 entries, with 2 bytes for the record and 14 for the name.
ld hl, SCORE_TABLE
ld b, 5 * (2 + 14)
l81c6h:
ld (hl),000h
inc hl
djnz l81c6h
ld a,003h ;81cb 3e 03 > .
ld (RANDOM_SOUND_BYTE),a ;81cd 32 59 bf 2 Y .
; Print title screen text messages (and BOOGA-BOO with redefined patterns)
; From QUICKSILVA_STR = 0x94DF to 0x95BC (222 bytes)
l81d0h:
ld sp,0ffffh ;81d0 31 ff ff 1 . .
call SCREEN2 ;81d3 cd 88 80 . . .
call CLS_PRINT_SCORE_TABLE ;81d6 cd 61 85 . a .
ld de,QUICKSILVA_STR ;81d9 11 df 94 . . .
ld hl,00018h ;81dc 21 18 00 ! . .
call PRINT_LOCATE_WHITE ;81df cd 00 80 . . .
ld hl,00218h ;81e2 21 18 02 ! . .
ld b,004h ;81e5 Four strings to print
l81e7h:
; Here it prints the big "BOOGA-BOO" title and
; "By Steve & Ann Haigh"
call PRINT_LOCATE_WHITE ;81e7 cd 00 80 . . .
inc h ;81ea 24 $
djnz l81e7h ;81eb 10 fa . .
ld hl,00728h ;81ed 21 28 07 ! ( .
ld a,COLOR_YELLOW_BLACK ;81f0
call PRINT_LOCATE_COLOR ;81f2
ld hl,00a28h ;81f5 21 28 0a ! ( .
ld b,004h ;81f8 Strings to print
l81fah:
; Here it prints "Hit fire button." and the following text
ld a,COLOR_GRAY_BLACK ;81fa
call PRINT_LOCATE_COLOR ;81fc cd 02 80 . . .
inc h ;81ff 24 $
djnz l81fah ;8200 10 f8 . .
ld a,0f0h ;8202 3e f0 > .
ld (TIMEOUT),a ;8204 32 32 bf 2 2 .
; Wait until the space bar or the joystick has been triggered, or a timeout.
; Meanwhile, roll colors in the BOOGABOO title screen
title_screen_wait:
call CHSNS ;8207 cd 9c 00 . . .
jr nz,l823dh ;820a 20 31 1
ld a,001h ;820c 3e 01 > .
call GTTRIG ;820e cd d8 00 . . .
or a ;8211 b7 .
ld a,001h ;8212 3e 01 > .
jr nz, init_game ;8214 User pressed space or trigger. Start game
ld a,(FORE_AND_BACK_COLORS) ;8216
ld hl,PIXELBYTE_COLOUR_TABLE + 0200h ;8219
ld bc,00400h ;821c BC: counter for number of color rotations
title_roll_colors:
add a,010h ;821f Next color
cp 0f1h ;8221
jr nz,l8227h ;8223
ld a,021h ;8225 if color == 241 then color = 33
l8227h:
ld d,a ;8227
call WRTVRM ;8228 Update color in VRAM
inc hl ;822b Next screen position
dec bc ;822c BC -= 1
ld a,b ;822d
or c ;822e
ld a,d ;822f
jr nz,title_roll_colors ;8230 if BC == 0 then keep rolling colors
ld (FORE_AND_BACK_COLORS),a ;8232
ld hl,TIMEOUT ;8235
dec (hl) ;8238
jr z,init_game ;8239 Timeout: start game
jr title_screen_wait ;823b 18 ca . .
l823dh:
call CHGET ;823d
cp 020h ;8240 Space pressed?
ld a,000h ;8242 3e 00 > .
jr nz,title_screen_wait ;8244 20 c1 .
init_game:
; a = 0: keyboard
; a = 1: joystick
; It uses auto-modified code and changes the instructions to take
; into account the keyboard/joystick choice (!)
ld (08955h),a ;8246
ld (08976h),a ;8249
ld (089fbh),a ;824c
ld hl,00000h ;824f 21 00 00 ! . .
ld (SCORE),hl ;8252 22 56 bf " V .
start_game:
ld a,001h ;8255 3e 01 > .
ld (BAKCLR),a ;8257 32 ea f3 2 . .
ld (BDRCLR),a ;825a 32 eb f3 2 . .
call CHGCLR ;825d cd 62 00 . b .
call INIT32 ;8260 cd 6f 00 . o .
call SETT32 ;8263 cd 7b 00 . { .
xor a ;8266 af .
call CLS ;8267 cd c3 00 . . .
ld hl,00000h ;826a 21 00 00 ! . .
call SETWRT ;826d cd 53 00 . S .
ld hl,(SCORE_TABLE) ;8270 2a 5a bf * Z .
ld bc,DECODED_HISCORE ;8273 01 2d 96 . - .
call PRINT_STORE_NUMBER_S1 ;8276 cd 57 81 . W .
ld hl,(SCORE) ;8279 2a 56 bf * V .
ld bc,DECODED_SCORE ;827c 01 24 96 . $ .
call PRINT_STORE_NUMBER_S1 ;827f cd 57 81 . W .
; Set characters
ld hl,(CGTABL) ; MSX Character Set address in Main-ROM
ld de, 48*8 ;8285
add hl,de ;8288 HL = CGT + 48*8
ld de,00000h ;8289
ld bc,00050h ;828c
; LDIRVM: copy BC bytes from HL to VRAM's DE
call LDIRVM ;828f Copy 50h bytes from CGT+48*8 (the numbers) to VRAM's 0 (CGT)
; With this call it can print the number directy by writing the byte number(0, 1, 2, ...) to VRAM
; Set game tiles/characters
ld hl,GAME_TILES ;8292
ld de,00050h ;8295
ld bc,246*8 ;8298
call LDIRVM ;829b Copy 1968 bytes from 0xADC4 to VRAM's 50h (CGT+0x50)
; Set colors
; From http://bifi.msxnet.org/msxnet/tech/tms9918a.txt :
; Each character is 8 x 8. The character number refers to an character pattern in
; the PG, which has 256 characters patterns. Each pattern is 8 bytes, so the
; entire PG is 256 x 8 = 2048 bytes. Each byte is a pixel line of the character
; (top first). If a bit is set, the foreground colour in the CT is shown,
; otherwise the background colour in the CT.
;
; The CT sets the colour of the character. Each byte in the CT sets the colour
; of 8 complete characters, so the CT is 32 bytes. The high four bits set the
; foreground colour, the low the background colour. If either of these is 0,
; it is transparent and the colour of the backdrop (BD) is used. To calculate
; the element in the CT, divide the character number in PN by 8.
ld hl,GAME_COLOR_TABLE ;829e
ld de,CHARACTERS_COLOUR_TABLE ;82a1
ld bc, 32 ;82a4 The CT has 32 bytes
call LDIRVM ;82a7 Copy 32 bytes to VRAM's 2000h (characters color table, CCT) from 0xB674
xor a ;82aa
ld (FORE_AND_BACK_COLORS),a ;82ab
call CLRSPR ;82ae
ld a, COLOR_RED ;82b1
ld hl,SPRITE_ATTRIBUTE_TABLE + 20*4 + 3 ;82b3
call WRTVRM ;82b6 Sprite attribute table 1B00-1B7F
ld a, COLOR_GRAY ;82b9
ld hl, SPRITE_ATTRIBUTE_TABLE + 6*4 + 3 ;82bb
call WRTVRM ;82be Sprite attribute table 1B00-1B7F
; Reset the 16 first sprites
ld hl, SPRITE_CHARACTER_PATTERNS ;82c1
ld bc, 16 * 8 ;82c4 16 sprites, each defined by 8 bytes
ld a, 0xff ;82c7
call FILVRM ;82c9
ld hl, SPRITE_ATTRIBUTE_TABLE ;82cc
ld de,0xb000 ;82cf ; D=0xb0, E=0
ld b,4 ;82d2 4 writes of 2 bytes = 8 writes to SPRITE_ATTRIBUTE_TABLE
l82d4h:
call WRITE_DE_VRAM_FROM_HL_INC ;82d4 cd 49 81 . I .
inc hl ;82d7 23 #
inc hl ;82d8 23 #
djnz l82d4h ;82d9 10 f9 . .
ld hl,02664h ;82db
ld (PULGA_X),hl ;82de Set PULGA_X=100, PULGA_Y = 38
ld a,005h ;82e1
ld (PULGA_ACTION),a ;82e3 PULGA_ACTION = 5 (falling left)
xor a ;82e6 af .
ld (BICHO_THREAT_STATUS),a ;82e7 32 3c bf 2 < .
call DO_ANIM_PLANT_FRAME ;82ea cd ea 88 . . .
call GICINI ;82ed cd 90 00 . . .
ld a,014h ;82f0 3e 14 > .
ld (l8a4eh+1),a ;82f2 32 4f 8a 2 O .
ld a,(RANDOM_SOUND_BYTE) ;82f5 3a 59 bf : Y .
add a,a ;82f8 87 .
ld (SOUND_SNAP),a ;82f9 32 6f 8e 2 o .
ld hl,PELICAN_WALK + 1 ;82fc
ld (PELICAN_POS_PTR),hl ;82ff Point to TY of the first record
; Set ABS_BICHO_X = BICHO_ABS_TARGET_X = 960
ld hl,960 ;8302
ld (ABS_BICHO_X),hl ;8305
ld (BICHO_ABS_TARGET_X),hl ;8308
; Set ABS_BICHO_Y = BICHO_ABS_TARGET_Y = 552
ld hl,552 ;830b
ld (ABS_BICHO_Y),hl ;830e
ld (BICHO_ABS_TARGET_Y),hl ;8311
ld de,00000h ;8314
call WRITE_SCENARIO ;8317
ld (TIMEOUT),a ;831a
; Disable GTSTCK and GTTRIG
ld hl,03e00h ;831d Automodified code: LD A, 0
ld (l8956h),hl ;8320 Changes GTTRIG ;8956 cd d8 00 to 'LD A,0', 'NOP'
ld (l89fch),hl ;8323 Changes GTSTCK ;89fc cd d5 00 to 'LD A,0', 'NOP'
xor a ;8326
ld (l8956h+2),a ;8327 Useless? call GTTRIG ;8956 cd d8 *00*
; This is the series of automatic jumps of Pulga at the beginning
; HL is the number of ticks the jump key is pressed during the simulation
ld hl,00400h ;832a
call SIMULATED_JUMP ;832d
ld hl,00800h ;8330
call SIMULATED_JUMP ;8333
ld hl,00500h ;8336
call SIMULATED_JUMP ;8339
ld hl,00780h ;833c
call SIMULATED_JUMP ;833f
; Enable back GTSTCK and GTTRIG
ld hl,GTSTCK ;8342
ld (l89fch+1),hl ;8345
ld hl,GTTRIG ;8348
ld (l8956h+1),hl ;834b
ld a,0cdh ;834e
ld (l8956h),a ;8350
ld (l89fch),a ;8353
; Set initial depth
ld a,96 ;8356
ld (SCORE_PULGA_DEPTH),a ;8358
ld hl,8000 ; We start with BONUS = 8000
ld (BONUS),hl
; Write the bottom line, slowly while performing GAME_MOVE_CYCLE
; bonus=9999 score=00000 hi=00000
ld hl, NAME_TABLE + 23*32 + 1 ; [1, 23] (row 23, col 1)
ld de,GRAPH_SCORE_LINE ;8364 11 13 96 . . .
l8367h:
ld a,(de) ;8367 Read character of the bottom line
inc de ;8368 Point to next character
inc a ;8369 Done with the line?
jr z,game_loop ;836a If so, start game
; No, not done
dec a ;836c
call WRTVRM ;836d Print character
inc hl ;8370 Next position in the screen
ld b,000h ;8371
l8373h:
push hl ;8373
push de ;8374
push bc ;8375
call GAME_MOVE_CYCLE ;8376
ld b,05ah ;8379
l837bh:
djnz l837bh ;837b Small delay
pop bc ;837d
pop de ;837e
pop hl ;837f
djnz l8373h ;8380 Repeat 255 times from l8373h (the GAME_MOVE_CYCLE)
; It's like a delay
jr l8367h ;8382 Keep printing characters until line done...
; Here it starts the interactive game
game_loop:
call BICHO_CYCLE ;8384 cd 08 86 . . .
call GAME_MOVE_CYCLE ;8387 cd 12 89 . . .
call PLANT_CYCLE ;838a cd d1 88 . . .
ld a,(RESET_PSG_FLAG) ;838d 3a 45 bf : E .
or a ;8390 b7 .
jr z,l839ah ;8391 28 07 ( .
xor a ;8393 af .
ld (RESET_PSG_FLAG),a ;8394 32 45 bf 2 E .
call GICINI ;8397 cd 90 00 . . .
l839ah:
ld a,(PULGA_Y) ;839a
rra ;839d
rra ;839e
rra ;839f A = 8*PULGA_Y
and 01fh ;83a0 only values [0, ..., 31]
ld hl,SCROLL_Y ;83a2
add a,(hl) ;83a5 A = 8*PULGA_Y + SCROLL_Y
cp 15 ;83a6
jr nc,check_new_score ;83a8 Jump if 8*PULGA_Y + SCROLL_Y >= 15
ld b,a ;83aa B = 8*PULGA_Y + SCROLL_Y
ld a,(PULGA_X) ;83ab
rra ;83ae
rra ;83af
rra ;83b0 A = 8*PULGA_X
and 01fh ;83b1 only values [0, ..., 31]
ld hl,SCROLL_X ;83b3
add a,(hl) ;83b6 A = 8*PULGA_X + SCROLL_X
cp 54 ;83b7
ld a,b ;83b9 A = 8*PULGA_Y + SCROLL_Y
jr nc,check_new_score ;83ba Jump if 8*PULGA_X + SCROLL_X >= 54
; Pulga has managed to escape! :D
; Indeed, 8*PULGA_Y + SCROLL_Y < 15 ==> Very high and
; 8*PULGA_X + SCROLL_X < 54 ==> On the left of the map
; Then, pulga escaped!
call PLAY_VIVALDI ;83bc cd 00 8e . . .
ld hl,00000h ;83bf 21 00 00 ! . .
call DELAY_HL ;83c2 cd 7b 81 . { .
call DELAY_HL ;83c5 cd 7b 81 . { .
ld hl, NAME_TABLE + 23*32 + 7 ;83c8 Coord [7, 23]
; Read record from screen
call RDVRM ;83cb Read digit
add a,a ;83ce A = 2*digitA
ld b,a ;83cf B = 2*digitA
add a,a ;83d0
add a,a ;83d1 A = 4*2*digitA = 8*digitA
add a,b ;83d2 A = 8*digitA + 2*digitA = 10*digitA
ld l,a ;83d3
ld h,000h ;83d4 HL = 10*digitA
in a,(VDP_VRAM_PORT) ;83d6 Read digitB
add a,l ;83d8 A = digitB + 10*digitA
ld l,a ;83d9 L = digitB + 10*digitA
add hl,hl ;83da HL = 2*digitB + 20*digitA
ld c,l ;83db C = 2*digitB + 20*digitA
ld b,h ;83dc B = 0
add hl,hl ;83dd HL = 4*digitB + 40*digitA
add hl,hl ;83de HL = 8*digitB + 80*digitA
add hl,bc ;83df HL = 8*digitB + 80*digitA + 2*digitB + 20*digitA =
; = 100*digitA + 10*digitB
in a,(VDP_VRAM_PORT) ;83e0 Read digitC
ld c,a ;83e2 C = digit
l83e3h:
ld b,000h ;83e3
add hl,bc ;83e5 HL = 100*digitA + 10*digitB + digitC
ld bc,(SCORE) ;83e6 BC = SCORE
add hl,bc ;83ea HL = 100*digitA + 10*digitB + digitC + SCORE
ld (SCORE),hl ;83eb Store new score
call SCREEN2 ;83ee
ld de,CONGRATULATIONS_STR ;83f1
ld hl,00a40h ;83f4
call PRINT_LOCATE_WHITE ;83f7 Print "CONGRATULATIONS"
ld hl,00f18h ;83fa
call PRINT_LOCATE_WHITE ;83fd Print "You dit it"
ld b,13 ;8400 13 delays
l8402h:
ld hl,00000h ;8402 21 00 00 ! . .
call DELAY_HL ;8405 cd 7b 81 . { .
djnz l8402h ;8408 10 f8 . .
jp start_game ;840a c3 55 82 . U .
check_new_score:
; It arrives here when pulga reaches a new high score
ld hl,SCORE_PULGA_DEPTH ;840d 21 58 bf ! X .
cp (hl) ;8410
jp nc,l842bh ;8411 Skip score update if SCORE_PULGA_DEPTH <= 8*PULGA_Y + SCROLL_Y
; 8*PULGA_Y + SCROLL_Y (or X) < SCORE_PULGA_DEPTH ==> New record!
ld b,a ;8414
ld a,(hl) ;8415
sub b ;8416 Store height diff. in A
ld (hl),b ;8417 Store new record height
ld c,a ;8418 C = height diff
ld b,000h ;8419
ld hl, NAME_TABLE + 23*32 + 18 ;841b Coord [18, 23] --> Score="..."
call SETWRT ;841e
ld hl,(SCORE) ;8421
add hl,bc ;8424
ld (SCORE),hl ;8425 SCORE = SCORE + diff
call PRINT_NUMBER_S1 ;8428 Update SCORE visualization at [18, 23]
l842bh:
ld a,(JIFFY) ;842b 3a 9e fc : . .
cp 008h ;842e fe 08 . .
jp c,l844dh ;8430 da 4d 84 . M .
xor a ;8433 af .
ld (JIFFY),a ;8434 32 9e fc 2 . .
ld hl, NAME_TABLE + 23*32 + 7 ; [7, 23] row 23, col 7
call SETWRT ;843a cd 53 00 . S .
ld hl,(BONUS)
ld de, 500
rst 20h
jr z,l8447h ; BONUS = 500? If so, don't decrement
dec hl ; Decrement BONUS
l8447h:
ld (BONUS),hl ; Store updated BONUS value
call PRINT_NUMBER_S1 ;844a cd 54 81 . T .
l844dh:
ld a,006h ;844d
call SNSMAT ;844f
bit 5,a ;8452 line #6, bit #5: F1 key
jr nz,l846bh ;8454 Jump if F1 not pressed
; Pause/exit control follows
; Pause while F1 pressed
l8456h:
ld a,006h ;8456
call SNSMAT ;8458
bit 5,a ;845b line #6, bit #5: F1 key
jr z,l8456h ;845d Loop while F1 pressed
ld a,(RANDOM_SOUND_BYTE) ;845f 3a 59 bf : Y .
xor 003h ;8462 ee 03 . .
ld (RANDOM_SOUND_BYTE),a ;8464 32 59 bf 2 Y .
add a,a ;8467 87 .
ld (SOUND_SNAP),a ;8468 32 6f 8e 2 o .
; End game if user pressed ESC
l846bh:
ld a,007h ;846b
call SNSMAT ;846d
bit 2,a ;8470 line #7, bit #2: ESC key
jp z,END_GAME ;8472
bit 4,a ;8475 line #7, bit #4: STOP key
jr nz,l849ch ;8477 Jump if STOP not pressed
; Here STOP has been pressed.
; Wait until the user stops touching...
l8479h:
ld a,007h ;8479
call SNSMAT ;847b
bit 4,a ;847e line #7, bit #4: STOP key
jr z,l8479h ;8480 Loop while STOP pressed
call GICINI ;8482
; Here user touched and released STOP.
; Now wait until STOP is pressed again.
; This pauses the game actually.
l8485h:
ld a,007h ;8485
call SNSMAT ;8487
bit 2,a ;848a line #7, bit #2: ESC key
jp z,END_GAME ;848c
bit 4,a ;848f line #7, bit #4: STOP key
jr nz,l8485h ;8491 Loop until STOP pressed
; Simply wait until user finally releases STOP
l8493h:
ld a,007h ;8493
call SNSMAT ;8495
bit 4,a ;8498 line #7, bit #4: STOP key
jr z,l8493h ;849a Loop while STOP pressed
; Getting out of stop pause
l849ch:
call KILBUF ;849c cd 56 01 . V .
ld a,00dh ;849f 3e 0d > .
ld (REPCNT),a ;84a1 32 f7 f3 2 . .
ld b,028h ;84a4 06 28 . (
l84a6h:
djnz l84a6h ;84a6 10 fe . .
jp game_loop ;84a8 c3 84 83 . . .
; **********************************************************************
; * End of game. *
; * Check if the score if a new records, store it in the table if so. *
; **********************************************************************
END_GAME:
ld sp,0ffffh ;84ab 31 ff ff 1 . .
call GICINI ;84ae cd 90 00 . . .
call SCREEN2 ;84b1 cd 88 80 . . .
ld hl,01388h ;84b4 21 88 13 ! . .
call DELAY_HL ;84b7 cd 7b 81 . { .
ld de,(SCORE) ;84ba ed 5b 56 bf . [ V .
call CHECK_STORE_NEW_RECORD ;84be
jp l81d0h ;84c1 c3 d0 81 . . .
; **********************************************************
; * Check if the current score is the highest in the *
; * table. If so, scan the scores in the table until the *
; * right sorting position is found, move the existing *
; * records down, and ask the users to type their name and *
; * store the new entry. *
; * *
; * Input DE = (SCORE) *
; **********************************************************
CHECK_STORE_NEW_RECORD:
push de ;84c4 d5
; Set sprites invisible
ld a,COLOR_TRANSPARENT_BLACK ;84c5
ld (FORE_AND_BACK_COLORS),a ;84c7
call CLRSPR ;84ca
ld hl,SPRITE_CHARACTER_PATTERNS + 4*1 + 3 ;84cd
ld a,0ffh ;84d0
call WRTVRM ;84d2
pop de ;84d5
ld hl,SCORE_TABLE ;84d6
ld b,005h ;84d9 The score table has 5 entries
l84dbh:
ld c,(hl) ;84db
inc hl ;84dc
ld a,(hl) ;84dd
dec hl ;84de
push hl ;84df
ld l,c ;84e0
ld h,a ;84e1
rst 20h ;84e2 Compare score in table (HL) with given score (DE)
pop hl ;84e3
jr c,l84f2h ;84e4 Jump if DE > HL <==> give score > table score
ld a,010h ;84e6 3e 10 > .
add a,l ;84e8 85 .
ld l,a ;84e9 6f o
jr nc,l84edh ;84ea 30 01 0 .
inc h ;84ec 24 $
l84edh:
djnz l84dbh ;84ed 10 ec . .
jp CLS_PRINT_SCORE_TABLE ;84ef c3 61 85 . a .
l84f2h:
dec b ;84f2 05 .
ld a,b ;84f3 78 x
jr z,l8508h ;84f4 28 12 ( .
add a,a ;84f6 87 .
add a,a ;84f7 87 .