File: loading_a_sid_file.asm

package info (click to toggle)
64tass 1.60.3243-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 3,432 kB
  • sloc: ansic: 48,995; xml: 647; asm: 333; makefile: 250
file content (64 lines) | stat: -rw-r--r-- 2,322 bytes parent folder | download | duplicates (3)
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
;
; In most cases where the SID file is known this might work:
;
                .comment
                *= $1000
music           .binary "music.sid", $7e; skip header and load

                *= $0801                ; C64 BASIC header
                .word (+), 2021
                .null $9e, format("%4d", start)
+               .word 0

start           lda #0
                jsr music               ; initialize

lp              bit $d011
                bpl lp
-               bit $d011
                bmi -
                jsr music+3             ; call play every frame
                jmp lp
                .endc
;
; However SID files can have all sorts of load/init/play addresses
; and might not always have the same length of header either.
;
; So the following function tries to figure these details out.

loadsid         .function _data : binary; use binary() for this parameter
_data_at        := _data[[$7,$6]]       ; data offset (big endian)
_load           := _data[[$9,$8]]       ; load address (big endian)
_init           := _data[[$b,$a]]       ; init address (big endian)
_play           := _data[[$d,$c]]       ; play address (big endian)

; dump music data after the header (and the optional loading address)
_sid            .text _data[_data_at + (_load != 0 ? 0 : 2):]

; if load address is zero then it's the first 2 bytes of music data
_sid.load       = _load != 0 ? _load : _data[_data_at + [0, 1]]
_sid.init       = _init != 0 ? _init : _load
_sid.play       = _play                 ; put results into constants
                .endf _sid              ; and return them

; There's a lot more information in the header, however that would make
; this example unnecessary complicated so it's left as an exercise
; to the reader.
; 
                *= music.load           ; set PC to load address
music           #loadsid "music.sid"    ; load this file as music

*               = $0801                ; C64 BASIC header
                .word (+), 2021
                .null $9e, format("%4d", start)
+               .word 0

start           lda #0
                jsr music.init          ; initialize

lp              bit $d011
                bpl lp
-               bit $d011
                bmi -
                jsr music.play          ; call play every frame
                jmp lp