?login_element?

Subversion Repositories NedoOS

Rev

Rev 1945 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

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