?login_element?

Subversion Repositories NedoOS

Rev

Rev 1760 | Rev 2033 | Go to most recent revision | 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.         sub 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.         sub 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.         sub 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.         sub 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 = 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.  
  124. ;       call gssoftreset
  125. ;b==0 if no reply from GS
  126. ;       dec b
  127. ;       inc b
  128. ;       call z,gshardreset
  129.         call gshardreset
  130. ;b==0 if no reply from GS
  131.         ld a,b
  132.         cp 1
  133.         ld hl,nodevicestr
  134.         ret c
  135.  
  136. ;get chip id
  137.         call gsstartcode
  138.         SC CMDGETCHIPID
  139.         WC
  140.         WN
  141.         GD
  142.         ld (vsversion),a
  143.         call gscodereset
  144.  
  145.         ld a,(vsversion)
  146.         cp SS_VER_VS1103+1
  147.         ld hl,gsinitok
  148.         jr nc,.gsonly
  149.         rrca
  150.         rrca
  151.         add a,idtostr%256
  152.         ld l,a
  153.         adc a,idtostr/256
  154.         sub l
  155.         ld h,a
  156.         ld de,chipidstr
  157.         ld bc,4
  158.         ldir
  159.         ld hl,ngsinitokstr
  160. .gsonly
  161.         xor a
  162.         ld (isgsdisabled),a
  163.         ret
  164.  
  165. playerdeinit
  166.         ret
  167.  
  168. musicload
  169. ;cde = file extension
  170. ;hl = input file name
  171. ;out: zf=1 if the file is ready for playing, zf=0 otherwise
  172.         call ismodfile
  173.         ld a,1
  174.         jr z,$+3
  175.         dec a
  176.         ld (isplayingmodfile),a
  177.  
  178.         ex de,hl
  179.         call openstream_file
  180.         or a
  181.         ret nz
  182.  
  183. page8000=$+1
  184.         ld a,0
  185.         SETPG8000
  186. pageC000=$+1
  187.         ld a,0
  188.         SETPGC000
  189.  
  190.         ld a,(isplayingmodfile)
  191.         or a
  192.         jr nz,loadmod
  193.  
  194.         ld a,(filehandle)
  195.         ld b,a
  196.         OS_GETFILESIZE
  197.         ld a,e
  198.         call setprogressdelta
  199.  
  200.         call gsstartcode
  201.  
  202.         ld hl,firstpaddingframedata
  203.         ld (paddingframedataptr),hl
  204.         ld hl,0
  205.         ld (paddingframecount),hl
  206.         ld (bufferdataleft),hl
  207.  
  208.         xor a
  209.         ret
  210.  
  211. TITLELENGTH = 64
  212. MODHEADERSIZE = 1084
  213.  
  214. loadmod
  215.         ld hl,MODHEADERSIZE
  216.         ld de,BUFADDR
  217.         call readstream_file
  218. ;init progress
  219.         call getmodtype
  220.         ld a,(BUFADDR+950)
  221.         jr z,$+5
  222.         ld a,(BUFADDR+470)
  223.         call setprogressdelta
  224. ;set title
  225.         ld hl,titlestr
  226.         ld (MUSICTITLEADDR),hl
  227.         ld de,BUFADDR
  228.         ld b,TITLELENGTH+1
  229. .copytitleloop
  230.         ld a,(de)
  231.         ld (hl),a
  232.         inc de
  233.         inc hl
  234.         dec b
  235.         or a
  236.         jr nz,.copytitleloop
  237.         dec hl
  238. .filltitleloop
  239.         ld (hl),' '
  240.         inc hl
  241.         djnz .filltitleloop
  242.         ld (hl),0
  243. ;load module
  244.         SC 0x30
  245.         WC
  246. ;open stream
  247.         SC 0xD1
  248.         WC
  249. ;upload file
  250.         ld hl,BUFADDR
  251.         ld bc,MODHEADERSIZE
  252. .uploadloop
  253.         ld a,(hl)
  254.         out (GSDAT),a
  255.         WD
  256.         inc hl
  257.         dec bc
  258.         ld a,b
  259.         or c
  260.         jr nz,.uploadloop
  261.         ld hl,BUFSIZE
  262.         ld de,BUFADDR
  263.         push de
  264.         call readstream_file
  265.         ex (sp),hl
  266.         pop bc
  267.         ld a,b
  268.         or c
  269.         jr nz,.uploadloop
  270.         call closestream_file
  271. ;close stream
  272.         SC 0xD2
  273.         WC
  274. ;play module
  275.         ld a,1
  276.         out (GSDAT),a
  277.         SC 0x31
  278.         WC
  279.         xor a
  280.         ld (currentposition),a
  281.         ret
  282.  
  283. musicunload
  284.         ld a,(isplayingmodfile)
  285.         or a
  286.         jr nz,unloadmod
  287.  
  288.         call closestream_file
  289.         jp gscodereset
  290.  
  291. unloadmod
  292.         SC 0xf3
  293.         WC
  294.         ret
  295.  
  296. musicplay
  297. ;out: zf=0 if still playing, zf=1 otherwise
  298. isplayingmodfile=$+1
  299.         ld a,0
  300.         or a
  301.         jr nz,playmod
  302.  
  303. bufferreadptr=$+1
  304.         ld hl,0
  305. bufferdataleft=$+1
  306.         ld bc,0
  307.         ld a,c
  308.         or b
  309.         jr nz,checkifcanupload
  310. readfilechunk
  311.         ld hl,(paddingframecount)
  312.         ld de,150
  313.         sub hl,de
  314.         sbc a
  315.         ret z
  316.         call readdata
  317.         ld hl,BUFADDR
  318.         ex de,hl
  319.         sub hl,de
  320.         ld b,l
  321.         dec hl
  322.         inc h
  323.         ld c,h
  324.         ex de,hl
  325.         jr checkifcanupload
  326.  
  327. uploaddataloop
  328.         ld a,(hl)
  329.         out (GSDAT),a
  330.         WD
  331.         inc hl
  332.         djnz uploaddataloop
  333.         dec c
  334.         jr z,readfilechunk          ;done uploading current chunk
  335.         bit 0,c
  336.         jr z,uploaddataloop         ;poll GS once per 512 bytes
  337. checkifcanupload
  338.         SC CMDGETFREEBUFFERSPACE
  339.         WC
  340.         WN
  341.         GD
  342.         cp 6
  343.         jr nc,uploaddataloop        ;keep uploading until we have less than 1024 free buffer space
  344.  
  345.         ld (bufferreadptr),hl
  346.         ld (bufferdataleft),bc
  347.  
  348.         YIELD
  349.  
  350.         or 1
  351.         ret
  352.  
  353. playmod
  354.         YIELD
  355.         YIELD
  356.         YIELD
  357.         YIELD
  358. ;update progress
  359.         SC 0x60
  360.         WC
  361.         WN
  362.         GD
  363.         push af
  364.         call updateprogress
  365.         pop af
  366. ;check if the position is increasing monotonically
  367.         ld hl,currentposition
  368.         cp (hl)
  369.         ld (hl),a
  370.         ccf
  371.         sbc a
  372.         ret
  373.  
  374. readdata
  375. ;out: de = past-the-end data pointer
  376.         ld hl,(paddingframecount)
  377.         ld a,l
  378.         or h
  379.         ld hl,BUFSIZE
  380.         ld de,BUFADDR
  381.         jr nz,writepadding
  382.         call readstream_file
  383.         ld bc,hl
  384.         ld hl,BUFADDR
  385.         add hl,bc
  386.         ex de,hl
  387.         ld hl,BUFSIZE
  388.         sub hl,bc
  389.         jr nz,writepadding
  390. ;update progress
  391.         ld hl,(filechunkcounter)
  392.         ld de,BUFSIZE>>8 ;256 bytes chunks
  393.         add hl,de
  394.         ld (filechunkcounter),hl
  395.         ld a,h
  396.         call updateprogress
  397.         ld de,(BUFADDR+BUFSIZE)%65536
  398.         ret
  399.  
  400. writepadding
  401.         ld bc,paddingframedata_end-paddingframedata
  402.         sub hl,bc
  403.         ret c
  404.         push hl
  405. paddingframedataptr=$+1
  406.         ld hl,0
  407.         ldir
  408.         ld hl,paddingframedata
  409.         ld (paddingframedataptr),hl
  410. paddingframecount=$+1
  411.         ld hl,0
  412.         inc hl
  413.         ld (paddingframecount),hl
  414.         pop hl
  415.         jr writepadding
  416.  
  417. gshardreset
  418. ;out: b!=0 if got reply from GS, b==0 otherwise
  419.         ld a,C_GRST
  420.         out (GSCTR),a               ;hw reset
  421.         YIELD
  422.         YIELD
  423.         YIELD
  424. gssoftreset
  425.         SC 0xf3                     ;GS reset
  426.         ld b,50                     ;max spins
  427. wcloop
  428.         push bc
  429.         YIELD
  430.         pop bc
  431.         dec b
  432.         ret z
  433.         in a,(GSCOM)
  434.         rrca
  435.         jr c,wcloop
  436.         ret
  437.  
  438. gsstartcode
  439.         ld bc,GSDAT
  440.         ld de,gscode_end-gscode
  441.         ld hl,GSPROGSTART
  442.         out (c),e
  443.         SC 0x14
  444.         WC
  445.         out (c),d
  446.         WD
  447.         out (c),l
  448.         WD
  449.         out (c),h
  450.         WD
  451. ;start upload
  452.         ld hl,gscode
  453. .uploadloop
  454.         outi
  455.         WD
  456.         dec de
  457.         ld a,d
  458.         or e
  459.         jr nz,.uploadloop
  460. ;launch the code
  461.         ld hl,GSPROGSTART
  462.         out (c),l
  463.         SC 0x13
  464.         WC
  465.         out (c),h
  466.         WD
  467. ;the code is starting
  468.         YIELD
  469.         YIELD
  470.         YIELD
  471.         ret
  472.  
  473. getmodtype
  474. ;https://github.com/psbhlw/gs-firmware/blob/6c783a56147511b43d197e4079e993c2b94b4f12/firmware/src/PLAY.a80#L27
  475. ;out: zf=0 for SoundTracker 4/15 file, zf=1 otherwise
  476.         LD A,(BUFADDR+1080)
  477.         CP "M"
  478.         JR Z,TTY1
  479.         CP "4"
  480.         JR Z,TTY1
  481.         CP "F"
  482.         JR Z,TTY1
  483.         ret
  484. TTY1    LD A,(BUFADDR+1081)
  485.         CP "."
  486.         JR Z,TTY2
  487.         CP "L"
  488.         JR Z,TTY2
  489.         CP "!"
  490.         JR Z,TTY2
  491.         CP "C"
  492.         JR Z,TTY2
  493.         ret
  494. TTY2    LD A,(BUFADDR+1082)
  495.         CP "K"
  496.         ret z
  497.         CP "T"
  498.         ret z
  499.         CP "H"
  500.         ret
  501.  
  502. gscodereset
  503.         SC CMDRESET
  504.         WC
  505.         ret
  506.  
  507. firstpaddingframedata
  508.         db 0xFF,0xFB,0x90,0x64,0x00,0x0F,0xF0,0x00,0x00
  509.         db 0x69,0x00,0x00,0x00,0x08,0x00,0x00,0x0D,0x20
  510.         db 0x00,0x00,0x01,0x00,0x00,0x01,0xA4,0x00,0x00
  511.         db 0x00,0x20,0x00,0x00,0x34,0x80,0x00,0x00,0x04
  512.         ds 381,0x55
  513. firstpaddingframedata_end
  514.  
  515. paddingframedata
  516.         db 0xFF,0xFB,0x90,0x64,0x40,0x8F,0xF0,0x00,0x00
  517.         db 0x69,0x00,0x00,0x00,0x08,0x00,0x00,0x0D,0x20
  518.         db 0x00,0x00,0x01,0x00,0x00,0x01,0xA4,0x00,0x00
  519.         db 0x00,0x20,0x00,0x00,0x34,0x80,0x00,0x00,0x04
  520.         ds 381,0x55
  521. paddingframedata_end
  522.  
  523. gscode
  524.         incbin "gscode.bin"
  525. gscode_end
  526.  
  527.         include "../_sdk/file.asm"
  528.         include "progress.asm"
  529.  
  530. SS_VER_VS1001 = 0x00
  531. SS_VER_VS1011 = 0x10
  532. SS_VER_VS1002 = 0x20
  533. SS_VER_VS1003 = 0x30
  534. SS_VER_VS1053 = 0x40
  535. SS_VER_VS8053 = 0x40
  536. SS_VER_VS1033 = 0x50
  537. SS_VER_VS1063 = 0x60
  538. SS_VER_VS1103 = 0x70
  539.  
  540. idtostr
  541.         db "1001"
  542.         db "1011"
  543.         db "1002"
  544.         db "1003"
  545.         db "1053"
  546.         db "1033"
  547.         db "1063"
  548. ngsinitokstr
  549.         db "NeoGS with VS"
  550. chipidstr
  551.         db "????\r\n",0
  552. gsinitok
  553.         db "GS\r\n",0
  554. nodevicestr
  555.         db "no device!\r\n",0
  556. playernamestr
  557.         db "GS/NeoGS",0
  558. end
  559.  
  560. currentposition
  561.         ds 1
  562. filechunkcounter
  563.         ds 2
  564. titlestr
  565.         ds TITLELENGTH+1
  566.  
  567.         savebin "mp3.bin",begin,end-begin
  568.