;play *.tfm
;newtfm=1 ;0=revision A, 1=revision C
pseudo60hz=1
;эти настройки не меняйте:
A6XXXX=1
PACK28=1
;LD HL,0xc000;tfmData
;LD (addrTFM),HL
;LD (loopPos),HL
;LD A,0
;LD (tfdplay_pg),A
;LD (looptfmpg),A
;LD A,1
;LD (skipTFM),A
if 0
LOOP
IF pseudo60hz
;делаем псевдо 60Hz
cnt=$+1
LD A,6
DEC A
jr NZ,$+4
LD A,6
LD (cnt),A
jr Z,nehalt
ENDIF
HALT
nehalt
;LD A,2
;OUT (-2),A
CALL tfm
;LD A,0
;OUT (-2),A
;LD A,#7F
;IN A,(-2)
;RRA
;JP LOOP
CALL tfmini
LD B,D
WaitStatus
LD A,#FF ;выкл. FM
OUT (C),A
RET
endif
if 0
WRITEREG
;A=REG
;A'=VALUE
LD B,D
WaitStatus
OUT (C),A ;reg
EXA
WaitStatus
LD B,E
OUT (C),A ;value
EXA
RET
endif
selChip0ix
LD B,D
LD A,statuschip0
OUT (C),A
LD IX,lows0
RET
selChip1ix
LD B,D
LD A,statuschip1
OUT (C),A
LD IX,lows1
RET
tfm_play
;a = port bd77 value
di
push af
and 0xf7;0xa0;%10101000 ;320x200 mode noturbo
ld bc,0xbd77 ;shadow ports and palette remain on
out (c),a
call tfm_playPP
pop af
;LD A,0xa8;%10101000 ;320x200 mode
ld bc,0xbd77 ;shadow ports and palette remain on
out (c),a
ei
ret
tfm_playPP
ld a,(tfdplay_pg)
ld c,a
ld b,tpgs/256
ld a,(bc)
SETPGC000
skipTFM=$+1
LD A,1
DEC A
JP NZ,skiperTFM
addrTFM=$+1
LD HL,0xc000;tfmData
;LD E,#BF
ld de,0xffbf
LD C,#FD
CALL selChip0ix
tfm_parse0
LD A,(HL)
INCHL
CP #C0
JP NC,parseMARKER
CP #14
jr Z,parseBEG
CP #A6
JP Z,parseA6
CP #A5
JP Z,parseA5
CP #A4
JP Z,parseA4
CP #A2
JP Z,parseA2
CP #A1
JP Z,parseA1
CP #A0
JP Z,parseA0
IF PACK28
SUB #2A
CP 6
JP C,parseKEY
SUB #0E-#2A
ELSE
SUB #0E
ENDIF
CP 6
JP C,parseH1SSG
SUB #08-#0E
CP 3
JP C,parseVOSSG
SUB #00-#08
CP 6
JP C,parseFRSSG
EXA
LD A,(HL)
INCHL
EXA
CALL WRITEREG
JR tfm_parse0
parseBEG
LD (loopPos),HL
LD A,(tfdplay_pg)
LD (looptfmpg),A
JR tfm_parse0
parseA6
LD A,(HL)
LD (IX+2+3),A
INCHL
IF A6XXXX
LD A,#A2
ELSE
JP tfm_parse0
ENDIF
parseA2
PUSH AF
ADD A,4
EXA
LD A,(IX+2+3)
EXA
CALL WRITEREG
POP AF
EXA
LD A,(HL)
LD (IX+2),A
EXA
CALL WRITEREG
INCHL
JP tfm_parse0
parseA5
LD A,(HL)
LD (IX+1+3),A
INCHL
IF A6XXXX
LD A,#A1
ELSE
JP tfm_parse0
ENDIF
parseA1
PUSH AF
ADD A,4
EXA
LD A,(IX+1+3)
EXA
CALL WRITEREG
POP AF
EXA
LD A,(HL)
LD (IX+1),A
EXA
CALL WRITEREG
INCHL
JP tfm_parse0
parseA4
LD A,(HL)
LD (IX+0+3),A
INCHL
IF A6XXXX
LD A,#A0
ELSE
JP tfm_parse0
ENDIF
parseA0
PUSH AF
ADD A,4
EXA
LD A,(IX+0+3)
EXA
CALL WRITEREG
POP AF
EXA
LD A,(HL)
LD (IX+0),A
EXA
CALL WRITEREG
INCHL
JP tfm_parse0
tfmQ
LD (addrTFM),HL ;tfdplay_pg уже сохранена
RET
parseHALTS
LD A,(HL)
INCHL
ADD A,3
HLskiperTFM
LD (addrTFM),HL
skiperTFM
LD (skipTFM),A
RET
parseCHIP1
CALL selChip1ix
JP tfm_parse0
parseEND
loopPos=$+1
LD HL,0xc000;tfmData
looptfmpg=$+1
LD A,0
LD (tfdplay_pg),A
PUSH BC
ld c,a
ld b,tpgs/256
ld a,(bc)
SETPGC000
POP BC
JP tfm_parse0
parseMARKER
CP #FF
jr Z,tfmQ
CP #FE
jr Z,parseHALTS
CP #FD
jr Z,parseCHIP1
CP #FC
jr Z,parseEND
CP #F0
jr NC,parseViSSG
CP #D8
jr NC,parseSLSSG
;CP #C0
;jr NC,parseSLIDE
parseSLIDE
;Cx,Cx+8,Dx - сдвиг мл.байта частоты на +x-4
PUSH AF
SUB #C0
RRA
RRA
RRA
AND 3
LD (_IXshift1),A
LD (_IXshift2),A
ADD A,3
LD (_IXshift3),A
ADD A,#A0 -3+4
PUSH AF
EXA
_IXshift3=$+2
LD A,(IX+3) ;ст.б.
EXA
CALL WRITEREG
POP AF
SUB 4
EXA
POP AF
AND #7
SUB 4
_IXshift1=$+2
ADD A,(IX) ;старый мл.байт частоты
_IXshift2=$+2
LD (IX),A ;новый мл.байт частоты
EXA
CALL WRITEREG
JP tfm_parse0
parseViSSG
;A=0..3 - vol -2..+2 SSG A
;4..7 - B
;8..b - C
PUSH AF
AND 3
SUB 2
SBC A,-1
LD (ViSSGa),A
POP AF
RRA
RRA
AND 3
ADD A,12
LD (_IXshViSSG),A
LD (_IXshViSSG2),A
ADD A,8-12
EXA
_IXshViSSG=$+2
LD A,(IX)
ViSSGa=$+1
ADD A,0
_IXshViSSG2=$+2
LD (IX),A
SUB 4
jr NC,$+3
XOR A
EXA
CALL WRITEREG
JP tfm_parse0
parseSLSSG
;A=Dx+8 - lfrqSSGA += x-4
;Ex - B
;Ex+8 - C
SUB #D8
PUSH AF
AND 7
SUB 4
;SBC A,-1
LD (SLSSGa),A
POP AF
RRA
RRA
AND 6
ADD A,6
LD (_IXshSLSSG),A
LD (_IXshSLSSG2),A
ADD A,0-6
EXA
_IXshSLSSG=$+2
LD A,(IX)
SLSSGa=$+1
ADD A,0
_IXshSLSSG2=$+2
LD (IX),A
EXA
CALL WRITEREG
JP tfm_parse0
parseVOSSG
ADD A,8
ADD A,12-8
LD (_IXshVOSSG),A
SUB 12-8
EXA
LD A,(HL)
_IXshVOSSG=$+2
LD (IX),A
SUB 4
jr NC,$+3
XOR A
EXA
CALL WRITEREG
INCHL
JP tfm_parse0
parseFRSSG
ADD A,6
LD (_IXshFRSSG),A
SUB 6
EXA
LD A,(HL)
_IXshFRSSG=$+2
LD (IX),A
EXA
CALL WRITEREG
INCHL
JP tfm_parse0
parseH1SSG
;A=0/1 - dec/inc HfrqSSGA
;2/3 - B
;4/5 - C
PUSH AF
AND 1
SUB 1
SBC A,-1
LD (H1SSGa),A
POP AF
OR 1
ADD A,6
LD (_IXshH1SSG),A
LD (_IXshH1SSG2),A
ADD A,0-6
EXA
_IXshH1SSG=$+2
LD A,(IX)
H1SSGa=$+1
ADD A,0
_IXshH1SSG2=$+2
LD (IX),A
EXA
CALL WRITEREG
JP tfm_parse0
IF PACK28
parseKEY
;A=0/1 - key OFF/OFFON chn A
;2/3 - B
;4/5 - C
PUSH AF
RRA
AND 3
EXA
LD A,#28
CALL WRITEREG ;key off
POP AF
RRA
JP NC,tfm_parse0
AND 3
OR #F0
EXA
LD A,#28
CALL WRITEREG ;key on
JP tfm_parse0
ENDIF
lows0 DS 3+3+6+3 ;l,h,SSGfrq,SSGv
lows1 DS 3+3+6+3
;msg DB "Sonic 3D Blast song #13"
;lmsg=$-msg
;tfmData=#C000
;name0 DB "sonic3d t"
;name1 DB "sonic3d 0"
;name3 DB "sonic3d 1"
;name4 DB "sonic3d 2"
;end
; ORG #5CDD
; DB "sonic3D B"
; INCLUDE "B:m2hr*",#C0
;ORG GO