Changes
PlayCity
,/* Technical description */
[[File:PlayCity.jpg|thumb|320px|]]
==Introduction==
==Hardware Installation==
* Power OFF your Amstrad / Schneider CPC.
* Attach the PlayCity board to one free MotherX4 slogslot.* Turn ON your computer, and enjoy! ==Peripheral Soft Reset==All expansion peripherals should be reset when an output is performed to I/O port '''$F8FF'''. Used by the standard BIOS functions'''MC_BOOT_PROGRAM''' and '''MC_START_PROGRAM''' (vectors $BD13 and $BD16), in particular a peripheral that generates interrupts. Also used by [[FutureOS]]. The PlayCity board use this feature to be sure that the CTC and YMZs circuits are properly reset before using them. == Light Pen/Gun connector ==For making it easier to adapt Light Pens/Guns from other systems or new ones, we added a 4-pin connector to the board. The connections are labeled in the board as VCC (+5V), TR (Trigger), LS (Light Sensor) and GND. Trigger (TR) = Request via output to port &FBFE. Light Sensor (LS) = CRTC Light Pen input. Making the system compatible with [[Amstrad_Magnum_Phaser|Amstrad Magnum Phaser]] games, the most accuracy light gun system for CPC. ==Counter/Timer Circuit=====Information===The Z84C30 has four independently programmable counter/timer channels interfaced directly with the Z80 CPU. You can get full information in the CTC datasheet ([[File:Z80ctc.pdf]]). The first thingto consider is how those channels are linked to the PlayCity board.====Channel 0 ($F880)====The channel 0 is exclusively used to generate the frequency of the two embedded soundchips (YMZ294). The input for the trigger(TRG0) is the 4 MHz system clock of the CPC. The output signal (ZC/TO0) is sent to the clock pins of the soundchips.====Channel 1 ($F881)====The channel 1 is typically used to generate raster interrupts. The input (TRG1) is linked to the CRTC CURSOR signal. The output(ZC/TO1) is connected to the NMI pin of the Z80. Used as a counter, it's synchronized with the CRTC CURSOR signal, generating a smooth high priority rasters interrupt. Used as atimer (prescaler set to 256), its 15.625 kHz signal is scanline-synchronized. That means the time constant is the number ofscanlines to wait before to send an NMI. ====Channel 2/3 ($F882/$F883)====The channels 2 and 3 are dedicated to general purpose usages. Yes, it's for you! The input for the trigger (TRG2) is the 4 MHzsystem clock. The output (ZC/TO2) is linked to the trigger for the channel 3 (TRG3). They can be used as 2x 8-bit or 1x 16-bitcounter/timer. They generate normal interrupts and allow using the Z80 vector interrupt (mode 2) too. ===Coding examples===Each channel is programmed with two bytes; a third is necessary when interrupts are enabled. Once started, the CTC countdownautomaticaly reloads its time constant and resume counting. Interrupt processing is simplified because only one vector need to bespecified; the CTC internally generates an unique vector for each channel. Before programming the CTC channels, you need to set the lower byte for the vectorized interrupts.====Vector interrupts====<pre>; Set Vector lower byte to 0LD BC,$F880OUT (C),0</pre>====Channel 0 example====<pre>; Set both YMZ294 clocks to sound like the CPC AY-3-8912LD BC,$F880LD HL,$7F01OUT (C),H ; $7F = Clock generatorOUT (C),L ; $01 = CPC AY</pre>====Channel 2 example====<pre>; Start CTC channel 2 in timer mode (prescalar 256 and set new time constant)LD H,%10110111 ; Timer mode and preescalar 256LD L,1 ; Time constantLD BC,$F882OUT (C),H ; Enable TimerOUT (C),L ; Set new time constant</pre><pre>; Stop CTC channel 2LD BC,$F882LD A,%00000011OUT (C),A ; Disable Timer 2</pre>====Channel 2/3 example====<pre>; Start CTC channel 2 and 3 in 16-bit counter modeLD BC,$F882LD HL,32768 ; Timer constantLD A,%11110111 ; Counter modeOUT (C),A ; Enable Timer 2OUT (C),L ; Set new time constant (lower byte)INC BCOUT (C),A ; Enable Timer 3OUT (C),H ; Set new time constant (high byte)</pre><pre>; Stop CTC channel 2 and 3 (16 bit mode)LD BC,$F882LD A,%00000011OUT (C),A ; Disable Timer 2INC BCOUT (C),A ; Disable Timer 3</pre>Don't forget to use RETN for NMI handlers as well as RETI for normal interrupt handlers. In other case, the Z80 CPU will notaknowledge the next interrupt properly. ==Audio Channels=====Informations===The PlayCity board is populated with two AY compatible soundchips, adding 6 stereo channels. The YMZ294 eliminate the I/O portand improve the CPU interface through /CS, /WR control signals and a 8-bit data bus. Each sound chip can be directlyprogrammed using two dedicated I/O ports for registers and data. No initialization code is required. By default, the YMZs are clocked at 4 MHz but run internaly at 2 MHz. So, they will sound like an Atari ST, while you don't changethe frequency by reprograming the CTC Channel 0.===YMZ294 Registers===They are exactly the same than the [[PSG]], only remember there is not PSG I/O registers ($0E-$0F) in the YMZ. The registers are write only. ===Coding Examples=======YMZ Initialization===='''YMZ_SELECT''', select a YMZ register. Use the port '''$F984''' for the right channels and port '''$F988''' for the left channels. '''YMZ_WRITE''', write a byte in the selected register. Use the port '''$F884''' for the right channels and port '''$F888''' for the left channels.<pre>; Initialization of the YMZ registersLD A,$D.loop_init_ymzLD BC,YMZ_SELECTOUT (C),A ; RegisterLD BC,YMZ_WRITECP 7JR NZ,.send_zeroLD A,$3F ; Noise and Tone disabledOUT (C),A ; Write in YMZ R7LD A,6JR .loop_init_ymz.send_zeroOUT (C),0 ; Write 0 in the selected YMZ registerDEC AJP P,.loop_init_ymz</pre>===CTC/YMZ Useful Values==={| class="wikitable"|-! CTC !! CTC Out (MHz) !! YMZ (MHz) !! Computer|-| $1 || 2,00 || 1,00 || = CPC|-| $2 || 3,00 || 1,50 |||-| $3 || 3,33 || 1,67 |||-| $4 || 3,50 || 1,75 || = ZX|-| $5 || 3,60 || 1,80 || ~ MSX|-| $6 || 3,67 || 1,83 |||-| $7 || 3,71 || 1,86 |||-| $8 || 3,75 || 1,88 |||- | $9 || 3,78 || 1,89 |||- | $A || 3,80 || 1,90 |||-| $B || 3,82 || 1,91 |||- | $C || 3,83 || 1,92 |||- | $D || 3,85 || 1,92 |||- | $E || 3,86 || 1,93 |||- | $F || 3,87 || 1,93 |||-| $0 || 3,98 || 1,99 || ~ ST|-| UNSET || 4,00 || 2,00 || = ST|} ==PlayCity coding tips==Interesting tips or "magic tricks" using the board should be documented here. If the code is long, you must put in other wiki page and link it here. ===PlayCity detection===We are going to use the NMI interrupt generator to check if our program is running in a grey screen appearCPC with a PlayCity board.<pre>; ---------------------------------------------------------------------------; PlayCity check; (c) 2013 SyX; --------------------------------------------------------------------------- ; ConstantesCTC_TIM1 EQU $F881 ; Channel 1 (I: Cursor CRTC | O: NMI) CTC_START_TIMER256 EQU %00110111CTC_STOP_CHANNEL EQU %00000011 ; ---------------------------------------------------------------------------; NOTE: The lower ROM must be disabled before to run this code.check_playcity ; Disable interrupts DI ; Install NMI handler LD A, turn off your computer $C3 ; JP $xxxx LD HL,nmi_interrupt LD ($0066),A LD ($0067),HL ; Initialize playcity variable to 0 XOR A LD (playcity),A ; Wait VBlank LD B,$F5.wait_vbl IN A,(C) RRA JR NC,.wait_vbl ; Initialize CTC timer 1 (NMI generator) LD HL,32 ; 32 scanlines LD BC,CTC_TIM1 LD A,CTC_START_TIMER256 OUT (C),A ; Enable Timer OUT (C),L ; Set new time constant ; Extra delay LD IX,33 * 4 - 1 ; Wait 33 scanlines CALL wait_scanlines_ix LD A,(playcity) OR A JR NZ,.playcity_detected ; No PlayCity detected . . . .playcity_detected . . . ; ---------------------------------------------------------------------------nmi_interrupt PUSH BC PUSH AF ; Change playcity variable LD A,$FF LD (playcity),A ; Disable CTC timer 1 (NMI generator) LD BC,CTC_TIM1 LD A,CTC_STOP_CHANNEL OUT (C),A ; Disable Timer POP AF POP BC EI RETN ; ---------------------------------------------------------------------------; Wait scanlines; INPUT:; IX: Scanlines to wait * 4 - 1; ---------------------------------------------------------------------------wait_scanlines_ix DEFS 5,0 ; (5) .loop_wait_scanlines_ix DEFS 6 ; (6) DEC IX ; (3) LD A,IXH ; (2) OR IXL ; (2) JR NZ,.loop_wait_scanlines_ix ; (2/3) ; Total loop --> 16 * (IX - 1) + 15 RET ; (3) ; Total Routine --> 64 * SCANLINES; ---------------------------------------------------------------------------playcity DEFS 1</pre> ===PlayCity detection (alternative)===Faster and shorter, but untested or not working on all CPC.<pre>;=========================; PlayCity check ; If it's present, A=1; Otherwise, A=0;-------------------------;;=========================macro PlaycityDetection ; Code for NMI management ld a,#3c ; inc a ld (#66),a ld hl,#45ed ; (inverted) opcodes for retn ld (#67),hl ; If a Playcity is present, the connexionscode generates a NMI then stops the counter. ld bc,#F881 ; 3 NOPs CTC channel 1 ld hl,%00010111*256 + 2 ; 3 NOPs A NMI every 8 NOPs out (c),h ; 4 NOPs out (c),l ; 4 NOPs ld a,0 ; 2 NOPs A is set to 0. If a CTC is present, it will be INCed by the INTerruption code inc hl ; 2 NOPs L=3 => Stop CTC channel nop ; 1 NOPs out (c),l ; 4 NOPs <- If a Playcity is plugged, a NMI should be raised during this opcodemend</pre> ==Downloads==In [[File:playcity_examples.zip]], you will find more examples with full sources of using the CTC, a customized arkos player that let you play songs using an external YMZ and the ReSeT party demo disk that includes a CPC version of the PT3 Turbo Sound player (6 channels song format). Another example, in [[File:test_sfx.zip]] you will find a 3 channels SFX player, you can choose the sound chip to be used by the player. == Software Supporting PlayCity == *[[Software_Supporting_PlayCity|List of software supporting the board.]] [[Category:FutureOS]][[Category:Music and sound]][[Category:Peripherals]] Website: [http://centpourcent.net centpourcent.net]