Difference between revisions of "ASIC"

From CPCWiki - THE Amstrad CPC encyclopedia!
Jump to: navigation, search
(Vectored Interrupt)
(ASIC I/O page)
 
(56 intermediate revisions by the same user not shown)
Line 9: Line 9:
 
<br>
 
<br>
  
==Amstrad Custom chips==
+
==Amstrad custom chips==
  
 
The Amstrad CPC used one custom chip: the video [[Gate Array]] (also called VGA – no connection with the Video PC standard).
 
The Amstrad CPC used one custom chip: the video [[Gate Array]] (also called VGA – no connection with the Video PC standard).
  
Latter [[CPC]] cost down series included a "pre-ASIC"-called ASIC to merge the VGA and the [[CRTC]].
+
Later [[CPC]] cost down series included a "pre-ASIC"-called ASIC to merge the VGA and the [[CRTC]].
  
 
The Amstrad [[Plus]] included a "second heart" simply referred as the ASIC.
 
The Amstrad [[Plus]] included a "second heart" simply referred as the ASIC.
Line 47: Line 47:
 
*Specific ROM switching
 
*Specific ROM switching
 
*8-bit printer port (with bit3 of CRTC register 12)
 
*8-bit printer port (with bit3 of CRTC register 12)
*Analog joystick port
+
*Analogue joystick port
  
 
<br>
 
<br>
  
== Soft Scroll ==
+
== Analogue joystick ==
  
The 8-bit register SSCR (at address 6804h) controls soft scrolling by pixels rather than by characters. Setting this register to 0 (the default value at power-up) disables the soft scroll feature. The soft scrolling mechanism affects the entire main screen, regardless of the split screen feature, but does not affect sprites.
+
Analogue joystick axes are unsigned 6-bit values. Bits7..6 are always 0.
 +
 
 +
<br>
 +
 
 +
== Colour palette ==
 +
 
 +
A colour in the palette is coded in 2 bytes:
 +
* For first byte, bits7..4 are blue value, bits3..0 are red value
 +
* For second byte, bits7..4 are ignored, bits3..0 are green value
 +
 
 +
<br>
 +
 
 +
== Hardware sprites ==
 +
 
 +
Sprites are prioritized so that the border has the highest priority, followed by sprites 0 to 15 in sequence, then the main screen data.
 +
 
 +
There is only one pixel per byte in sprite image data. Bits3..0 of each byte define the palette index for this pixel (a value of 0 means transparent colour). Bits7..4 are ignored.
 +
 
 +
Each sprite magnification is coded in 1 byte:
 +
* bits7..4 are ignored
 +
* bits3..2 are X magnification (00 = not displayed, 01 = x1, 10 = x2, 11 = x4)
 +
* bits1..0 are Y magnification (00 = not displayed, 01 = x1, 10 = x2, 11 = x4)
 +
 
 +
Sprites will be displayed at coordinates based on the internal counters of the CRTC. Sprite X coordinate is based on HCC. Sprite Y coordinate is based on VCC and VLC.
 +
 
 +
<br>
 +
 
 +
== Soft scroll ==
 +
 
 +
The SSCR register (at address 6804h) controls soft (meaning smooth, not software) scrolling by pixels rather than by characters. Setting this register to 0 (the default value at power-up) disables the soft scroll feature. The soft scrolling mechanism affects the entire main screen, regardless of the split screen feature, but does not affect sprites.
 
* Bits3..0 of SSCR define a horizontal delay between 0 and 15 high-resolution (mode 2) pixels, shifting the screen image to the right by the programmed value. This causes pixels to be lost behind the right border and random data to appear on the left. Also the programmer must ensure that the delay value is a multiple of the number of bits per pixel.
 
* Bits3..0 of SSCR define a horizontal delay between 0 and 15 high-resolution (mode 2) pixels, shifting the screen image to the right by the programmed value. This causes pixels to be lost behind the right border and random data to appear on the left. Also the programmer must ensure that the delay value is a multiple of the number of bits per pixel.
 
* Bits6..4 of SSCR are summed to the least significant 3 bits of the scan line address, determining which of the eight 2k blocks contains the data for the first scan line on the screen. This shifts the display up by the programmed number of scan lines, causing the first lines to be lost and extra lines to appear at the bottom.
 
* Bits6..4 of SSCR are summed to the least significant 3 bits of the scan line address, determining which of the eight 2k blocks contains the data for the first scan line on the screen. This shifts the display up by the programmed number of scan lines, causing the first lines to be lost and extra lines to appear at the bottom.
Line 60: Line 89:
 
<br>
 
<br>
  
== Split Screen ==
+
== Split screen ==
  
The 8-bit register SPLT (at address 6801h) specifies the scan line where the screen split occurs. Setting this register to 0 (the default value at power-up) disables the split screen feature.
+
The SPLT register (at address 6801h) specifies the scan line where the screen split occurs. Setting this register to 0 (the default value at power-up) disables the split screen feature.
  
The 16-bit register SSA (high byte at address 6802h and low byte at address 6803h) defines the starting address in memory for displaying the lower part of the screen. SSA works similarly to the duo R12/R13 in the CRTC. This configuration allows the lower part of the screen to be sourced from a different memory area and be scrolled independently. However, note that the soft scrolling register SSCR acts on the whole screen.
+
The SSA register (high byte at address 6802h and low byte at address 6803h) defines the starting address in memory for displaying the lower part of the screen.
 +
 
 +
SSA works similarly to the duo R12/R13 in the CRTC and allows the lower part of the screen to be sourced from a different memory area and be scrolled independently. However, note that the soft scrolling register SSCR acts on the whole screen regardless.
  
 
<br>
 
<br>
  
== Programmable Raster Interrupt ==
+
== Programmable raster interrupt ==
 +
 
 +
The PRI register (at address 6800h) specifies the raster line where the interrupt occurs. The raster interrupt will start exactly 10µs after the HSYNC start on that raster line. Unlike the R52 raster interrupt system, it is not dependant on the width of the HSYNC.
  
The 8-bit memory-mapped register PRI (at address 6800h) specifies the scan line where the interrupt occurs. The interrupt will occur at the end of that scan line. Setting this register to 0 (the default value at power-up) reverts to the classic [[Gate Array]] R52 raster interrupt system instead.
+
Setting the PRI register to 0 (the default value at power-up) reverts to the classic [[Gate Array]] R52 raster interrupt system instead.
  
 
PRI can be reprogrammed as required to produce multiple interrupts per frame.
 
PRI can be reprogrammed as required to produce multiple interrupts per frame.
  
Additionally, on Amstrad Plus, we have multiple sources of interrupts as each DMA sound channel can trigger an interrupt.
+
Also PRI can trigger interrupts beyond the first 256 lines. For example, when PRI = 10, an interrupt will be triggered at line 10 but also at line 266.
  
 
<br>
 
<br>
  
== DMA commands ==
+
== DMA sound channels ==
 
+
Each DMA channel fetch one 16-bit instruction during horizontal retrace time. Once the 3 instructions have been captured, they are then executed sequentially.
+
 
+
These instructions are encoded in little-endian (LSB byte first). They must be located in Base 64k RAM and aligned to word boundary (the address of first byte must be even).
+
  
 
The available commands are:
 
The available commands are:
Line 130: Line 159:
 
* REPEAT 0 and PAUSE 0 instructions have no effect, i.e. they are equivalent to NOP.
 
* REPEAT 0 and PAUSE 0 instructions have no effect, i.e. they are equivalent to NOP.
 
* Control group (4xxxh) instructions can be logically ORed to produce more complex instructions, e.g. INT|STOP = 4030h = Interrupt and Stop.
 
* Control group (4xxxh) instructions can be logically ORed to produce more complex instructions, e.g. INT|STOP = 4030h = Interrupt and Stop.
* The STOP instruction will leave the source address register pointing to the next instruction, so that the instruction stream can be continued after CPU intervention.
+
* The STOP instruction will leave the source address register (SAR) pointing to the next instruction, so that the instruction stream can be continued after CPU intervention.
 
* The argument field (N) of the REPEAT instruction is actually the number of times the loop is taken. The block of code between REPEAT and LOOP instructions is therefore executed N+1 times.
 
* The argument field (N) of the REPEAT instruction is actually the number of times the loop is taken. The block of code between REPEAT and LOOP instructions is therefore executed N+1 times.
  
 +
These instructions are encoded in little-endian (LSB byte first). They must be located in Base 64k RAM and aligned to word boundary (the address of first byte must be even).
 +
 +
Instruction codes 4xxxh are partially decoded by the DMA controller. For example, the instruction code CFCFh is equivalent to 4001h.
 +
 +
Each DMA channel fetch one 16-bit instruction during horizontal retrace time. Once the 3 instructions have been captured, they are then executed sequentially.
 +
 +
All instructions execute in 1 cycle, except LOAD which requires at least 8 cycles. An extra cycle is added to a LOAD if the CPU is accessing the PPI, or 2 extra cycles if the CPU access was itself a PSG register write.
 +
 +
A pause prescaler register (PPR) is available for each channel to define the pause unit. It is expressed in number of HSYNCs.
  
 
The DMA control and status register DCSR (at address 6C0Fh) controls which channels are currently enabled, and also tells the CPU which channel is interrupting:
 
The DMA control and status register DCSR (at address 6C0Fh) controls which channels are currently enabled, and also tells the CPU which channel is interrupting:
* Bits2..0 are the channel enable bits. When set to "1" it enables the corresponding DMA channel. It can be set by the CPU, and cleared by either the CPU, a STOP instruction, or power on rest.
+
* Bits2..0 are the channel enable bits. When set to "1" it enables the corresponding DMA channel. It can be set by the CPU, and cleared by either the CPU, a STOP instruction, or power-on reset.
 
* Bits7..4 are the interrupt bits. An interrupt bit is set to "0" when the corresponding channel is requesting an interrupt, and cleared when the CPU writes a "1" to the appropriate bit.
 
* Bits7..4 are the interrupt bits. An interrupt bit is set to "0" when the corresponding channel is requesting an interrupt, and cleared when the CPU writes a "1" to the appropriate bit.
 
* The INT signal of the ASIC is the compositing of all the interrupt bits of DCSR by using the AND function. INT is active at "0" if at least one of the interrupt bits is "0".
 
* The INT signal of the ASIC is the compositing of all the interrupt bits of DCSR by using the AND function. INT is active at "0" if at least one of the interrupt bits is "0".
Line 141: Line 179:
 
<br>
 
<br>
  
== Vectored Interrupt ==
+
== Vectored interrupt ==
  
The ASIC provides an interrupt vector on interrupt request.
+
The ASIC always provides an interrupt vector to the CPU on INT ACK.
  
 
The register IVR (at address 6805h) supplies the top 5 bits of the vector provided to the CPU. IVR is undefined at reset except that bit0 will be set to 1. Therefore, before placing the CPU in vectored interrupt mode, always set up the IVR so that the top 5 bits are defined.
 
The register IVR (at address 6805h) supplies the top 5 bits of the vector provided to the CPU. IVR is undefined at reset except that bit0 will be set to 1. Therefore, before placing the CPU in vectored interrupt mode, always set up the IVR so that the top 5 bits are defined.
Line 149: Line 187:
 
Bits2..1 of the IVR register are unused.
 
Bits2..1 of the IVR register are unused.
  
Bit0 of the IVR register controls whether DMA channel interrupts are automatically cleared.
+
Bit0 of the IVR register controls whether DMA channel interrupts are automatically cleared. Raster interrupts are always automatically cleared regardless of this setting.
  
 
Interrupts are prioritized in a fixed sequence. The raster interrupt has the highest priority, followed by DMA channels 2 down to 0 respectively.
 
Interrupts are prioritized in a fixed sequence. The raster interrupt has the highest priority, followed by DMA channels 2 down to 0 respectively.
  
==== Interrupt Vector used on Z80 IM2 mode ====
+
==== Interrupt vector used on Z80 IM2 mode ====
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
!Interrupt Vector
+
!Interrupt vector
 
!Signal source
 
!Signal source
 
!Value
 
!Value
Line 164: Line 202:
 
|A7..A3||ASIC||IVR register bits7..3
 
|A7..A3||ASIC||IVR register bits7..3
 
|-
 
|-
|A2..A1||ASIC||00 = DMA chan 2, 01 = DMA chan 1, 10 = DMA chan 0, 11 = DMA raster
+
|A2..A1||ASIC||00 = DMA chan2 ; 01 = DMA chan1 ; 10 = DMA chan0 ; 11 = Raster
 
|-
 
|-
 
|A0||ASIC||Always 0
 
|A0||ASIC||Always 0
Line 171: Line 209:
 
<br>
 
<br>
  
== Known Flaws==
+
== Known flaws==
  
 
The Amstrad Plus ASIC improved a lot of the old CPC's capability.
 
The Amstrad Plus ASIC improved a lot of the old CPC's capability.
Line 180: Line 218:
 
*PPI emulation is not correct as the original 8255 does not need validation. On ASIC emulation, this validation is needed so some programs written for "old CPCs" will not be able to get keyboard state.
 
*PPI emulation is not correct as the original 8255 does not need validation. On ASIC emulation, this validation is needed so some programs written for "old CPCs" will not be able to get keyboard state.
  
*Z80 IM2 mode is bugged. In this mode, the Z80 I register gives the high word for vector table. ASIC gives the low word from IVR and the devices that generate interrupt (raster and DMAs channels). ASIC may generate a bad values and the raster interrupt routine is called instead of DMA0 routine if the Z80 is running particular portions of memory. See [[Plus Vectored Interrupt Bug]] for more details.
+
*Z80 IM2 mode is bugged. In this mode, the Z80 I register gives the high byte for vector table. ASIC gives the low byte from IVR and the devices that generate interrupt (raster and DMAs channels). ASIC may generate a bad value and make the raster interrupt routine called instead of DMA0 routine if the Z80 is running particular portions of memory. See [[Plus Vectored Interrupt Bug]] for more details.
  
 
*There is a conflict between programmable interrupts and some CRTC settings (line screen split). That will cause the RAM refresh to stop and the memory content will be quickly corrupted causing machine crash.
 
*There is a conflict between programmable interrupts and some CRTC settings (line screen split). That will cause the RAM refresh to stop and the memory content will be quickly corrupted causing machine crash.
Line 190: Line 228:
 
<br>
 
<br>
  
==Internal Links==
+
== ASIC I/O page ==
  
*[[Arnold V specs]]
+
{| class="wikitable"
*[[Arnold V Specs Revised]]
+
! ADDR
 +
! SIZE
 +
! POR
 +
! TYPE
 +
! MNEM
 +
! USE
 +
|-
 +
| 4000h || 100h || N || R/W || || Sprite 0 image data
 +
|-
 +
| 4100h || 100h || N || R/W || || Sprite 1 image data
 +
|-
 +
| ...  || ...  || ... || ...  || ... || ...
 +
|-
 +
| 4F00h || 100h || N || R/W || || Sprite 15 image data
 +
|-
 +
|style="background:#efefef;" colspan="6"|''Block unused''
 +
|-
 +
| 6000h || 2    || N || R/W  || X0  || Sprite 0 X position
 +
|-
 +
| 6002h || 2    || N || R/W  || Y0  || Sprite 0 Y position
 +
|-
 +
| 6004h || 1    || Y || W    || M0  || Sprite 0 magnification
 +
|-
 +
| 6005h || 3    ||  ||      ||    || (unused)
 +
|-
 +
| 6008h || 2    || N || R/W  || X1  || Sprite 1 X position
 +
|-
 +
| 600Ah || 2    || N || R/W  || Y1  || Sprite 1 Y position
 +
|-
 +
| 600Ch || 1    || Y || W    || M1  || Sprite 1 magnification
 +
|-
 +
| 600Dh || 3    ||  ||      ||    || (unused)
 +
|-
 +
| ...  || ...  || ... || ...  || ... || ...
 +
|-
 +
| 6078h || 2    || N || R/W  || X15 || Sprite 15 X position
 +
|-
 +
| 607Ah || 2    || N || R/W  || Y15 || Sprite 15 Y position
 +
|-
 +
| 607Ch || 1    || N || W    || M15 || Sprite 15 magnification
 +
|-
 +
| 607Dh || 3    ||  ||      ||    || (unused)
 +
|-
 +
|style="background:#efefef;" colspan="6"|''Block unused''
 +
|-
 +
| 6400h || 2    || N || R/W  ||    || Colour palette, pen 0
 +
|-
 +
| 6402h || 2    || N || R/W  ||    || Colour palette, pen 1
 +
|-
 +
| ...  || ...  || ... || ...  || ... || ...
 +
|-
 +
| 641Eh || 2    || N || R/W  ||    || Colour palette, pen 15
 +
|-
 +
| 6420h || 2    || N || R/W  ||    || Colour palette, border
 +
|-
 +
| 6422h || 2    || N || R/W  ||    || Colour palette, sprite colour 1
 +
|-
 +
| 6424h || 2    || N || R/W  ||    || Colour palette, sprite colour 2
 +
|-
 +
| ...  || ...  || ... || ...  || ... || ...
 +
|-
 +
| 643Eh || 2    || N || R/W  ||    || Colour palette, sprite colour 15
 +
|-
 +
|style="background:#efefef;" colspan="6"|''Block unused''
 +
|-
 +
| 6800h || 1    || Y || W    || PRI  || Programmable raster interrupt scan line
 +
|-
 +
| 6801h || 1    || Y || W    || SPLT || Screen split scan line
 +
|-
 +
| 6802h || 2    || N || W    || SSA  || Screen split secondary start address
 +
|-
 +
| 6804h || 1    || Y || W    || SSCR || Soft scroll control register
 +
|-
 +
| 6805h || 1    || N || W    || IVR  || Interrupt Vector (Bit 0 set to 1 on reset)
 +
|-
 +
| 6806h || 2    ||  ||      ||    || (unused)
 +
|-
 +
| 6808h || 1    ||  || R    || ADC0 || Analogue input channel 0
 +
|-
 +
| 6809h || 1    ||  || R    || ADC1 || Analogue input channel 1
 +
|-
 +
| 680Ah || 1    ||  || R    || ADC2 || Analogue input channel 2
 +
|-
 +
| 680Bh || 1    ||  || R    || ADC3 || Analogue input channel 3
 +
|-
 +
| 680Ch || 1    ||  || R    || ADC4 || Analogue input channel 4
 +
|-
 +
| 680Dh || 1    ||  || R    || ADC5 || Analogue input channel 5
 +
|-
 +
| 680Eh || 1    ||  || R    || ADC6 || Analogue input channel 6
 +
|-
 +
| 680Fh || 1    ||  || R    || ADC7 || Analogue input channel 7
 +
|-
 +
|style="background:#efefef;" colspan="6"|''Block unused''
 +
|-
 +
| 6C00h || 2    || N || W    || SAR0 || "DMA" channel 0 address pointer
 +
|-
 +
| 6C02h || 1    || N || W    || PPR0 || "DMA" channel 0 pause prescaler
 +
|-
 +
| 6C03h || 1    ||  ||      ||    || (unused)
 +
|-
 +
| 6C04h || 2    || N || W    || SAR1 || "DMA" channel 1 address pointer
 +
|-
 +
| 6C06h || 1    || N || W    || PPR1 || "DMA" channel 1 pause prescaler
 +
|-
 +
| 6C07h || 1    ||  ||      ||    || (unused)
 +
|-
 +
| 6C08h || 2    || N || W    || SAR2 || "DMA" channel 2 address pointer
 +
|-
 +
| 6C0Ah || 1    || N || W    || PPR2 || "DMA" channel 2 pause prescaler
 +
|-
 +
| 6C0Bh || 4    ||  ||      ||    || (unused)
 +
|-
 +
| 6C0Fh || 1    || Y || R/W  || DCSR || "DMA" control/status register
 +
|-
 +
|style="background:#efefef;" colspan="6"|''Block unused''
 +
|}
  
*[[Default I/O Port Summary|ASIC I/O page]]
+
POR column indicates whether a register has power-on reset. A "N" indicates that the contents of a register are undefined at power-on.
*[[Programming:Unlocking ASIC]]
+
*[[B-ASIC]]
+
  
*[[CRTC]]
+
 
*[[Gate Array]]
+
Beware, when booting your software from cartridge. Z80 is in Interrupt Mode 0 by default. Stack Pointer is uninitialized. FDC is in DMA mode by default. And hardware sprites memory has random value.
 +
 
 +
Anyway, you have to initialize all internal components (Z80, PPI, CRTC, AY, etc) when you are booting from cartridge.
  
 
<br>
 
<br>
  
==External Links==
+
==Links==
  
 
*[http://en.wikipedia.org/wiki/Application-specific_integrated_circuit ASIC at Wikipedia] General information on ASICs.
 
*[http://en.wikipedia.org/wiki/Application-specific_integrated_circuit ASIC at Wikipedia] General information on ASICs.
Line 210: Line 364:
 
*[http://www.cpctech.org.uk/docs/arn5new.html Asic and Plus features at Unofficial CPC ressources 1.4]
 
*[http://www.cpctech.org.uk/docs/arn5new.html Asic and Plus features at Unofficial CPC ressources 1.4]
 
*[http://www.cpctech.org.uk/docs/arnold5a.html Asic and Plus features at Unofficial CPC ressources 1.5]
 
*[http://www.cpctech.org.uk/docs/arnold5a.html Asic and Plus features at Unofficial CPC ressources 1.5]
*[http://www.cpctech.org.uk/docs/cpcplus.html Extra Plus Hardware Information]
 
 
*[http://quasar.cpcscene.net/doku.php?id=assem:asic Quasar ASIC documentation (in french)]
 
*[http://quasar.cpcscene.net/doku.php?id=assem:asic Quasar ASIC documentation (in french)]
  
 
<br>
 
<br>
 +
 +
==Related pages==
 +
 +
*[[Arnold V specs]]
 +
*[[Arnold V Specs Revised]]
 +
*[[Extra CPC Plus Hardware Information]]
 +
 +
*[[Programming:Unlocking ASIC]]
 +
*[[B-ASIC]]
 +
 +
*[[CRTC]]
 +
*[[Gate Array]]
  
 
[[Category:CPC Plus|*]][[Category:Electronic Component]][[Category:Programming]][[Category:Datasheet]][[Category:Graphic]]
 
[[Category:CPC Plus|*]][[Category:Electronic Component]][[Category:Programming]][[Category:Datasheet]][[Category:Graphic]]
 
[[Category:Stub]][[Category:CPC Internal Components]]
 
[[Category:Stub]][[Category:CPC Internal Components]]

Latest revision as of 23:05, 31 July 2024

Application-Specific Integrated Circuit (ASIC)

An ASIC is an especially manufactured custom chip designed to fulfill special functions.

The main reason is to perform special tasks or combine different electronic components into a single Integrated Circuit (chip). This chip is not commonly available (COTS), but has to be ordered as a genuine part, prices dictated by the seller.

After a seller goes out of business or stops supporting a product line, before IPs (Instruction set Processors) like CPLD or FPGA, they essentially became unavailable. Commodore used a plethora of ASICs in their machines (VIC, SID, PAULA,......); MSX or the IBM PC/XT/AT were the opposite in using only COTS components, making it easy for third parties to offer parts (or to re-build and repair the computers for as long as the COTS chip was still available or a backwards-compatible component exists).


Amstrad custom chips

The Amstrad CPC used one custom chip: the video Gate Array (also called VGA – no connection with the Video PC standard).

Later CPC cost down series included a "pre-ASIC"-called ASIC to merge the VGA and the CRTC.

The Amstrad Plus included a "second heart" simply referred as the ASIC.

CPC+ ASIC's part number is 40489


Emulated chips

CPC+ ASIC emulates the following chips:


New features

This Amstrad Plus ASIC performs many additional features that the old CPC series couldn't: the "Plus Features".

  • 12-bit colour palette
  • Hardware sprites
  • Vertical and horizontal per-pixel hardware soft scrolling (in complement with register 12&13 of the CRTC)
  • Screen splitting
  • Programmable raster interrupts
  • Vectored interrupts
  • DMA sound channels
  • Specific ROM switching
  • 8-bit printer port (with bit3 of CRTC register 12)
  • Analogue joystick port


Analogue joystick

Analogue joystick axes are unsigned 6-bit values. Bits7..6 are always 0.


Colour palette

A colour in the palette is coded in 2 bytes:

  • For first byte, bits7..4 are blue value, bits3..0 are red value
  • For second byte, bits7..4 are ignored, bits3..0 are green value


Hardware sprites

Sprites are prioritized so that the border has the highest priority, followed by sprites 0 to 15 in sequence, then the main screen data.

There is only one pixel per byte in sprite image data. Bits3..0 of each byte define the palette index for this pixel (a value of 0 means transparent colour). Bits7..4 are ignored.

Each sprite magnification is coded in 1 byte:

  • bits7..4 are ignored
  • bits3..2 are X magnification (00 = not displayed, 01 = x1, 10 = x2, 11 = x4)
  • bits1..0 are Y magnification (00 = not displayed, 01 = x1, 10 = x2, 11 = x4)

Sprites will be displayed at coordinates based on the internal counters of the CRTC. Sprite X coordinate is based on HCC. Sprite Y coordinate is based on VCC and VLC.


Soft scroll

The SSCR register (at address 6804h) controls soft (meaning smooth, not software) scrolling by pixels rather than by characters. Setting this register to 0 (the default value at power-up) disables the soft scroll feature. The soft scrolling mechanism affects the entire main screen, regardless of the split screen feature, but does not affect sprites.

  • Bits3..0 of SSCR define a horizontal delay between 0 and 15 high-resolution (mode 2) pixels, shifting the screen image to the right by the programmed value. This causes pixels to be lost behind the right border and random data to appear on the left. Also the programmer must ensure that the delay value is a multiple of the number of bits per pixel.
  • Bits6..4 of SSCR are summed to the least significant 3 bits of the scan line address, determining which of the eight 2k blocks contains the data for the first scan line on the screen. This shifts the display up by the programmed number of scan lines, causing the first lines to be lost and extra lines to appear at the bottom.
  • Bit7 of SSCR, when set, extends the border to cover the first 2 bytes (16 high-resolution pixels) of each scan line, masking bad data caused by the horizontal soft scroll. When using horizontal soft scroll, always set this bit to maintain consistent screen width.


Split screen

The SPLT register (at address 6801h) specifies the scan line where the screen split occurs. Setting this register to 0 (the default value at power-up) disables the split screen feature.

The SSA register (high byte at address 6802h and low byte at address 6803h) defines the starting address in memory for displaying the lower part of the screen.

SSA works similarly to the duo R12/R13 in the CRTC and allows the lower part of the screen to be sourced from a different memory area and be scrolled independently. However, note that the soft scrolling register SSCR acts on the whole screen regardless.


Programmable raster interrupt

The PRI register (at address 6800h) specifies the raster line where the interrupt occurs. The raster interrupt will start exactly 10µs after the HSYNC start on that raster line. Unlike the R52 raster interrupt system, it is not dependant on the width of the HSYNC.

Setting the PRI register to 0 (the default value at power-up) reverts to the classic Gate Array R52 raster interrupt system instead.

PRI can be reprogrammed as required to produce multiple interrupts per frame.

Also PRI can trigger interrupts beyond the first 256 lines. For example, when PRI = 10, an interrupt will be triggered at line 10 but also at line 266.


DMA sound channels

The available commands are:

Code Mnemonic Description
0RDDh LOAD R,D Load 8 bit data D to PSG register R (0 < R ≤ 15)
1NNNh PAUSE N Pause for N prescaled ticks (0 < N ≤ 4095)
2NNNh REPEAT N Set loop counter to N for this stream (0 < N ≤ 4095) and mark next instruction as loop start
3xxxh (reserved) Do not use
4000h NOP No operation (64µs idle)
4001h LOOP If loop counter non zero, loop back to the first instruction after REPEAT instruction and decrement loop counter
4010h INT Interrupt the CPU
4020h STOP Stop processing the sound list

Note that:

  • REPEAT Loops cannot be nested. Only one is allowed to be active per instruction stream at any time.
  • REPEAT 0 and PAUSE 0 instructions have no effect, i.e. they are equivalent to NOP.
  • Control group (4xxxh) instructions can be logically ORed to produce more complex instructions, e.g. INT|STOP = 4030h = Interrupt and Stop.
  • The STOP instruction will leave the source address register (SAR) pointing to the next instruction, so that the instruction stream can be continued after CPU intervention.
  • The argument field (N) of the REPEAT instruction is actually the number of times the loop is taken. The block of code between REPEAT and LOOP instructions is therefore executed N+1 times.

These instructions are encoded in little-endian (LSB byte first). They must be located in Base 64k RAM and aligned to word boundary (the address of first byte must be even).

Instruction codes 4xxxh are partially decoded by the DMA controller. For example, the instruction code CFCFh is equivalent to 4001h.

Each DMA channel fetch one 16-bit instruction during horizontal retrace time. Once the 3 instructions have been captured, they are then executed sequentially.

All instructions execute in 1 cycle, except LOAD which requires at least 8 cycles. An extra cycle is added to a LOAD if the CPU is accessing the PPI, or 2 extra cycles if the CPU access was itself a PSG register write.

A pause prescaler register (PPR) is available for each channel to define the pause unit. It is expressed in number of HSYNCs.

The DMA control and status register DCSR (at address 6C0Fh) controls which channels are currently enabled, and also tells the CPU which channel is interrupting:

  • Bits2..0 are the channel enable bits. When set to "1" it enables the corresponding DMA channel. It can be set by the CPU, and cleared by either the CPU, a STOP instruction, or power-on reset.
  • Bits7..4 are the interrupt bits. An interrupt bit is set to "0" when the corresponding channel is requesting an interrupt, and cleared when the CPU writes a "1" to the appropriate bit.
  • The INT signal of the ASIC is the compositing of all the interrupt bits of DCSR by using the AND function. INT is active at "0" if at least one of the interrupt bits is "0".


Vectored interrupt

The ASIC always provides an interrupt vector to the CPU on INT ACK.

The register IVR (at address 6805h) supplies the top 5 bits of the vector provided to the CPU. IVR is undefined at reset except that bit0 will be set to 1. Therefore, before placing the CPU in vectored interrupt mode, always set up the IVR so that the top 5 bits are defined.

Bits2..1 of the IVR register are unused.

Bit0 of the IVR register controls whether DMA channel interrupts are automatically cleared. Raster interrupts are always automatically cleared regardless of this setting.

Interrupts are prioritized in a fixed sequence. The raster interrupt has the highest priority, followed by DMA channels 2 down to 0 respectively.

Interrupt vector used on Z80 IM2 mode

Interrupt vector Signal source Value
A15..A8 Z80 Register I
A7..A3 ASIC IVR register bits7..3
A2..A1 ASIC 00 = DMA chan2 ; 01 = DMA chan1 ; 10 = DMA chan0 ; 11 = Raster
A0 ASIC Always 0


Known flaws

The Amstrad Plus ASIC improved a lot of the old CPC's capability. Yet this was a bit flawed.

  • Despite removing some tasks from the CPU (Z80), ASIC registers are mapped onto memory from #4000 to #7FFF range prior to other type of memory (RAM or ROM). That means this memory range is not accessible when ASIC registers are paged.
  • PPI emulation is not correct as the original 8255 does not need validation. On ASIC emulation, this validation is needed so some programs written for "old CPCs" will not be able to get keyboard state.
  • Z80 IM2 mode is bugged. In this mode, the Z80 I register gives the high byte for vector table. ASIC gives the low byte from IVR and the devices that generate interrupt (raster and DMAs channels). ASIC may generate a bad value and make the raster interrupt routine called instead of DMA0 routine if the Z80 is running particular portions of memory. See Plus Vectored Interrupt Bug for more details.
  • There is a conflict between programmable interrupts and some CRTC settings (line screen split). That will cause the RAM refresh to stop and the memory content will be quickly corrupted causing machine crash.
  • Reducing horizontal blanking could cause another internal conflict when using DMA lists. In the worst case, this conflict can cause irreversible damage to the ASIC.
  • Original CPC colors emulation is not correct.


ASIC I/O page

ADDR SIZE POR TYPE MNEM USE
4000h 100h N R/W Sprite 0 image data
4100h 100h N R/W Sprite 1 image data
... ... ... ... ... ...
4F00h 100h N R/W Sprite 15 image data
Block unused
6000h 2 N R/W X0 Sprite 0 X position
6002h 2 N R/W Y0 Sprite 0 Y position
6004h 1 Y W M0 Sprite 0 magnification
6005h 3 (unused)
6008h 2 N R/W X1 Sprite 1 X position
600Ah 2 N R/W Y1 Sprite 1 Y position
600Ch 1 Y W M1 Sprite 1 magnification
600Dh 3 (unused)
... ... ... ... ... ...
6078h 2 N R/W X15 Sprite 15 X position
607Ah 2 N R/W Y15 Sprite 15 Y position
607Ch 1 N W M15 Sprite 15 magnification
607Dh 3 (unused)
Block unused
6400h 2 N R/W Colour palette, pen 0
6402h 2 N R/W Colour palette, pen 1
... ... ... ... ... ...
641Eh 2 N R/W Colour palette, pen 15
6420h 2 N R/W Colour palette, border
6422h 2 N R/W Colour palette, sprite colour 1
6424h 2 N R/W Colour palette, sprite colour 2
... ... ... ... ... ...
643Eh 2 N R/W Colour palette, sprite colour 15
Block unused
6800h 1 Y W PRI Programmable raster interrupt scan line
6801h 1 Y W SPLT Screen split scan line
6802h 2 N W SSA Screen split secondary start address
6804h 1 Y W SSCR Soft scroll control register
6805h 1 N W IVR Interrupt Vector (Bit 0 set to 1 on reset)
6806h 2 (unused)
6808h 1 R ADC0 Analogue input channel 0
6809h 1 R ADC1 Analogue input channel 1
680Ah 1 R ADC2 Analogue input channel 2
680Bh 1 R ADC3 Analogue input channel 3
680Ch 1 R ADC4 Analogue input channel 4
680Dh 1 R ADC5 Analogue input channel 5
680Eh 1 R ADC6 Analogue input channel 6
680Fh 1 R ADC7 Analogue input channel 7
Block unused
6C00h 2 N W SAR0 "DMA" channel 0 address pointer
6C02h 1 N W PPR0 "DMA" channel 0 pause prescaler
6C03h 1 (unused)
6C04h 2 N W SAR1 "DMA" channel 1 address pointer
6C06h 1 N W PPR1 "DMA" channel 1 pause prescaler
6C07h 1 (unused)
6C08h 2 N W SAR2 "DMA" channel 2 address pointer
6C0Ah 1 N W PPR2 "DMA" channel 2 pause prescaler
6C0Bh 4 (unused)
6C0Fh 1 Y R/W DCSR "DMA" control/status register
Block unused

POR column indicates whether a register has power-on reset. A "N" indicates that the contents of a register are undefined at power-on.


Beware, when booting your software from cartridge. Z80 is in Interrupt Mode 0 by default. Stack Pointer is uninitialized. FDC is in DMA mode by default. And hardware sprites memory has random value.

Anyway, you have to initialize all internal components (Z80, PPI, CRTC, AY, etc) when you are booting from cartridge.


Links


Related pages