?login_element?

Subversion Repositories NedoOS

Rev

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

  1.         DEVICE ZXSPECTRUM128
  2.         include "gsports.asm"
  3.         include "gscodedefs.asm"
  4.         include "vs10xx.asm"
  5.  
  6. XTALI_FREQ = 14000000 ;14mhz on NGS
  7. CLOCKF_VS1011 = 0x8000|((XTALI_FREQ+1000)/2000) ;28mhz
  8. CLOCKF_VS1033 = ((XTALI_FREQ-8000000+2000)/4000)|SC_MULT_03_35X|SC_ADD_03_00X ;49mhz
  9. CLOCKF_VS1053 = ((XTALI_FREQ-8000000+2000)/4000)|SC_MULT_53_40X|SC_ADD_53_00X ;56mhz
  10.  
  11.         MACRO WDC
  12. ;        in a,(SSTAT)
  13. ;        and M_MCRDY
  14. ;        jr z,$-4
  15. ;TODO: why MCRDY polling works fine on real hardware, but not in UnrealSpeccy?
  16. ;Neo Player Light does this
  17.         call noper
  18.         ENDM
  19.  
  20.         MACRO WDD
  21.         in a,(SSTAT)
  22.         rrca
  23.         jr nc,$-3
  24.         ENDM
  25.  
  26.         MACRO ATOZX
  27.         out (ZXDATWR),a
  28.         in a,(ZXSTAT)
  29.         rlca
  30.         jr c,$-3
  31.         ENDM
  32.  
  33.         MACRO CALCFREEBUFFERSPACE
  34.         ld a,h
  35.         sub d
  36.         and 0x7f
  37.         ENDM
  38.  
  39.         MACRO LOAD256 IENABLED
  40. .loadloop
  41.         in a,(ZXSTAT)                         ;check if data or command is pending
  42.         and M_CBIT|M_DBIT
  43.         jr z,.loadloop
  44.         rlca
  45.         jr c,.loaddata
  46. ;got command
  47.         IF IENABLED
  48.         di
  49.         ENDIF
  50.         call processcommand
  51.         IF IENABLED
  52.         ei
  53.         ENDIF
  54.         jr .loadloop
  55. .loaddata
  56.         in a,(ZXDATRD)
  57.         ld (de),a
  58.         inc e
  59.         jr nz,.loadloop
  60.         inc d
  61.         ENDM
  62.  
  63.         org GSPROGSTART
  64. begin   di
  65.         ld sp,GSSTACKADDR
  66.         call checkifngs
  67. ;uploading is done via interrupt handler
  68.         ld hl,interrupthandler
  69.         ld (GSINTERRUPTTABLEENTRYADDR),hl
  70.         ld a,GSINTERRUPTTABLEENTRYADDR>>8
  71.         ld i,a
  72.         im 2
  73.         call mutemod
  74.         ld a,%10011100
  75.         out (SCTRL),a
  76. ;set ngs to 10mhz
  77.         ld d,C_10MHZ
  78.         call ngssetfreq
  79. ;hw decoder reset
  80.         ld a,M_MPXRS
  81.         out (SCTRL),a
  82.         WDC
  83. ;clear reset signal
  84.         ld a,M_MPXRS|M_SETNCLR
  85.         out (SCTRL),a
  86. ;go to 12mhz
  87.         ld d,C_12MHZ
  88.         call ngssetfreq
  89. ;write to a register after reset
  90.         ld l,SCI_VOL
  91.         ld de,SV_SILENCE
  92.         call vswriteregister
  93. ;read chip id
  94.         ld l,SCI_STATUS
  95.         call vsreadregister
  96.         ld a,e
  97.         and SS_VER_MASK
  98.         ld (vsversion),a
  99. ;set an arbitrary writable page for the ring buffer in 0x8000...0xffff
  100.         ld a,2
  101.         out (MPAG),a
  102. startnewstream
  103.         call vssoftreset                      ;reset decoder setting SDI to compatibility mode
  104. ;start preloading
  105.         ld h,0x70
  106.         ld de,0x8000                          ;de is ring buffer write pointer
  107. preloadloop
  108.         LOAD256 0
  109.         ld a,d
  110.         cp 0xdf
  111.         jr c,preloadloop
  112. ;start uploading
  113.         ld hl,0x8000                          ;hl is ring buffer read pointer
  114.         ei
  115. mainloop
  116.         in a,(ZXSTAT)                         ;check if a command is pending
  117.         rrca
  118.         jr nc,checkifcandownload
  119. ;handle command
  120.         di
  121.         call processcommand
  122.         ei
  123.         jr mainloop
  124. checkifcandownload
  125.         CALCFREEBUFFERSPACE
  126.         cp 3
  127.         jr c,mainloop                         ;keep read and write addresses of the ring buffer at least 256 bytes apart
  128.         LOAD256 1
  129.         set 7,d
  130.         jr mainloop
  131.  
  132. interrupthandler
  133.         push af
  134.         push bc
  135.         ld a,d
  136.         sub h
  137.         and 0x7f
  138.         cp 3
  139.         jr c,skipupload                       ;keep read and write addresses of the ring buffer at least 256 bytes apart
  140.         in a,(SSTAT)
  141.         rrca
  142.         jr nc,skipupload                      ;check if data requested
  143.         ld b,32                               ;upload 32 bytes
  144. uploadloop
  145.         ld a,(hl)
  146.         out (MD_SEND),a
  147.         inc hl
  148.         djnz uploadloop
  149.         set 7,h                               ;make sure the address didn't wrap under 0x8000
  150. ;blink LED
  151. ;        ld a,h
  152. ;        rlca
  153. ;        rlca
  154. ;        out (LEDCTR),a
  155. skipupload
  156.         pop bc
  157.         pop af
  158.         ei
  159.         ret
  160.  
  161. vssoftreset
  162.         ld l,SCI_VOL
  163.         ld de,SV_SILENCE
  164.         call vswriteregister                  ;set volume to minimum
  165.         ld l,SCI_MODE
  166.         call vsreadregister
  167.         ld a,e
  168.         xor SM_RESET
  169.         ld e,a
  170.         ld a,d
  171.         and ~(SM_SDINEW>>8)                   ;NGS implements compatibility mode only
  172.         ld d,a
  173.         call vswriteregister                  ;reset
  174.         ld a,e
  175.         xor SM_RESET
  176.         ld e,a
  177.         call vswriteregister                  ;clear reset
  178. volumevalue=$+1
  179.         ld de,0
  180.         ld l,SCI_VOL
  181.         call vswriteregister                  ;restore volume
  182.         call vsclockvalue
  183.         ld l,SCI_CLOCKF
  184.         call vswriteregister                  ;set internal clock
  185. vsversion=$+1
  186.         ld a,255
  187.         cp SS_VER_VS1001
  188.         ret nz
  189.         ld l,0x02                             ;Force the clock-doubler on by writing 0x8008 to SCI_INT_FCTLH.
  190.         ld de,0x8008                          ;The datasheet states that you should never write to this register.
  191.         jr vswriteregister                    ;This is, however, an exception.
  192.  
  193. ;l = register
  194. ;de = value
  195. vswriteregister
  196.         WDD
  197.         WDC
  198.         ld a,M_MCNCS
  199.         out (SCTRL),a                         ;SCI start
  200.         WDC
  201.         ld bc,MC_SEND
  202.         ld a,2
  203.         out (c),a                             ;write op
  204.         WDC
  205.         out (c),l                             ;which register
  206.         WDC
  207.         out (c),d                             ;high byte
  208.         WDC
  209.         out (c),e                             ;low byte
  210.         WDC
  211.         ld a,M_MCNCS|M_SETNCLR
  212.         out (SCTRL),a                         ;SCI end
  213.         WDC
  214.         ret
  215.  
  216. ;l = register
  217. ;out: de = value
  218. vsreadregister
  219.         WDD
  220.         WDC
  221.         ld a,M_MCNCS
  222.         out (SCTRL),a                         ;SCI start
  223.         WDC
  224.         ld bc,MC_SEND
  225.         ld a,3
  226.         out (c),a                             ;read op
  227.         WDC
  228.         out (c),l                             ;which register
  229.         WDC
  230.         ld a,0xff
  231.         out (c),a
  232.         WDC
  233.         ld bc,MC_READ
  234.         in d,(c)                              ;high byte
  235.         WDC
  236.         ld a,0xff
  237.         out (MC_SEND),a
  238.         WDC
  239.         in e,(c)                              ;low byte
  240.         WDC
  241.         ld a,M_MCNCS|M_SETNCLR
  242.         out (SCTRL),a                         ;SCI end
  243.         WDC
  244.         ret
  245.  
  246. vsclockvalue
  247. ;out: de = CLOCKF value
  248.         ld a,(vsversion)
  249.         ld de,CLOCKF_VS1011
  250.         cp SS_VER_VS1001
  251.         ret z
  252.         cp SS_VER_VS1002
  253.         ret z
  254.         cp SS_VER_VS1011
  255.         ret z
  256.         ld de,CLOCKF_VS1033
  257.         cp SS_VER_VS1003
  258.         ret z
  259.         cp SS_VER_VS1033
  260.         ret z
  261.         ld de,CLOCKF_VS1053
  262.         ret
  263.  
  264. ngssetfreq
  265. ;d = frequency constant
  266.         in a,(GSCFG0)
  267.         and %11001111
  268.         or d
  269.         out (GSCFG0),a
  270.         ret
  271.  
  272. checkifngs
  273.         in a,(GSCFG0)
  274.         cp 255
  275.         ret nz
  276. .msgloop
  277.         in a,(ZXSTAT)
  278.         rrca
  279.         call c,processcommand
  280.         jr .msgloop
  281.  
  282. mutemod
  283.         xor a
  284.         out (VOL1),a
  285.         out (VOL2),a
  286.         out (VOL3),a
  287.         out (VOL4),a
  288.         out (VOL5),a
  289.         out (VOL6),a
  290.         out (VOL7),a
  291.         out (VOL8),a
  292.         ret
  293.  
  294. processcommand
  295.         in a,(ZXCMD)
  296.         cp CMDCOUNT
  297.         jr nc,cmdreset                        ;received an invalid command, so the player crashed?
  298.         rlca
  299.         ld (commandtable+1),a
  300.         out (CLRCBIT),a
  301. commandtable
  302.         jr $
  303.         jr cmdreset : assert CMDRESET==0
  304.         jr cmdgetfreebufferspace : assert CMDGETFREEBUFFERSPACE==1
  305.         jr cmdgetchipid : assert CMDGETCHIPID==2
  306.         jr cmdrestartstream : assert CMDRESTARTSTREAM==3
  307.         jr cmdvolumeup : assert CMDVOLUMEUP==4
  308.         jr cmdvolumedown : assert CMDVOLUMEDOWN==5
  309.  
  310. cmdreset
  311.         ld a,(vsversion)
  312.         inc a
  313.         jp z,0
  314.         call vssoftreset
  315.         ld d,C_20MHZ
  316.         call ngssetfreq
  317.         jp 0
  318.  
  319. cmdgetfreebufferspace
  320.         CALCFREEBUFFERSPACE
  321.         ATOZX
  322.         ret
  323.  
  324. cmdgetchipid
  325.         ld a,(vsversion)
  326.         ATOZX
  327.         ret
  328.  
  329. cmdrestartstream
  330.         ld sp,GSSTACKADDR
  331.         jp startnewstream
  332.  
  333. cmdvolumeup
  334.         ld a,(volumevalue)
  335.         or a
  336.         ret z
  337.         dec a
  338. setvolume
  339.         push hl
  340.         push de
  341.         push bc
  342.         ld e,a
  343.         ld d,a
  344.         ld (volumevalue),de
  345.         ld l,SCI_VOL
  346.         call vswriteregister
  347.         pop bc
  348.         pop de
  349.         pop hl
  350.         ret
  351.  
  352. cmdvolumedown
  353.         ld a,(volumevalue)
  354.         cp SV_SILENCE>>8
  355.         ret nc
  356.         inc a
  357.         jr setvolume
  358.  
  359. noper
  360.         ds 18,0
  361.         ret
  362.  
  363. end
  364.         savebin "gscode.bin",begin,end-begin
  365.