?login_element?

Subversion Repositories NedoOS

Rev

Rev 2033 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; Player for NeoGS decoder chip (also GS/NeoGS .mod player)
  2. ; Supports a range of VLSI decoders: VS1001, VS1011, VS1003, VS1033, VS1053
  3.  
  4.         DEVICE ZXSPECTRUM128
  5.         include "../_sdk/sys_h.asm"
  6.         include "ngsdec/gscodedefs.asm"
  7.         include "ngsdec/gsports.asm"
  8.         include "ngsdec/vs10xx.asm"
  9.         include "playerdefs.asm"
  10.  
  11. BUFADDR = 0x8000
  12. BUFSIZE = 0x8000
  13.  
  14.         org PLAYERSTART
  15.  
  16. begin   PLAYERHEADER
  17.  
  18. isfilesupported
  19. ;cde = file extension
  20. ;out: zf=1 if this player can handle the file and the sound hardware is available, zf=0 otherwise
  21. isgsdisabled=$+1
  22.         jr nosupportedfiles
  23.         call ismodfile
  24.         jr nz,checkmid
  25.         ld hl,0
  26.         ld (MUSICTITLEADDR),hl
  27.         ld hl,musicprogress+1
  28.         ld (MUSICPROGRESSADDR),hl
  29.         jp initprogress
  30. nosupportedfiles
  31.         or 1
  32.         ret
  33. checkmid
  34. vsversion=$+1
  35.         ld a,255
  36.         ld l,'m'
  37.         ld h,b
  38.         sub hl,bc
  39.         jr nz,checkogg
  40.         ld hl,'id'
  41.         sbc hl,de
  42.         jr nz,checkogg
  43.         cp SS_VER_VS1003
  44.         jr z,initmidvars
  45.         cp SS_VER_VS1033
  46.         jr z,initmidvars
  47.         cp SS_VER_VS1053
  48.         jr z,initmidvars
  49.         cp SS_VER_VS1103
  50.         ret nz
  51. initmidvars
  52.         ld (filechunkcounter),hl
  53.         ld (MUSICTITLEADDR),hl
  54.         ld (MUSICPROGRESSADDR),hl
  55.         jp initprogress
  56. checkogg
  57.         ld l,'o'
  58.         ld h,b
  59.         sub hl,bc
  60.         jr nz,checkaac
  61.         ld hl,'gg'
  62.         sbc hl,de
  63.         jr nz,checkaac
  64.         cp SS_VER_VS1053
  65.         jr z,initmp3vars
  66.         cp SS_VER_VS1063
  67.         jr z,initmp3vars
  68.         ret    
  69. checkaac
  70.         ld l,'a'
  71.         ld h,b
  72.         sub hl,bc
  73.         jr nz,checkmp3
  74.         ld hl,'ac'
  75.         sbc hl,de
  76.         jr nz,checkmp3
  77.         cp SS_VER_VS1033
  78.         jr z,initmp3vars
  79.         cp SS_VER_VS1053
  80.         jr z,initmp3vars
  81.         cp SS_VER_VS1063
  82.         jr z,initmp3vars
  83.         ret
  84. checkmp3
  85.         ld l,'m'
  86.         ld h,b
  87.         sub hl,bc
  88.         ret nz
  89.         ld hl,'p3'
  90.         sbc hl,de
  91.         ret nz
  92.         and ~SS_VER_MASK
  93.         ret nz
  94. initmp3vars
  95.         ld (filechunkcounter),hl
  96.         ld (MUSICTITLEADDR),hl
  97.         ld hl,musicprogress+1
  98.         ld (MUSICPROGRESSADDR),hl
  99.         jp initprogress
  100.  
  101. ismodfile
  102. ;cde = file extension
  103. ;out: zf=1 if .mod, zf=0 otherwise
  104.         ld a,'m'
  105.         cp c
  106.         ret nz
  107.         ld a,'o'
  108.         cp d
  109.         ret nz
  110.         ld a,'d'
  111.         cp e
  112.         ret
  113.  
  114. playerinit
  115. ;hl,ix = GPSETTINGS
  116. ;a = player page
  117. ;out: zf=1 if init is successful, hl=init message
  118.         ld a,(hl)
  119.         ld (page8000),a
  120.         inc hl
  121.         ld a,(hl)
  122.         ld (pageC000),a
  123. ;       call gssoftreset
  124. ;b==0 if no reply from GS
  125. ;       dec b
  126. ;       inc b
  127. ;       call z,gshardreset
  128.         call gshardreset
  129. ;b==0 if no reply from GS
  130.         ld a,b
  131.         cp 1
  132.         ld hl,nodevicestr
  133.         ret c
  134. ;get chip id
  135.         call gsstartcode
  136.         SC CMDGETCHIPID
  137.         WC
  138.         WN
  139.         GD
  140.         ld (vsversion),a
  141.         call gscodereset
  142.         ld a,(vsversion)
  143.         cp SS_VER_VS1103+1
  144.         ld hl,gsinitok
  145.         jr nc,.gsonly
  146.         rrca
  147.         rrca
  148.         add a,idtostr%256
  149.         ld l,a
  150.         adc a,idtostr/256
  151.         sub l
  152.         ld h,a
  153.         ld de,chipidstr
  154.         ld bc,4
  155.         ldir
  156.         ld hl,ngsinitokstr
  157. .gsonly
  158.         xor a
  159.         ld (isgsdisabled),a
  160.         ret
  161.  
  162. playerdeinit
  163.         ret
  164.  
  165. musicload
  166. ;cde = file extension
  167. ;hl = input file name
  168. ;out: a = device mask, zf=1 if the file is ready for playing, zf=0 otherwise
  169.         call ismodfile
  170.         ld a,1
  171.         jr z,$+3
  172.         dec a
  173.         ld (isplayingmodfile),a
  174.         ex de,hl
  175.         call openstream_file
  176.         or a
  177.         ret nz
  178. page8000=$+1
  179.         ld a,0
  180.         SETPG8000
  181. pageC000=$+1
  182.         ld a,0
  183.         SETPGC000
  184.         ld a,(isplayingmodfile)
  185.         or a
  186.         jr nz,loadmod
  187.         ld a,(filehandle)
  188.         ld b,a
  189.         OS_GETFILESIZE
  190.         ld a,e
  191.         call setprogressdelta
  192.         call gsstartcode
  193.         ld hl,firstpaddingframedata
  194.         ld (paddingframedataptr),hl
  195.         ld hl,0
  196.         ld (paddingframecount),hl
  197.         ld (bufferdataleft),hl
  198.         ld a,DEVICE_NEOGS_MASK
  199.         cp a
  200.         ret
  201.  
  202. TITLELENGTH = 64
  203. MODHEADERSIZE = 1084
  204.  
  205. loadmod
  206.         ld hl,MODHEADERSIZE
  207.         ld de,BUFADDR
  208.         call readstream_file
  209. ;init progress
  210.         call getmodtype
  211.         ld a,(BUFADDR+950)
  212.         jr z,$+5
  213.         ld a,(BUFADDR+470)
  214.         call setprogressdelta
  215. ;set title
  216.         ld hl,titlestr
  217.         ld (MUSICTITLEADDR),hl
  218.         ld de,BUFADDR
  219.         ld b,TITLELENGTH+1
  220. .copytitleloop
  221.         ld a,(de)
  222.         ld (hl),a
  223.         inc de
  224.         inc hl
  225.         dec b
  226.         or a
  227.         jr nz,.copytitleloop
  228.         dec hl
  229. .filltitleloop
  230.         ld (hl),' '
  231.         inc hl
  232.         djnz .filltitleloop
  233.         ld (hl),0
  234. ;load module
  235.         SC 0x30
  236.         WC
  237. ;open stream
  238.         SC 0xD1
  239.         WC
  240. ;upload file
  241.         ld hl,BUFADDR
  242.         ld bc,MODHEADERSIZE
  243. .uploadloop
  244.         ld a,(hl)
  245.         out (GSDAT),a
  246.         WD
  247.         inc hl
  248.         dec bc
  249.         ld a,b
  250.         or c
  251.         jr nz,.uploadloop
  252.         ld hl,BUFSIZE
  253.         ld de,BUFADDR
  254.         push de
  255.         call readstream_file
  256.         ex (sp),hl
  257.         pop bc
  258.         ld a,b
  259.         or c
  260.         jr nz,.uploadloop
  261.         call closestream_file
  262. ;close stream
  263.         SC 0xD2
  264.         WC
  265. ;play module
  266.         ld a,1
  267.         out (GSDAT),a
  268.         SC 0x31
  269.         WC
  270.         xor a
  271.         ld (currentposition),a
  272.         ld a,DEVICE_GS_MASK
  273.         ret
  274.  
  275. musicunload
  276.         ld a,(isplayingmodfile)
  277.         or a
  278.         jr nz,unloadmod
  279.         call closestream_file
  280.         jp gscodereset
  281.  
  282. unloadmod
  283.         SC 0xf3
  284.         WC
  285.         ret
  286.  
  287. musicplay
  288. ;out: zf=0 if still playing, zf=1 otherwise
  289. isplayingmodfile=$+1
  290.         ld a,0
  291.         or a
  292.         jr nz,playmod
  293.  
  294. bufferreadptr=$+1
  295.         ld hl,0
  296. bufferdataleft=$+1
  297.         ld bc,0
  298.         ld a,c
  299.         or b
  300.         jr nz,checkifcanupload
  301. readfilechunk
  302.         ld hl,(paddingframecount)
  303.         ld de,150
  304.         sub hl,de
  305.         sbc a
  306.         ret z
  307.         call readdata
  308.         ld hl,BUFADDR
  309.         ex de,hl
  310.         sub hl,de
  311.         ld b,l
  312.         dec hl
  313.         inc h
  314.         ld c,h
  315.         ex de,hl
  316.         jr checkifcanupload
  317.  
  318. uploaddataloop
  319.         ld a,(hl)
  320.         out (GSDAT),a
  321.         WD
  322.         inc hl
  323.         djnz uploaddataloop
  324.         dec c
  325.         jr z,readfilechunk          ;done uploading current chunk
  326.         bit 0,c
  327.         jr z,uploaddataloop         ;poll GS once per 512 bytes
  328. checkifcanupload
  329.         SC CMDGETFREEBUFFERSPACE
  330.         WC
  331.         WN
  332.         GD
  333.         cp 6
  334.         jr nc,uploaddataloop        ;keep uploading until we have less than 1024 free buffer space
  335.         ld (bufferreadptr),hl
  336.         ld (bufferdataleft),bc
  337.         YIELD
  338.         or 1
  339.         ret
  340.  
  341. playmod
  342.         YIELD
  343.         YIELD
  344.         YIELD
  345.         YIELD
  346. ;update progress
  347.         SC 0x60
  348.         WC
  349.         WN
  350.         GD
  351.         push af
  352.         call updateprogress
  353.         pop af
  354. ;check if the position is increasing monotonically
  355.         ld hl,currentposition
  356.         cp (hl)
  357.         ld (hl),a
  358.         ccf
  359.         sbc a
  360.         ret
  361.  
  362. readdata
  363. ;out: de = past-the-end data pointer
  364.         ld hl,(paddingframecount)
  365.         ld a,l
  366.         or h
  367.         ld hl,BUFSIZE
  368.         ld de,BUFADDR
  369.         jr nz,writepadding
  370.         call readstream_file
  371.         ld bc,hl
  372.         ld hl,BUFADDR
  373.         add hl,bc
  374.         ex de,hl
  375.         ld hl,BUFSIZE
  376.         sub hl,bc
  377.         jr nz,writepadding
  378. ;update progress
  379.         ld hl,(filechunkcounter)
  380.         ld de,BUFSIZE>>8 ;256 bytes chunks
  381.         add hl,de
  382.         ld (filechunkcounter),hl
  383.         ld a,h
  384.         call updateprogress
  385.         ld de,(BUFADDR+BUFSIZE)%65536
  386.         ret
  387.  
  388. writepadding
  389.         ld bc,paddingframedata_end-paddingframedata
  390.         sub hl,bc
  391.         ret c
  392.         push hl
  393. paddingframedataptr=$+1
  394.         ld hl,0
  395.         ldir
  396.         ld hl,paddingframedata
  397.         ld (paddingframedataptr),hl
  398. paddingframecount=$+1
  399.         ld hl,0
  400.         inc hl
  401.         ld (paddingframecount),hl
  402.         pop hl
  403.         jr writepadding
  404.  
  405. gshardreset
  406. ;out: b!=0 if got reply from GS, b==0 otherwise
  407.         ld a,C_GRST
  408.         out (GSCTR),a               ;hw reset
  409.         YIELD
  410.         YIELD
  411.         YIELD
  412. gssoftreset
  413.         SC 0xf3                     ;GS reset
  414.         ld b,50                     ;max spins
  415. wcloop
  416.         push bc
  417.         YIELD
  418.         pop bc
  419.         dec b
  420.         ret z
  421.         in a,(GSCOM)
  422.         rrca
  423.         jr c,wcloop
  424.         ret
  425.  
  426. gsstartcode
  427.         ld bc,GSDAT
  428.         ld de,gscode_end-gscode
  429.         ld hl,GSPROGSTART
  430.         out (c),e
  431.         SC 0x14
  432.         WC
  433.         out (c),d
  434.         WD
  435.         out (c),l
  436.         WD
  437.         out (c),h
  438.         WD
  439. ;start upload
  440.         ld hl,gscode
  441. .uploadloop
  442.         outi
  443.         WD
  444.         dec de
  445.         ld a,d
  446.         or e
  447.         jr nz,.uploadloop
  448. ;launch the code
  449.         ld hl,GSPROGSTART
  450.         out (c),l
  451.         SC 0x13
  452.         WC
  453.         out (c),h
  454.         WD
  455. ;the code is starting
  456.         YIELD
  457.         YIELD
  458.         YIELD
  459.         ret
  460.  
  461. getmodtype
  462. ;https://github.com/psbhlw/gs-firmware/blob/6c783a56147511b43d197e4079e993c2b94b4f12/firmware/src/PLAY.a80#L27
  463. ;out: zf=0 for SoundTracker 4/15 file, zf=1 otherwise
  464.         LD A,(BUFADDR+1080)
  465.         CP "M"
  466.         JR Z,TTY1
  467.         CP "4"
  468.         JR Z,TTY1
  469.         CP "F"
  470.         JR Z,TTY1
  471.         ret
  472. TTY1    LD A,(BUFADDR+1081)
  473.         CP "."
  474.         JR Z,TTY2
  475.         CP "L"
  476.         JR Z,TTY2
  477.         CP "!"
  478.         JR Z,TTY2
  479.         CP "C"
  480.         JR Z,TTY2
  481.         ret
  482. TTY2    LD A,(BUFADDR+1082)
  483.         CP "K"
  484.         ret z
  485.         CP "T"
  486.         ret z
  487.         CP "H"
  488.         ret
  489.  
  490. gscodereset
  491.         SC CMDRESET
  492.         WC
  493.         ret
  494.  
  495. firstpaddingframedata
  496.         db 0xFF,0xFB,0x90,0x64,0x00,0x0F,0xF0,0x00,0x00
  497.         db 0x69,0x00,0x00,0x00,0x08,0x00,0x00,0x0D,0x20
  498.         db 0x00,0x00,0x01,0x00,0x00,0x01,0xA4,0x00,0x00
  499.         db 0x00,0x20,0x00,0x00,0x34,0x80,0x00,0x00,0x04
  500.         ds 381,0x55
  501. firstpaddingframedata_end
  502.  
  503. paddingframedata
  504.         db 0xFF,0xFB,0x90,0x64,0x40,0x8F,0xF0,0x00,0x00
  505.         db 0x69,0x00,0x00,0x00,0x08,0x00,0x00,0x0D,0x20
  506.         db 0x00,0x00,0x01,0x00,0x00,0x01,0xA4,0x00,0x00
  507.         db 0x00,0x20,0x00,0x00,0x34,0x80,0x00,0x00,0x04
  508.         ds 381,0x55
  509. paddingframedata_end
  510.  
  511. gscode
  512.         incbin "gscode.bin"
  513. gscode_end
  514.  
  515.         include "../_sdk/file.asm"
  516.         include "progress.asm"
  517.  
  518. SS_VER_VS1001 = 0x00
  519. SS_VER_VS1011 = 0x10
  520. SS_VER_VS1002 = 0x20
  521. SS_VER_VS1003 = 0x30
  522. SS_VER_VS1053 = 0x40
  523. SS_VER_VS8053 = 0x40
  524. SS_VER_VS1033 = 0x50
  525. SS_VER_VS1063 = 0x60
  526. SS_VER_VS1103 = 0x70
  527.  
  528. idtostr
  529.         db "1001"
  530.         db "1011"
  531.         db "1002"
  532.         db "1003"
  533.         db "1053"
  534.         db "1033"
  535.         db "1063"
  536. ngsinitokstr
  537.         db "NeoGS with VS"
  538. chipidstr
  539.         db "????\r\n",0
  540. gsinitok
  541.         db "GS\r\n",0
  542. nodevicestr
  543.         db "no device!\r\n",0
  544. playernamestr
  545.         db "GS/NeoGS",0
  546. end
  547.  
  548. currentposition
  549.         ds 1
  550. filechunkcounter
  551.         ds 2
  552. titlestr
  553.         ds TITLELENGTH+1
  554.  
  555.         savebin "mp3.bin",begin,end-begin
  556.