DEVICE ZXSPECTRUM128
include "../_sdk/sys_h.asm"
include "ngsdec/gscodedefs.asm"
include "ngsdec/gsports.asm"
include "ngsdec/vs10xx.asm"
include "playerdefs.asm"
BUFADDR = 0x8000
BUFSIZE = 0x8000
org PLAYERSTART
begin PLAYERHEADER
isfilesupported
;cde = file extension
vsversion=$+1
ld a,255
ld l,'m'
ld h,b
sub hl,bc
jr nz,checkogg
ld hl,'id'
sub hl,de
jr nz,checkogg
cp SS_VER_VS1003
ret z
cp SS_VER_VS1033
ret z
cp SS_VER_VS1053
ret z
cp SS_VER_VS1103
ret
checkogg
ld l,'o'
ld h,b
sub hl,bc
jr nz,checkaac
ld hl,'gg'
sub hl,de
jr nz,checkaac
cp SS_VER_VS1053
ret z
cp SS_VER_VS1063
ret
checkaac
ld l,'a'
ld h,b
sub hl,bc
jr nz,checkmp3
ld hl,'ac'
sub hl,de
jr nz,checkmp3
cp SS_VER_VS1033
ret z
cp SS_VER_VS1053
ret z
cp SS_VER_VS1063
ret
checkmp3
ld l,'m'
ld h,b
sub hl,bc
ret nz
ld hl,'p3'
sub hl,de
ret nz
and ~SS_VER_MASK
ret
playerinit
;hl = shared pages
;a = player page
ld a,(hl)
ld (page8000),a
inc hl
ld a,(hl)
ld (pageC000),a
; call gssoftreset
;b==0 if no reply from GS
; dec b
; inc b
; call z,gshardreset
call gshardreset
;b==0 if no reply from GS
ld a,b
cp 1
ret c
ld bc,GSDAT
ld de,gscode_end-gscode
ld hl,GSPROGSTART
out (c),e
SC 0x14
WC
out (c),d
WD
out (c),l
WD
out (c),h
WD
;start upload
ld hl,gscode
uploadcodeloop
outi
WD
dec de
ld a,d
or e
jr nz,uploadcodeloop
;launch the code
ld hl,GSPROGSTART
out (c),l
SC 0x13
WC
out (c),h
WD
;the code is starting
YIELD
YIELD
YIELD
;get chip id
SC CMDGETCHIPID
WC
WN
GD
ld (vsversion),a
xor a
ret
playerdeinit
ld a,(vsversion)
inc a
ret z
SC CMDRESTART
ret
musicload
;de = input file name
call openstream_file
or a
ret nz
page8000=$+1
ld a,0
SETPG8000
pageC000=$+1
ld a,0
SETPGC000
ld hl,firstpaddingframedata
ld (paddingframedataptr),hl
ld hl,0
ld (paddingframecount),hl
ld (bufferdataleft),hl
xor a
ret
musicunload
call closestream_file
SC CMDRESTARTSTREAM
WC
ret
musicplay
;out: zf=0 if still playing, zf=1 otherwise
bufferreadptr=$+1
ld hl,0
bufferdataleft=$+1
ld bc,0
ld a,c
or b
jr nz,checkifcanupload
readfilechunk
ld hl,(paddingframecount)
ld de,150
sub hl,de
sbc a
ret z
call readdata
ld hl,BUFADDR
ex de,hl
sub hl,de
ld b,l
dec hl
inc h
ld c,h
ex de,hl
jr checkifcanupload
uploaddataloop
ld a,(hl)
out (GSDAT),a
WD
inc hl
djnz uploaddataloop
dec c
jr z,readfilechunk ;done uploading current chunk
bit 0,c
jr z,uploaddataloop ;poll GS once per 512 bytes
checkifcanupload
SC CMDGETFREEBUFFERSPACE
WC
WN
GD
cp 6
jr nc,uploaddataloop ;keep uploading until we have less than 1024 free buffer space
ld (bufferreadptr),hl
ld (bufferdataleft),bc
YIELD
or 1
ret
readdata
;out: de = past-the-end data pointer
ld hl,(paddingframecount)
ld a,l
or h
ld hl,BUFSIZE
ld de,BUFADDR
jr nz,writepadding
call readstream_file
ld bc,hl
ld hl,BUFADDR
add hl,bc
ex de,hl
ld hl,BUFSIZE
sub hl,bc
ret z
writepadding
ld bc,paddingframedata_end-paddingframedata
sub hl,bc
ret c
push hl
paddingframedataptr=$+1
ld hl,0
ldir
ld hl,paddingframedata
ld (paddingframedataptr),hl
paddingframecount=$+1
ld hl,0
inc hl
ld (paddingframecount),hl
pop hl
jr writepadding
gshardreset
;out: b!=0 if got reply from GS, b==0 otherwise
ld a,C_GRST
out (GSCTR),a ;hw reset
YIELD
YIELD
YIELD
gssoftreset
SC 0xf3 ;GS reset
ld b,0x30 ;max spins
wcloop
push bc
YIELD
pop bc
dec b
ret z
in a,(GSCOM)
rrca
jr c,wcloop
ret
firstpaddingframedata
db 0xFF,0xFB,0x90,0x64,0x00,0x0F,0xF0,0x00,0x00
db 0x69,0x00,0x00,0x00,0x08,0x00,0x00,0x0D,0x20
db 0x00,0x00,0x01,0x00,0x00,0x01,0xA4,0x00,0x00
db 0x00,0x20,0x00,0x00,0x34,0x80,0x00,0x00,0x04
ds 381,0x55
firstpaddingframedata_end
paddingframedata
db 0xFF,0xFB,0x90,0x64,0x40,0x8F,0xF0,0x00,0x00
db 0x69,0x00,0x00,0x00,0x08,0x00,0x00,0x0D,0x20
db 0x00,0x00,0x01,0x00,0x00,0x01,0xA4,0x00,0x00
db 0x00,0x20,0x00,0x00,0x34,0x80,0x00,0x00,0x04
ds 381,0x55
paddingframedata_end
gscode
incbin "gscode.bin"
gscode_end
include "../_sdk/file.asm"
end
savebin "mp3.bin",begin,end-begin