/
+Music.s
4867 lines (4616 loc) · 109 KB
/
+Music.s
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
;---------------------------------------------------------------------
; ** ** ** *** *** **** ** *** ** ****
; **** *** *** ** ** ** ** ** **** ** ** ** **
; ** ** ** * ** ** ** *** ***** ** ** *** ** **
; ****** ** ** ** ** ** ** ** ****** ** ** **
; ** ** ** ** ** ** * ** ** ** ** ** * ** ** ** **
; ** ** ** ** *** *** ***** ** ** *** ** ****
;---------------------------------------------------------------------
; Music extension source code for AMOSPro, Last change 20/07/1993
; By Francois Lionet
; AMOS, AMOSPro AMOS Compiler (c) Europress Software 1990-1993
; To be used with AMOSPro 2.0 and over
;---------------------------------------------------------------------
;
; Published under the MIT Licence
;
; Copyright (c) 1992 Europress Software
; Copyright (c) 2020 Francois Lionet
;
; Permission is hereby granted, free of charge, to any person
; obtaining a copy of this software and associated documentation
; files (the "Software"), to deal in the Software without
; restriction, including without limitation the rights to use,
; copy, modify, merge, publish, distribute, sublicense, and/or
; sell copies of the Software, and to permit persons to whom the
; Software is furnished to do so, subject to the following
; conditions:
;
; The above copyright notice and this permission notice shall be
; included in all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
; ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
; THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;
;---------------------------------------------------------------------
;
; NOTE: every chapter is preceded by "+++", so just look for this sign
; with your editor to go from one important paragraph to another
;
; +++
; This listing explains how to create an extension for AMOSPro V2.0
; The format of the extension have changed between V1.x and V2.x,
; but V2.x still accepts old-format extensions.
; So if you do not want to rewrite your code, just don't, it will work
; with the interpreter and the compiler.
;
; Several advantages of rewriting your code:
; - Faster under both interpreter and compiler
; - Reserved variables can be created in extensions
; - Mathematical functions can be created in extensions
; - You can call any AMOSPro function using special macros
; from within your extension.
;
; Drawbacks:
; - Your function have to save D6/D7 registers
;
; To know how to rewrite your code, just read the text at the end of this
; file. Just know that this music extension has been turned from the old
; format (V1.x) to the new one, in one afternoon. You just need a good
; editor to perform the job. All the rest of the text only explain how to
; write a V2.x extension.
;
; --------------------------------------------------------------------------
;
; +++ What's an extension?
;
; An extension to AMOS is a machine language program that adds new
; instructions to the already huge AMOS instruction set. This system is
; designed to be as powerfull as AMOS itself: the extension includes its
; own token list, its own routines. It can even access some main AMOS
; routines via special macros. It has a total access to the internal AMOS
; data zone, and to the graphic library functions.
;
; To produce your own extension, I suggest you copy and rename this
; file, and remove the used code. This way you will not forgive one line.
; Also keep in mind that you can perfectly call AMOS from within MONAM2,
; and set some ILLEGAL instructions where you want to debug. To flip back to
; MONAM2 display, just press AMIGA-A.
;
; I have designed the extension system so that one only file works with
; both AMOS interpretor and compiler.
; - The extension is more a compiler library than a one chunk program:
; it is done so that the compiler can pick one routine here and there
; to cope with the program it is compiling.
; - AMOSPro extension loader works a little like the compiler, exept
; that all instructions are loaded and relocated.
; - The AMOSPro (V2.x) instruction set is in fact a big extension,
; called "AMOSPro.Lib", in the APSystem folder
;
; This code was assembled with GENAM3 on a A3000 25 Mhz machine, but a
; A500 can do it very well!
; The assembled program must be ONE CHUNK only, you must not link the
; the symbol table with it. Also be sure that you program is totally
; relocatable (see later) : if not it will add a relocation chunk to
; the output code, and your extension will simply crash AMOS on loading
; (and the compiler too!).
;
; +++
; Before assembling your code, you must run one AMOSro Compiled program that
; explores your source code, and creates the label table for the assembler.
; This program is called "Library_Digest". Here is my script file to assemble
; the music extension :
;
; Library_Digest +Music.s
; Genam FROM +Music.s TO APro:APSystem/AMOSPro_Music.Lib
;
; Library_Digest loads +music.s and creates two ascii files:
; +Music_Size.s contains the number of functions in the extension
; +Music_Labels.s contains the list of labels and their value.
;
; Here we go now!
;
; +++
; Here comes the number of the extension in the list of extensions in
; AMOSPro_Interpretor_Config program (minus one).
; This number is used later to reference the extension in internal AMOS
; tables...
;
ExtNb equ 1-1
;---------------------------------------------------------------------
; +++
; Include the files automatically calculated by
; Library_Digest.AMOS
;---------------------------------------------------------------------
Include "+Music_Size.s"
Include "+Music_Labels.s"
; +++ You must include this file, it will decalre everything for you.
Include "+AMOS_Includes.s"
; +++ This one is only for the current version number.
Include "+Version.s"
; A usefull macro to find the address of data in the extension's own
; datazone (see later)...
Dlea MACRO
move.l ExtAdr+ExtNb*16(a5),\2
add.w #\1-MB,\2
ENDM
; Another macro to load the base address of the datazone...
Dload MACRO
move.l ExtAdr+ExtNb*16(a5),\1
ENDM
; ---------------------------------------------------------------------------
; Now some equates used by the music extension itself. Ignore this in your
; code!
Translate equ -30
*************** Enveloppes definitions
RsReset
EnvNb: rs.w 1
EnvDVol: rs.w 1
EnvVol: rs.l 1
EnvDelta: rs.l 1
EnvAd: rs.l 1
EnvDeb: rs.l 1
EnvLong: equ __RS
*************** Wave definition
LWave: equ 256+128+64+32+16+8+4+2
LNoise: equ LWave
RsReset
WaveNext: rs.l 1
WaveNb: rs.w 1
WaveEnv: rs.w 16*2
WaveDeb: rs.b LWave
WaveLong: equ __RS
*************** Music voice data
RsReset
VoiAdr rs.l 1
VoiDeb rs.l 1
VoiInst rs.l 1
VoiDPat rs.l 1
VoiPat rs.l 1
VoiCpt rs.w 1
VoiRep rs.w 1
VoiNote rs.w 1
VoiDVol rs.w 1
VoiVol rs.w 1
VoiEffect rs.l 1
VoiValue rs.w 1
VoiPToTo rs.w 1
VoiPTone rs.b 1
VoiVib rs.b 1
VoiLong equ __RS
*************** MUBASE table
RsReset
* Voix 0
MuVoix0 equ __RS
VoiAdr0 rs.l 1
VoiDeb0 rs.l 1
VoiInst0 rs.l 1
VoiDPat0 rs.l 1
VoiPat0 rs.l 1
VoiCpt0 rs.w 1
VoiRep0 rs.w 1
VoiNote0 rs.w 1
VoiDVol0 rs.w 1
VoiVol0 rs.w 1
VoiEffect0 rs.l 1
VoiValue0 rs.w 1
VoiPToTo0 rs.w 1
VoiPTone0 rs.b 1
VoiVib0 rs.b 1
* Voix 1
MuVoix1 equ __RS
VoiAdr1 rs.l 1
VoiDeb1 rs.l 1
VoiInst1 rs.l 1
VoiDPat1 rs.l 1
VoiPat1 rs.l 1
VoiCpt1 rs.w 1
VoiRep1 rs.w 1
VoiNote1 rs.w 1
VoiDVol1 rs.w 1
VoiVol1 rs.w 1
VoiEffect1 rs.l 1
VoiValue1 rs.w 1
VoiPToTo1 rs.w 1
VoiPTone1 rs.b 1
VoiVib1 rs.b 1
* Voix 2
MuVoix2 equ __RS
VoiAdr2 rs.l 1
VoiDeb2 rs.l 1
VoiInst2 rs.l 1
VoiDPat2 rs.l 1
VoiPat2 rs.l 1
VoiCpt2 rs.w 1
VoiRep2 rs.w 1
VoiNote2 rs.w 1
VoiDVol2 rs.w 1
VoiVol2 rs.w 1
VoiEffect2 rs.l 1
VoiValue2 rs.w 1
VoiPToTo2 rs.w 1
VoiPTone2 rs.b 1
VoiVib2 rs.b 1
* Voix 3
MuVoix3 equ __RS
VoiAdr3 rs.l 1
VoiDeb3 rs.l 1
VoiInst3 rs.l 1
VoiDPat3 rs.l 1
VoiPat3 rs.l 1
VoiCpt3 rs.w 1
VoiRep3 rs.w 1
VoiNote3 rs.w 1
VoiDVol3 rs.w 1
VoiVol3 rs.w 1
VoiEffect3 rs.l 1
VoiValue3 rs.w 1
VoiPToTo3 rs.w 1
VoiPTone3 rs.b 1
VoiVib3 rs.b 1
* Other data
MuCpt rs.w 1
MuTempo rs.w 1
MuStart rs.w 1
MuStop rs.w 1
* Total length
MuLong equ __RS
IntEnaR equ $1c
IntReqR equ $1e
is_data equ $0e
is_code equ $12
ln_pri equ $09
ln_type equ $08
; +++
; All the above did not produce any byte of code. Here is the real beginning
; of the program. It MUST begin by a small table of pointers so that both
; AMOS and the compiler know where to get their data...
; Please remark that everything is relocatable...
; +++ First, a pointer to the token list
Start dc.l C_Tk-C_Off
;
; +++ Then, a pointer to the first library function
dc.l C_Lib-C_Tk
;
; +++ Then to the title
dc.l C_Title-C_Lib
;
; +++ From title to the end of the program
dc.l C_End-C_Title
; +++
; An important flag. Imagine a program does not call your extension, the
; compiler will NOT copy any routine from it in the object program. For
; certain extensions, like MUSIC, COMPACT, it is perfect.
; But for the REQUEST extension, even if it is not called, the first routine
; MUST be called, otherwise AMOS requester will not work!
; So, a value of 0 indicates to copy if needed only,
; A value of -1 forces the copy of the first library routine...
dc.w 0
; +++ This magic code tells AMOSPro that this extensions uses the new format
dc.b "AP20"
;---------------------------------------------------------------------
; +++ TABLE OF POINTERS TO THE LIBRARY
;
; The following macros automatically create the necessary pointers
; to the library. It uses the informations created by "Library_Digest"
; You are free to add/remove a function in the middle of the extension
; without having to care about the numbers of the function.
;---------------------------------------------------------------------
MCInit
C_Off
REPT Lib_Size
MC
ENDR
;---------------------------------------------------------------------
; +++ TOKEN TABLE
;
;
; This table is the crucial point of the extension! It tells
; everything the tokenisation process needs to know. You have to
; be carefull when writing it!
;
; The format is simple:
; dc.w Number of instruction,Number of function
; dc.b "instruction nam","e"+$80,"Param list",-1[or -2]
;
; (1) Number of instruction / function
; You must state the one that is needed for this token.
; I suggest you keep the same method of referencing the
; routines than mine: L_name, this label being defined
; in the main program.
; A -1 means take no routine is called (example a
; instruction only will have a -1 in the function space...)
;
; (2) Instruction name
; It must be finished by the letter plus $80.
; - You can SET A MARK in the token table with a "!" before
; the name. See later
; -Using a $80 ALONE as a name definition, will force AMOS
; to point to the previous "!" mark...
;
; (3) Param list
; This list tells AMOS everything about the instruction.
;
; - First character:
; The first character defines the TYPE on instruction:
; I--> instruction
; 0--> function that returns a integer
; 1--> function that returns a float
; 2--> function that returns a string
; V--> reserved variable. In that case, you must
; state the type int-float-string
; - If your instruction does not need parameters, then you stop
; - Your instruction needs parameters, now comes the param list
; Type,TypetType,Type...
; Type of the parameter:
; 0--> integer
; 1--> float or double
; 2--> string
; 3--> integer OR string. The only way to check the type
; is to check the adress (UGLY, but safe for integer
; up to 512 which cannot ever be a string's address)
; 4--> Integer OR float/double. You must then write TWO
; routines. The first one being called when the param
; is an integer, and being the one pointed to by the
; token table. The second one being called when the
; parameter is a float/double.
; This system is used for functions like SGN.
; 5--> Angle. This parameter will always be a float/double,
; in radians, even if DEGREE has been set.
; Comma or "t" for TO
;
; (4) End of instruction
; "-1" states the end of the instruction
; "-2" tells AMOS that another parameter list
; can be accepted. if so, MUST follow the
; complete instruction definition as explained
; but with another param list.
; If so, you can use the "!" and $80 facility not to rewrite the
; full name of the instruction...See SAM LOOP ON instruction for an
; example...
;
;
; +++ You _MUST_ leave this keyword in the source, in upper case:
; Library_Digest uses it to detect the start of the library.
;
; TOKEN_START
; +++ The next two lines needs to be unchanged...
C_Tk: dc.w 1,0
dc.b $80,-1
; Now the real tokens...
dc.w L_Nul,L_FnMusicBase
dc.b "mubas","e"+$80,"0",-1
dc.w L_Nul,L_FnVuMeter
dc.b "vumete","r"+$80,"00",-1
dc.w L_InVoice,L_Nul
dc.b "voic","e"+$80,"I0",-1
dc.w L_InMusicOff,L_Nul
dc.b "music of","f"+$80,"I",-1
dc.w L_InMusicStop,L_Nul
dc.b "music sto","p"+$80,"I",-1
dc.w L_InTempo,L_Nul
dc.b "temp","o"+$80,"I0",-1
dc.w L_InMusic,L_Nul
dc.b "musi","c"+$80,"I0",-1
dc.w L_InNoiseTo,L_Nul
dc.b "noise t","o"+$80,"I0",-1
dc.w L_InBoom,L_Nul
dc.b "boo","m"+$80,"I",-1
dc.w L_InShoot,L_Nul
dc.b "shoo","t"+$80,"I",-1
dc.w L_InSamBank,L_Nul
dc.b "sam ban","k"+$80,"I0",-1
dc.w L_InSamLoopOn0,L_Nul
dc.b "!sam loop o","n"+$80,"I",-2
dc.w L_InSamLoopOn1,L_Nul
dc.b $80,"I",-1
dc.w L_InSamLoopOff0,L_Nul
dc.b "sam loop of","f"+$80,"I",-2
dc.w L_InSamLoopOff1,L_Nul
dc.b $80,"I0",-1
dc.w L_InSampleTo,L_Nul
dc.b "sampl","e"+$80,"I0t0",-1
dc.w L_InSamPlay1,L_Nul
dc.b "!sam pla","y"+$80,"I0",-2
dc.w L_InSamPlay2,L_Nul
dc.b $80,"I0,0",-2
dc.w L_InSamPlay3,L_Nul
dc.b $80,"I0,0,0",-1
dc.w L_InSamRaw,L_Nul
dc.b "sam ra","w"+$80,"I0,0,0,0",-1
dc.w L_InBell0,L_Nul
dc.b "!bel","l"+$80,"I",-2
dc.w L_InBell1,L_Nul
dc.b $80,"I0",-1
dc.w L_InPlayOff0,L_Nul
dc.b "!play of","f"+$80,"I",-2
dc.w L_InPlayOff1,L_Nul
dc.b $80,"I0",-1
dc.w L_InPlay2,L_Nul
dc.b "!pla","y"+$80,"I0,0",-2
dc.w L_InPlay3,L_Nul
dc.b $80,"I0,0,0",-1
dc.w L_InSetWave,L_Nul
dc.b "set wav","e"+$80,"I0,2",-1
dc.w L_InDelWave,L_Nul
dc.b "del wav","e"+$80,"I0",-1
dc.w L_InSetEnvel,L_Nul
dc.b "set enve","l"+$80,"I0,0t0,0",-1
dc.w L_InMvolume,L_Nul
dc.b "mvolum","e"+$80,"I0",-1
dc.w L_InVolume1,L_Nul
dc.b "!volum","e"+$80,"I0",-2
dc.w L_InVolume2,L_Nul
dc.b $80,"I0,0",-1
dc.w L_InWave,L_Nul
dc.b "wav","e"+$80,"I0t0",-1
dc.w L_InLedOn,L_Nul
dc.b "led o","n"+$80,"I",-1
dc.w L_InLedOf,L_Nul
dc.b "led of","f"+$80,"I",-1
dc.w L_InSay1,L_Nul
dc.b "!sa","y"+$80,"I2",-2
dc.w L_InSay2,L_Nul
dc.b $80,"I2,0",-1
dc.w L_InSetTalk,L_Nul
dc.b "set tal","k"+$80,"I0,0,0,0",-1
dc.w L_InSload,L_Nul
dc.b "sloa","d"+$80,"I0t0,0",-1
dc.w L_Nul,L_FnSamSwapped
dc.b "sam swappe","d"+$80,"00",-1
dc.w L_InSamSwap,L_Nul
dc.b "sam swa","p"+$80,"I0t0,0",-1
dc.w L_InSamStop0,L_Nul
dc.b "!sam sto","p"+$80,"I",-2
dc.w L_InSamStop1,L_Nul
dc.b $80,"I0",-1
dc.w L_InTrackStop,L_Nul
dc.b "track sto","p"+$80,"I",-1
dc.w L_InTrackLoopOn,L_Nul
dc.b "track loop o","n"+$80,"I",-1
dc.w L_InTrackLoopOff,L_Nul
dc.b "track loop o","f"+$80,"I",-1
dc.w L_InTrackPlay0,L_Nul
dc.b "!track pla","y"+$80,"I",-2
dc.w L_InTrackPlay1,L_Nul
dc.b $80,"I0",-2
dc.w L_InTrackPlay2,L_Nul
dc.b $80,"I0,0",-1
dc.w L_InTrackLoad,L_Nul
dc.b "track loa","d"+$80,"I2,0",-1
dc.w L_Nul,L_FnMouthWidth
dc.b "mouth widt","h"+$80,"0",-1
dc.w L_Nul,L_FnMouthHeight
dc.b "mouth heigh","t"+$80,"0",-1
dc.w L_InMouthRead,L_Nul
dc.b "mouth rea","d"+$80,"I",-1
dc.w L_InTalkStop,L_Nul
dc.b "talk sto","p"+$80,"I",-1
dc.w L_InTalkMisc,L_Nul
dc.b "talk mis","c"+$80,"I0,0",-1
dc.w L_InSsave,L_Nul
dc.b "ssav","e"+$80,"I0,0t0",-1
dc.w L_InMedLoad,L_Nul
dc.b "med loa","d"+$80,"I2,0",-1
dc.w L_InMedPlay0,L_Nul
dc.b "!med pla","y"+$80,"I",-2
dc.w L_InMedPlay1,L_Nul
dc.b $80,"I0",-2
dc.w L_InMedPlay2,L_Nul
dc.b $80,"I0,0",-1
dc.w L_InMedStop,L_Nul
dc.b "med sto","p"+$80,"I",-1
dc.w L_InMedCont,L_Nul
dc.b "med con","t"+$80,"I",-1
dc.w L_InMedMidiOn,L_Nul
dc.b "med midi o","n"+$80,"I",-1
; +++ You must also leave this keyword untouched, just before the zeros.
; TOKEN_END
; +++ The token table must end by this
dc.w 0
dc.l 0
;
; Now come the big part, the library.
;
; The beginning of each routine is defined with macros. NB: in the following text
; a space in inserted in the macro name, so that it is not detected by
; "Library_Digest".
;
; Lib_ Def Function_Name_No_Parameter
; or
; Lib_ Par Function_Name_With_Parameter
;
; Those two macro have the same function:
; - Create an entry in the library offset table, so that AMOSPro locates
; the function,
; - Are detected by Library_Digest: it then creates a label in the "_Label.s"
; file (see above) of the following form, by appending a "L_" to the name:
; "L_Function_Name_..." This label must be used in the extension to reference
; the routine.
;
; Differences between Lib_ Def and Lib_ Par
; - Lib_ Def must be used for internal routines (ie, not instructions or
; functions)
; - Lib_ Par must be used for instructions or functions: it reserved a space
; before the routine if used by the interpreter, to call the parameter
; calculation routines. Well this is internal, you don't have to care
; about it, just use "Lib_ Par" for routines referenced in the token
; table...
;
; BSR and JSR
; - You cannot directly call other library routines from one routine
; by doing a BSR, but I have defined special macros (in +CEQU.S file)
; to allow you to easily do so. Here is the list of available macros:
;
; Rbsr L_Routine does a simple BSR to the routine
; Rbra L_Routine as a normal BRA
; Rbeq L_Routine as a normal Beq
; Rbne L_Routine ...
; Rbcc L_Routine
; Rbcs L_Routine
; Rblt L_Routine
; Rbge L_Routine
; Rbls L_Routine
; Rbhi L_Routine
; Rble L_Routine
; Rbpl L_Routine
; Rbmi L_Routine
;
; I remind you that you can only use this to call an library routine
; from ANOTHER routine. You cannot do a call WITHIN a routine, or call
; the number of the routine your calling from...
; The compiler (and AMOSPro extension loading part) will manage to find
; the good addresses in your program from the offset table.
;
; You can also call some main AMOSPro.Lib routines, to do so, use the
; following macros:
; Rjsr L_Routine
; Rjmp L_Routine
;
; Here is the list of the most usefull routines from the AMOSPro.Lib
;
; Rjsr L_Error
; ~~~~~~~~~~~~~~~~~~~~~
; Jump to normal error routine. See end of listing
;
; Rjsr L_ErrorExt
; ~~~~~~~~~~~~~~~~~~~~~~~~
; Jump to specific error routine. See end of listing.
;
; Rjsr L_Test_PaSaut
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Perform one AMOSPro updating procedure, update screens, sprites,
; bobs etc. You should use it for wait loops. Does not jump to
; automatic calls.
;
; Rjsr L_Test_Normal
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Same as before, but with automatic function jump.
;
; Rjsr L_WaitRout
; ~~~~~~~~~~~~~~~~~~~~~~~~
; Wait for D3 VBL with tests.
; See play instruction.
;
; Rjsr L_GetEc
; ~~~~~~~~~~~~~~~~~~~~~
; Get screen address: In: D1.l= number, Out: A0=address
;
; Rjsr L_Demande
; ~~~~~~~~~~~~~~~~~~~~~~~
; Ask for string space.
; D3.l is the length to ask for. Return A0/A1 point to free space.
; Poke your string there, add the length of it to A0, EVEN the
; address to the highest multiple of two, and move it into
; HICHAINE(a5) location...
;
; Rjsr L_RamChip
; ~~~~~~~~~~~~~~~~~~~~~
; Ask for PUBLIC|CLEAR|CHIP ram, size D0, return address in D0, nothing
; changed, Z set according to the success.
;
; Rjsr L_RamChip2
; ~~~~~~~~~~~~~~~~~~~~~~
; Same for PUBLIC|CHIP
;
; Rjsr L_RamFast
; ~~~~~~~~~~~~~~~~~~~~~
; Same for PUBLIC|CLEAR
;
; Rjsr L_RamFast2
; ~~~~~~~~~~~~~~~~~~~~~~~~
; Same for PUBLIC
;
; Rjsr L_RamFree
; ~~~~~~~~~~~~~~~~~~~~~~~
; Free memory A1/D0
;
; Rjsr L_Bnk.OrAdr
; ~~~~~~~~~~~~~~~~~~~~~~~~~
; Find whether a number is a address or a memory bank number
; IN: D0.l= number
; OUT: D0/A0= number or start(number)
;
; Rjsr L_Bnk.GetAdr
; ~~~~~~~~~~~~~~~~~~~~~~~~~~
; Find the start of a memory bank.
; IN: D0.l= Bank number
; OUT: A0= Bank address
; D0.w= Bank flags
; Z set if bank not defined.
;
; Rjsr L_Bnk.GetBobs
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Returns the address of the bob's bank
; IN:
; OUT: Z Set if not defined
; A0= address of bank
;
; Rjsr L_Bnk.GetIcons
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Returns the address of the icons bank
; IN:
; OUT: Z Set if not defined
; A0= address of bank
;
; Rjsr L_Bnk.Reserve
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Reserve a memory bank.
; IN: D0.l Number
; D1 Flags
; D2 Length
; A0 Name of the bank (8 bytes)
; OUT: Z Set inf not successfull
; A0 Address of bank
; FLAGS:
; Bnk_BitData Data bank
; Bnk_BitChip Chip bank
; Example: Bset #Bnk_BitData|Bnk_BitChip,d1
; NOTE: you should call L_Bnk.Change after reserving/erasing a bank.
;
; Rjsr L_Bnk.Eff
; ~~~~~~~~~~~~~~~~~~~~~~~
; Erase one memory bank.
; IN: D0.l Number
; OUT:
;
; Rjsr L_Bnk.EffA0
; ~~~~~~~~~~~~~~~~~~~~~~~~~
; Erase a bank from its address.
; IN: A0 Start(bank)
; OUT:
;
; Rjsr L_Bnk.EffTemp
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Erase all temporary banks
; IN:
; OUT:
;
; Rjsr L_Bnk.EffAll
; ~~~~~~~~~~~~~~~~~~~~~~~~~~
; Erase all banks
; IN:
; OUT:
;
; Rjsr L_Bnk.Change
; ~~~~~~~~~~~~~~~~~~~~~~~~~~
; Inform the extension, the bob handler that something has changed
; in the banks. You should use this function after every bank
; reserve / erase.
; IN:
; OUT:
;
; Rjsr L_Dsk.PathIt
; ~~~~~~~~~~~~~~~~~~~~~~~~~~
; Add the current AMOS path to a file name.
; IN: (Name1(a5)) contains the name, finished by zero
; OUT: (Name1(a5)) contains the name with new path
; Example:
; move.l Name1(a5),a0
; move.l #"Kiki",(a0)+
; clr.b (a0)
; Rjsr L_Dsk.PathIt
; ... now I load in the current directory
;
; Rjsr L_Dsk.FileSelector
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Call the file selector.
; IN: 12(a3) Path+filter
; 8(a3) Default name
; 4(a3) Title 2
; 0(a3) Title 1
; All strings must be in AMOS string format:
; dc.w Length
; dc.b "String"
; OUT: D0.w Length of the result. 0 if no selection
; A0 Address of first character of the result.
;
;
; How does it work?
; Having a look at the +CEQU file, you see that I use special codes
; to show the compiler that it has to copy the asked routine and relocate
; the branch. Some remarks:
; - The size of a Rbsr is 4 bytes, like the normal branch, it does
; not change the program (you can make some jumps over it)
; - Although I have coded the signal, and put a lot a security,
; a mischance may lead to the compiler thinking there is a Rbsr where
; there is nothing than normal data. The result may be disastrous! So if
; you have BIG parts of datas in which you do not make any special calls,
; you can put before it the macro: RDATA. It tells the compiler that
; the following code, up to the end of the library routine (up to the next
; L(N) label) is normal data: the compiler will not check for Rbranches...
; Up to now, I have not been forced to do so, but if something goes wrong,
; try that!
;
; +++ Remember!
; - Your code must be (pc), TOTALLY relocatable, check carefully your
; code!
; - Never perform a BSR or a JSR from one function to another: it
; _will_ crash once compiled. Use the special macros instead.
; - Each individual routine of the library can be up to 32K
;---------------------------------------------------------------------
; +++ This macro initialise the library counter, and is also detected by
; Library_Digest
;
Lib_Ini 0
;---------------------------------------------------------------------
; +++ Start of the library (for the header)
C_Lib
******************************************************************
* COLD START
*
; The first routine of the library will perform all initialisations in the
; booting of AMOS.
;
; I have put here all the music datazone, and all the interrupt routines.
; I suggest you put all you C-Code here too if you have some...
; ALL the following code, from L0 to L1 will be copied into the compiled
; program (if any music is used in the program) at once. All RBSR, RBRA etc
; will be detected and relocated. AMOSPro extension loader does the same.
; The length of this routine (and of any routine) must not exceed 32K
; - - - - - - - - - - - - -
Lib_Def Mus_Cold
; - - - - - - - - - - - - -
cmp.l #"APex",d1 Version 1.10 or over?
bne.s BadVer
movem.l a3-a6,-(sp)
;
; Here I store the address of the extension data zone in the special area
lea MB(pc),a3
move.l a3,ExtAdr+ExtNb*16(a5)
;
; Here, I store the address of the routine called by DEFAULT, or RUN
lea MusDef(pc),a0
move.l a0,ExtAdr+ExtNb*16+4(a5)
;
; Here, the address of the END routine,
lea MusEnd(pc),a0
move.l a0,ExtAdr+ExtNb*16+8(a5)
;
; And now the Bank check routine..
lea BkCheck(pc),a0
move.l a0,ExtAdr+ExtNb*16+12(a5)
; You are not obliged to store something in the above areas, you can leave
; them to zero if no routine is to be called...
;
; In AMOS data zone, stands 8 long words allowing you to simply
; put a patch in the VBL interrupt. The first on is at VBLRout.
; At each VBL, AMOS explores this list, and call all address <> 0
; It stops at the FIRST zero. The music patch is the first routine
; called.
lea MusInt(pc),a0 * Interrupt routine
move.l a0,VblRout(a5)
; 50/60 herz?
move.l #3546895,MusClock-MB(a3)
move.w #100,TempoBase-MB(a3)
EcCall NTSC * Is system NTSC?
tst.w d1
beq.s ItsPAL
move.w #120,TempoBase-MB(a3)
move.l #3579545,MusClock-MB(a3)
ItsPAL
; Install sample interrupts
lea Sami_handler(pc),a0
move.l a0,Sami_handad-MB(a3)
; As you can see, you MUST preserve A3-A6, and return in D0 the
; Number of the extension if everything went allright. If an error has
; occured (no more memory, no file found etc...), return -1 in D0 and
; AMOS will refuse to start.
movem.l (sp)+,a3-a6
moveq #ExtNb,d0 * NO ERRORS
move.w #$0110,d1 * Version d'ecriture
rts
; In case this extension is runned on AMOSPro V1.00
BadVer moveq #-1,d0 * Bad version number
sub.l a0,a0
rts
******* SCREEN RESET
; This routine is called each time a DEFAULT occurs...
;
; The next instruction loads the internal datazone address. I could have
; of course done a load MB(pc),a3 as the datazone is in the same
; library chunk.
MusDef Dload a3
* Stop/Init narrator
Rbsr L_InTalkStop
Rbsr L_NarInit
* Reset TRACKER music
Rbsr L_InTrackStop
clr.b Track_Loop-MB(a3)
* Reset MED music
Rbsr L_MedClose
clr.b Med_Midi-MB(a3)
* Reset Sam_interrupts
move.w #$000F,Circuits+DmaCon
Rbsr L_Sami_install
* Init musique
Rbsr L_RazWave * Reset waves
move.l Buffer(a5),a0 * Draw square wave
move.l a0,a1
moveq #127,d0
MuDf1 move.b #-127,128(a0)
move.b #127,(a0)+
dbra d0,MuDf1
moveq #0,d1 * 0-> Noise
Rbsr L_NeWave
moveq #1,d1 * 1-> Square wave
Rbsr L_NeWave
move.w #LNoise/2-1,d2 * Draw first noise
move.w BSeed-MB(a3),d1
move.l WaveBase-MB(a3),a0
lea WaveDeb(a0),a0
MuDf2 add.w Circuits+6,d1
mulu #$3171,d1
lsr.l #8,d1
move.w d1,(a0)+
dbra d2,MuDf2
move.w d1,BSeed-MB(a3)
moveq #56,d0 * Default settings
moveq #%1111,d1
Rbsr L_Vol
Rbsr L_MVol
move.w #5,SamBank-MB(a3) * Sample bank=5
moveq #-1,d0 * Sam loop off
moveq #-1,d1
Rbsr L_SL0
Rbra L_MuInit
******* QUIT
; This routine is called when you quit AMOS or when the compiled program
; ends. If you have opend devices, reserved memory you MUST close and
; restore everything to normal.
MusEnd: Dload a3
; Ferme le narrator
Rbsr L_InTalkStop
move.l $4.w,a6
move.l WriteIo-MB(a3),d0
beq.s .Skip1
move.l d0,a1
move.l WriteIo-MB(a3),a1
jsr _LVOCloseDevice(a6)
; Enleve la structure
move.l WriteIo-MB(a3),-(sp)
Rjsr L_DeleteExtIO
addq.l #4,sp
; Enleve les ports
move.l WritePort-MB(a3),-(sp)
Rjsr L_DeletePort
addq.l #4,sp
move.l ReadPort-MB(a3),-(sp)
Rjsr L_DeletePort
addq.l #4,sp
; Enleve le translator
.Skip1 move.l TranBase-MB(a3),d0
beq.s NarEnd
move.l d0,a1
jsr CloseLib(a6)
NarEnd
* No more TRACKER music
Rbsr L_InTrackStop
* No more MED music
Rbsr L_MedClose
* No more VBL
clr.l VblRout(a5)
* No more Sami
Rbsr L_Sami_remove
* End music
Rbsr L_MOff
moveq #%1111,d0
Rbsr L_EnvOff
Rbsr L_RazWave
lea Circuits,a0
move.w #$000F,DmaCon(a0)
clr.w $a8(a0)
clr.w $b8(a0)
clr.w $c8(a0)
clr.w $d8(a0)
* Finished!
rts
******* LOOK FOR MUSIC BANK
; This routine is called after any bank has been loaded, reserved or erased.
; Here, if a music is being played and if the music bank is erased, I MUST
; stop the music, otherwise it might crash the computer. That's why I
; do a checksum on the first bytes of the bank to see if they have changed...
BkCheck
Rbsr L_TrackCheck * Check Tracker
Rbsr L_MedCheck * Check Med
* Check normal music.
Dload a3
move.l MusBank-MB(a3),d2 Old music bank address
moveq #3,d0 Ask for music bank address
Rjsr L_Bnk.GetAdr
beq.s BkNo
move.l -8(a0),d0 Looks for "Musi"
cmp.l BkMus-MB(a3),d0
bne.s BkNo
moveq #0,d0 Performs a check sum
add.l (a0),d0