<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://oldwiki.cpcwiki.eu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Urusergi</id>
		<title>CPCWiki - THE Amstrad CPC encyclopedia! - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://oldwiki.cpcwiki.eu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Urusergi"/>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php/Special:Contributions/Urusergi"/>
		<updated>2026-08-28T07:26:22Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Keyboard_scanning&amp;diff=127106</id>
		<title>Programming:Keyboard scanning</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Keyboard_scanning&amp;diff=127106"/>
				<updated>2026-01-14T14:59:51Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Complete keyboard scanning routine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware scancodes ==&lt;br /&gt;
&lt;br /&gt;
=== English table ===&lt;br /&gt;
{|{{Prettytable|width: 700px; font-size: 2em;}}&lt;br /&gt;
|'''Bit:&amp;lt;br&amp;gt;Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;40''' || F Dot || ENTER || F3 || F6 || F9 || CURDOWN || CURRIGHT || CURUP&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPY || CURLEFT&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;42''' || CONTROL || \ ` || SHIFT || F4 || ] } || RETURN || [ { || CLR&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;43''' || . &amp;gt; || / ? || : * || ; + || P || @ ¦ || - = || ^ £&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;44''' || , &amp;lt; || M || K || L || I || O || 9 ) || 0 _&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;45''' || SPACE || N || J || H || Y || U || 7 ' || 8 (&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;46''' || V || B (Joy2 fire3) || F (Joy2 fire2) || G (Joy2 fire1) || T (Joy2 right) || R (Joy2 left) || 5 % (Joy2 down)|| 6 &amp;amp; (Joy2 up)&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;47''' || X || C || D || S || W || E || 3 # || 4 $&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;48''' || Z || CAPSLOCK || A || TAB || Q || ESC || 2 &amp;quot; || 1 !&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;49''' || DEL || Joy1 fire3 || Joy1 fire2 ||Joy1 fire1||Joy1 right||Joy1 left||Joy1 down||Joy1 up&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Danish table ===&lt;br /&gt;
{|{{Prettytable|width: 700px; font-size: 2em;}}&lt;br /&gt;
|'''Bit:&amp;lt;br&amp;gt;Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;40''' || F Dot || ENTER || F3 || F6 || F9 || CURDOWN || CURRIGHT || CURUP&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPY || CURLEFT&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;42''' || CONTROL || ; + || SHIFT || F4 || : * || RETURN || @ \ || CLR&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;43''' || . &amp;gt; || / ? || Æ || Ø || P || Å || - = || ^ £&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;44''' || , &amp;lt; || M || K || L || I || O || 9 ) || 0 _&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;45''' || SPACE || N || J || H || Y || U || 7 ' || 8 (&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;46''' || V || B (Joy2 fire3) || F (Joy2 fire2) || G (Joy2 fire1) || T (Joy2 right) || R (Joy2 left) || 5 % (Joy2 down)|| 6 &amp;amp; (Joy2 up)&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;47''' || X || C || D || S || W || E || 3 # || 4 $&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;48''' || Z || CAPSLOCK || A || TAB || Q || ESC || 2 &amp;quot; || 1 !&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;49''' || DEL || Joy1 fire3 || Joy1 fire2 ||Joy1 fire1||Joy1 right||Joy1 left||Joy1 down||Joy1 up&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Spanish table ===&lt;br /&gt;
{|{{Prettytable|width: 700px; font-size: 2em;}}&lt;br /&gt;
|'''Bit:&amp;lt;br&amp;gt;Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;40''' || F Dot || INTRO || F3 || F6 || F9 || CURDOWN || CURRIGHT || CURUP&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPIA || CURLEFT&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;42''' || CONTROL || \ ` || MAYS || F4 || ] + || RETURN || [ * || CLR&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;43''' || . &amp;gt; || / ? || Ñ || ; : || P || @ ¦ || - = || ^ ₧&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;44''' || , &amp;lt; || M || K || L || I || O || 9 ) || 0 _&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;45''' || SPACE || N || J || H || Y || U || 7 ' || 8 (&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;46''' || V || B (Joy2 fire3) || F (Joy2 fire2) || G (Joy2 fire1) || T (Joy2 right) || R (Joy2 left) || 5 % (Joy2 down)|| 6 &amp;amp; (Joy2 up)&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;47''' || X || C || D || S || W || E || 3 # || 4 $&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;48''' || Z || FIJA MAYS || A || TAB || Q || ESC || 2 &amp;quot; || 1 !&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;49''' || BORR || Joy1 fire3 || Joy1 fire2 ||Joy1 fire1||Joy1 right||Joy1 left||Joy1 down||Joy1 up&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== French table ===&lt;br /&gt;
{|{{Prettytable|width: 700px; font-size: 2em;}}&lt;br /&gt;
|'''Bit:&amp;lt;br&amp;gt;Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;40''' || F Dot || ENTER || F3 || F6 || F9 || CURDOWN || CURRIGHT || CURUP&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPY || CURLEFT&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;42''' || CONTROL || $ @\ || SHIFT || F4 || # &amp;gt; || RETURN || * &amp;lt; || CLR&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;43''' || : / || = + || M || ù % || P || ^ ¦ || ) [ || - _&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;44''' || ; . || , ? || K || L || I || O || ç 9 || à 0&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;45''' || SPACE || N || J || H || Y || U || è 7 || ! 8&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;46''' || V || B (Joy2 fire3) || F (Joy2 fire2) || G (Joy2 fire1) || T (Joy2 right) || R (Joy2 left) || ( 5 (Joy2 down)|| ] 6 (Joy2 up)&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;47''' || X || C || D || S || Z || E || &amp;quot; 3 || ' 4&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;48''' || W || CAPSLOCK || Q || TAB || A || ESC || é 2 || &amp;amp; 1&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;49''' || DEL || Joy1 fire3 || Joy1 fire2 ||Joy1 fire1||Joy1 right||Joy1 left||Joy1 down||Joy1 up&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: Fire3 only work on Amstrad CPC, not on Amstrad Plus.&lt;br /&gt;
&lt;br /&gt;
== Computing key code ==&lt;br /&gt;
&lt;br /&gt;
System key codes (codes that are writted on the top of the disc drive on 664/6128 or in the CPC user manual) can be computed with the formula : (Line*8)+bit&lt;br /&gt;
&lt;br /&gt;
Example : for key SHIFT , Line = 2 , bit = 5 so (2*8)+5 = 21&lt;br /&gt;
&lt;br /&gt;
== Keyboard clash ==&lt;br /&gt;
&lt;br /&gt;
This is the name of the phenomenon when a &amp;quot;ghost&amp;quot; or &amp;quot;phantom&amp;quot; key is generated when you press some combinations of keys.&lt;br /&gt;
It is caused by the design of the keyboard hardware. It has been tested and confirmed that keyboard clash doesn't occur on an English CPC664 keyboard.&lt;br /&gt;
&lt;br /&gt;
For example, pressing Q,A,P will also generate :.&lt;br /&gt;
&lt;br /&gt;
The ':' key is the &amp;quot;ghost&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
The problem is much bigger in 2 player games.&lt;br /&gt;
&lt;br /&gt;
It is possible to avoid or minimize the problem by carefully choosing the controls. The problem also occurs when using digital joysticks because these are part of the keyboard matrix.&lt;br /&gt;
&lt;br /&gt;
If you visualize a rectangle in the keyboard matrix above, where 3 of the corners are 3 keys you have pressed. Then the key in the fourth corner will also be pressed this is the &amp;quot;ghost&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
On Plus it is possible to avoid it mostly by having one player on analogue joystick and the other on keyboard/digital joystick.&lt;br /&gt;
&lt;br /&gt;
== One line scanning routine ==&lt;br /&gt;
&lt;br /&gt;
This is a routine which scans one line of the keyboard directly. It is approximately 8% faster than the firmware routine and doesn't enable interrupts.&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''line (&amp;amp;amp;40 - &amp;amp;amp;49)''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A = ''hardware keyboard value''&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' BC&lt;br /&gt;
&amp;lt;pre&amp;gt;LD A,kbdline ; from &amp;amp;40 to &amp;amp;49 with bdir/bc1=01&lt;br /&gt;
LD D,0&lt;br /&gt;
LD BC,#F782 ; PPI port A out /C out &lt;br /&gt;
OUT (C),C &lt;br /&gt;
LD BC,#F40E ; Select Ay reg 14 on ppi port A &lt;br /&gt;
OUT (C),C &lt;br /&gt;
LD BC,#F6C0 ; This value is an AY index (R14) &lt;br /&gt;
OUT (C),C &lt;br /&gt;
OUT (C),D ; Validate!! out (c),0&lt;br /&gt;
LD BC,#F792 ; PPI port A in/C out &lt;br /&gt;
OUT (C),C &lt;br /&gt;
DEC B &lt;br /&gt;
OUT (C),A ; Send KbdLine on reg 14 AY through ppi port A&lt;br /&gt;
LD B,#F4 ; Read ppi port A &lt;br /&gt;
IN A,(C) ; e.g. AY R14 (AY port A) &lt;br /&gt;
LD BC,#F782 ; PPI port A out / C out &lt;br /&gt;
OUT (C),C &lt;br /&gt;
DEC B ; Reset PPI Write &lt;br /&gt;
OUT (C),D ; out (c),0&lt;br /&gt;
&lt;br /&gt;
Register A now holds the value of requested keyboard row&lt;br /&gt;
Now check for the value from the table e.g. with''''bit x,A''''and a condition e.g.''''jp z,xxxx''''or''''call z,xxxx''''&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Please note:&lt;br /&gt;
&lt;br /&gt;
* Bit = 0: Key is pressed&lt;br /&gt;
* Bit = 1: Key is not pressed&lt;br /&gt;
&lt;br /&gt;
== Complete keyboard scanning routine ==&lt;br /&gt;
&lt;br /&gt;
This routine scans the complete keyboard and writes all key status bits in a map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
keymap  ds 10  ;map with 10*8 = 80 key status bits (bit=0 key is pressed)&lt;br /&gt;
&lt;br /&gt;
keyscan di              ;1 ##%%## C P C   VERSION ##%%##&lt;br /&gt;
        xor a           ;1&lt;br /&gt;
        ld hl,keymap    ;3&lt;br /&gt;
        ld bc,#f782     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld bc,#f40e     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld e,b          ;1&lt;br /&gt;
        ld bc,#f6c0     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld d,b          ;1&lt;br /&gt;
        out (c),a       ;4&lt;br /&gt;
        sub c           ;1 a=#40 (-#C0)&lt;br /&gt;
        ld bc,#f792     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld c,d          ;1 (+41)&lt;br /&gt;
loop    ld b,d          ;1&lt;br /&gt;
        out (c),a       ;4 select line&lt;br /&gt;
        ld b,e          ;1&lt;br /&gt;
        ini             ;5 read bits and write into KEYMAP&lt;br /&gt;
        inc a           ;1&lt;br /&gt;
        inc c           ;1&lt;br /&gt;
        jr nz,loop      ;2/3 (9*16+1*15 = 159)&lt;br /&gt;
        ld bc,#f782     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ei              ;1 (+8 = 208 microseconds)&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Developing programs that use joystick ==&lt;br /&gt;
&lt;br /&gt;
In the CPC world it is more common that a game supports both keyboard and digital joystick for those users who don't own joysticks.&lt;br /&gt;
In addition, it is also nice if the keys could be redefined but that is not necessary.&lt;br /&gt;
&lt;br /&gt;
The standard CPC can support 3 buttons per joystick, though many CPC joysticks only have 1 button.&lt;br /&gt;
&lt;br /&gt;
The CPC+ and GX4000 only support 2 buttons per joystick, and the included Amstrad joypads have 2 buttons.&lt;br /&gt;
&lt;br /&gt;
There are some common keyboard configurations used:&lt;br /&gt;
&lt;br /&gt;
* '''Joystick''' - This configuration is compatible with all Amstrad machines, even the GX4000 and you need to scan only one keyboard line (this means you can't be faster)&lt;br /&gt;
&lt;br /&gt;
* '''Cursor keys &amp;amp; SPACE''' - This configuration is often used and is great for the CPC6128 and Plus and playing using emulators. This is '''not''' good for CPC 464 and 664 (which have uncomfortably arranged cursor keys)&lt;br /&gt;
&lt;br /&gt;
* '''Q,A,O,P,SPACE''' - (Q up, A down, O left, P right, SPACE fire) This is a good solution, and it's a sort of standard (used by many games). It is best for english QWERTY keyboards, on french AZERTY it'd be A-Q-O-P (but because the decoding of the keys is done in software, normally by the OS, the bits in the keyboard matrix are actually the same).&lt;br /&gt;
&lt;br /&gt;
The standard CPC has only 1 digital joystick port (and no analog joystick port). But it was possible to daisy chain the official Amstrad joysticks. And a common accessory, the joystick port doubler, offered 2 digital joystick ports. &lt;br /&gt;
&lt;br /&gt;
The CPC+ and GX4000 have 2 digital joystick ports built-in (and 1 analog joystick port).&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Digital Joysticks]]&lt;br /&gt;
* [[Keyboard Versions]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]][[Category:CPC Internal Components]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=CPCng&amp;diff=124743</id>
		<title>CPCng</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=CPCng&amp;diff=124743"/>
				<updated>2025-04-17T18:46:24Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:Cpcng.jpg|thumb|CPCng case design]]&lt;br /&gt;
&lt;br /&gt;
The '''CPCng''' (CPC next generation) projects aim was to build a new and very poweful Amstrad CPC compatible computer. The project was managed by [[Christophe Guelff]] from France. It should be based on an eZ80 CPU and could run in CPC compatible mode or in an extended 16bit mode.&lt;br /&gt;
&lt;br /&gt;
Currently the project seems to be on hold or dead. Also with the release of the [[CPC TREX]] with its [[TobiFlex]] 24MHz TurboCPC core the question appeared, if the originally CPCng project still makes sense, or if it would be better to focus on a pure FPGA-based ready-produced industrial solutions like the CPC TREX.&lt;br /&gt;
&lt;br /&gt;
Nevertheless Douglas Beatties CPCng homepage has still been updated not a long time ago, so there is still the chance, that the CPCng will be reality at some day.&lt;br /&gt;
&lt;br /&gt;
== Web links ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.hanssummers.com/cpcng.html Hans Summers CPCng homepage]&lt;br /&gt;
* [http://cpcng.hytherion.com/ Douglas Beatties CPCng homepage]&lt;br /&gt;
* [http://fr.wikipedia.org/wiki/Color_Computer_New_Generation french Wikipedia article]&lt;br /&gt;
* [http://www.digi-alt.net/cpcoxygen/magazine/08/contents.htm CPCng special in CPC Oxygen #8]&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]][[Category:Vaporware]][[Category:Non CPC Computers]][[Category:Clones]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124349</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124349"/>
				<updated>2025-04-07T19:10:45Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Urusergi version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
It still uses some magic numbers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD		; a = #CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
&lt;br /&gt;
No magic numbers here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v3.1 -&amp;gt; 30 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0		; db #ED,#71&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),a&lt;br /&gt;
ld h,a			; h = 7654 3210&lt;br /&gt;
add hl,hl		; h = 6543 210*&lt;br /&gt;
rra			; a = 7765 4321&lt;br /&gt;
add hl,hl		; h = 5432 10**&lt;br /&gt;
xor h:and #F7:xor h	; a = 7765 1321&lt;br /&gt;
ld l,a			; l = 7765 1321&lt;br /&gt;
ld a,h			; a = 5432 10**&lt;br /&gt;
rla			; a = 4321 0***&lt;br /&gt;
and #88:xor l		; a = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Algorithm ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    out(b, c)&lt;br /&gt;
    out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        out(b, a)&lt;br /&gt;
        # a = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
        a = ((a &amp;gt;&amp;gt; 1) &amp;amp; 0x77) | ((a ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x80) | (((a &amp;lt;&amp;lt; 2) ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x08)&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx  Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
According to [https://patents.google.com/patent/GB2243701A/en Google patents for GB2243701A] the patent was withdrawn on 1994-12-21. This means that this particular patent cannot be enforced.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124335</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124335"/>
				<updated>2025-04-07T14:38:20Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Urusergi version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
It still uses some magic numbers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD		; a = #CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
&lt;br /&gt;
No magic numbers here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v3.0 -&amp;gt; 30 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0		; db #ED,#71&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),a&lt;br /&gt;
ld h,a			; h = 7654 3210&lt;br /&gt;
add hl,hl		; h = 6543 210*&lt;br /&gt;
rra			; a = 7765 4321&lt;br /&gt;
add hl,hl		; h = 5432 10**&lt;br /&gt;
xor h:and #F7:xor h	; a = 7765 1321&lt;br /&gt;
ld l,a			; l = 7765 1321&lt;br /&gt;
ld a,h			; a = 5432 10**&lt;br /&gt;
rla			; a = 4321 0***&lt;br /&gt;
and #88:xor l		; a = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Algorithm ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    out(b, c)&lt;br /&gt;
    out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        out(b, a)&lt;br /&gt;
        # a = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
        a = ((a &amp;gt;&amp;gt; 1) &amp;amp; 0x77) | ((a ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x80) | (((a &amp;lt;&amp;lt; 2) ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x08)&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx  Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124315</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124315"/>
				<updated>2025-04-06T13:02:42Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Urusergi version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
It still uses some magic numbers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD		; a = #CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
&lt;br /&gt;
No magic numbers here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v3.0 -&amp;gt; 30 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0		; db #ED,#71&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),a&lt;br /&gt;
ld h,a			; h = 7654 3210&lt;br /&gt;
add hl,hl		; h = 6543 210*&lt;br /&gt;
rra			; a = 7765 4321&lt;br /&gt;
add hl,hl		; h = 5432 10**&lt;br /&gt;
xor h:and #F7:xor h	; a = 7765 1321&lt;br /&gt;
add hl,hl		; h = 4321 0***&lt;br /&gt;
ld l,a			; l = 7765 1321&lt;br /&gt;
ld a,h			; a = 4321 0***&lt;br /&gt;
and #88:xor l		; a = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Algorithm ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    out(b, c)&lt;br /&gt;
    out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        out(b, a)&lt;br /&gt;
        # a = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
        a = ((a &amp;gt;&amp;gt; 1) &amp;amp; 0x77) | ((a ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x80) | (((a &amp;lt;&amp;lt; 2) ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x08)&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx  Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124285</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124285"/>
				<updated>2025-04-05T17:22:26Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Urusergi version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
It still uses some magic numbers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD		; a = #CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
&lt;br /&gt;
No magic numbers here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v3.0 -&amp;gt; 30 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),a&lt;br /&gt;
ld h,a			; h = 7654 3210&lt;br /&gt;
add hl,hl		; h = 6543 210*&lt;br /&gt;
rra			; a = 7765 4321&lt;br /&gt;
add hl,hl		; h = 5432 10**&lt;br /&gt;
xor h:and #F7:xor h	; a = 7765 1321&lt;br /&gt;
add hl,hl		; h = 4321 0***&lt;br /&gt;
ld l,a			; l = 7765 1321&lt;br /&gt;
ld a,h			; a = 4321 0***&lt;br /&gt;
and #88:xor l		; a = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Algorithm ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    out(b, c)&lt;br /&gt;
    out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        out(b, a)&lt;br /&gt;
        # a = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
        a = ((a &amp;gt;&amp;gt; 1) &amp;amp; 0x77) | ((a ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x80) | (((a &amp;lt;&amp;lt; 2) ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x08)&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)} Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124283</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124283"/>
				<updated>2025-04-05T15:28:26Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Madram version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
It still uses some magic numbers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD		; a = #CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
&lt;br /&gt;
No magic numbers here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v3.0 -&amp;gt; 30 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),a&lt;br /&gt;
ld h,a			; h = 7654 3210&lt;br /&gt;
add hl,hl		; h = 6543 210*&lt;br /&gt;
rra			; a = 7765 4321&lt;br /&gt;
add hl,hl		; h = 5432 10**&lt;br /&gt;
xor h:and #F7:xor h	; a = 7765 1321&lt;br /&gt;
add hl,hl		; h = 4321 0***&lt;br /&gt;
ld l,a			; l = 7765 1321&lt;br /&gt;
ld a,h			; a = 4321 0***&lt;br /&gt;
and #88&lt;br /&gt;
xor l&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Algorithm ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    out(b, c)&lt;br /&gt;
    out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        out(b, a)&lt;br /&gt;
        a = ((a &amp;gt;&amp;gt; 1) &amp;amp; 0x77) | ((a ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x80) | (((a &amp;lt;&amp;lt; 2) ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x08)&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)} Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124282</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124282"/>
				<updated>2025-04-05T15:24:31Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Madram version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
It still uses some magic numbers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD		; a=#CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
&lt;br /&gt;
No magic numbers here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v3.0 -&amp;gt; 30 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),a&lt;br /&gt;
ld h,a			; h = 7654 3210&lt;br /&gt;
add hl,hl		; h = 6543 210*&lt;br /&gt;
rra			; a = 7765 4321&lt;br /&gt;
add hl,hl		; h = 5432 10**&lt;br /&gt;
xor h:and #F7:xor h	; a = 7765 1321&lt;br /&gt;
add hl,hl		; h = 4321 0***&lt;br /&gt;
ld l,a			; l = 7765 1321&lt;br /&gt;
ld a,h			; a = 4321 0***&lt;br /&gt;
and #88&lt;br /&gt;
xor l&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Algorithm ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    out(b, c)&lt;br /&gt;
    out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        out(b, a)&lt;br /&gt;
        a = ((a &amp;gt;&amp;gt; 1) &amp;amp; 0x77) | ((a ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x80) | (((a &amp;lt;&amp;lt; 2) ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x08)&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)} Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124281</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=124281"/>
				<updated>2025-04-05T15:09:21Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Urusergi version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
It still uses some magic numbers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UnlockAsic&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
.loop&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD      ; a=#CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
&lt;br /&gt;
No magic numbers here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v3.0 -&amp;gt; 30 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
out (c),a&lt;br /&gt;
ld h,a			; h = 7654 3210&lt;br /&gt;
add hl,hl		; h = 6543 210*&lt;br /&gt;
rra			; a = 7765 4321&lt;br /&gt;
add hl,hl		; h = 5432 10**&lt;br /&gt;
xor h:and #F7:xor h	; a = 7765 1321&lt;br /&gt;
add hl,hl		; h = 4321 0***&lt;br /&gt;
ld l,a			; l = 7765 1321&lt;br /&gt;
ld a,h			; a = 4321 0***&lt;br /&gt;
and #88&lt;br /&gt;
xor l&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Algorithm ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    out(b, c)&lt;br /&gt;
    out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        out(b, a)&lt;br /&gt;
        a = ((a &amp;gt;&amp;gt; 1) &amp;amp; 0x77) | ((a ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x80) | (((a &amp;lt;&amp;lt; 2) ^ (a &amp;lt;&amp;lt; 3)) &amp;amp; 0x08)&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)} Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123970</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123970"/>
				<updated>2025-03-29T20:37:33Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Urusergi version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
In Z80 Assembler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UnlockAsic&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
.loop&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD      ; a=#CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c, h, l = 0xBC, 0xFF, 0x90, 0xEA  # Initialize registers&lt;br /&gt;
    port_out(b, c)&lt;br /&gt;
    port_out(b, 0)&lt;br /&gt;
&lt;br /&gt;
    while c != 0x4D:&lt;br /&gt;
        port_out(b, c)&lt;br /&gt;
        h, l = l, ((h &amp;lt;&amp;lt; 1) | (h &amp;gt;&amp;gt; 7)) &amp;amp; 0xFF  # Rotate h and swap h,l&lt;br /&gt;
        c = ((c &amp;gt;&amp;gt; 1) &amp;amp; ~(1 &amp;lt;&amp;lt; 3)) | (l &amp;amp; 0x88)  # Modify c&lt;br /&gt;
&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
&lt;br /&gt;
def port_out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
In Z80 Assembler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v2.0 -&amp;gt; 31 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
.loop&lt;br /&gt;
out (c),a&lt;br /&gt;
ld h,a			; H = 7654 3210&lt;br /&gt;
rra			; A = *765 4321&lt;br /&gt;
add hl,hl		; H = 6543 210-&lt;br /&gt;
push af			; Carry flag (bit 7) preserved&lt;br /&gt;
add hl,hl		; H = 5432 10--&lt;br /&gt;
add hl,hl		; H = 4321 0---&lt;br /&gt;
pop af			; Carry flag (bit 7) recovered&lt;br /&gt;
ld l,a			; L = *765 4321&lt;br /&gt;
ld a,h			; A = 4321 0---&lt;br /&gt;
rra			; A = 7432 10--&lt;br /&gt;
xor h			; A = (7 xor 4)*** (1 xor 0)***&lt;br /&gt;
xor l:and #88:xor l	; A = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    port_out(b, c)&lt;br /&gt;
    port_out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        port_out(b, a)&lt;br /&gt;
        d = a&lt;br /&gt;
        a = (((a &amp;lt;&amp;lt; 2 | a &amp;gt;&amp;gt; 6) ^ d) &amp;amp; 0x7F) ^ d&lt;br /&gt;
        d = (d &amp;gt;&amp;gt; 1 | d &amp;lt;&amp;lt; 7) &amp;amp; 0xFF&lt;br /&gt;
        a = ((((a &amp;lt;&amp;lt; 1 | a &amp;gt;&amp;gt; 7) ^ a) ^ d) &amp;amp; 0x88) ^ d&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def port_out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123969</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123969"/>
				<updated>2025-03-29T18:52:03Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Urusergi version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
In Z80 Assembler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UnlockAsic&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
.loop&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD      ; a=#CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c, h, l = 0xBC, 0xFF, 0x90, 0xEA  # Initialize registers&lt;br /&gt;
    port_out(b, c)&lt;br /&gt;
    port_out(b, 0)&lt;br /&gt;
&lt;br /&gt;
    while c != 0x4D:&lt;br /&gt;
        port_out(b, c)&lt;br /&gt;
        h, l = l, ((h &amp;lt;&amp;lt; 1) | (h &amp;gt;&amp;gt; 7)) &amp;amp; 0xFF  # Rotate h and swap h,l&lt;br /&gt;
        c = ((c &amp;gt;&amp;gt; 1) &amp;amp; ~(1 &amp;lt;&amp;lt; 3)) | (l &amp;amp; 0x88)  # Modify c&lt;br /&gt;
&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
&lt;br /&gt;
def port_out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
In Z80 Assembler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v2.0 -&amp;gt; 31 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
.loop&lt;br /&gt;
out (c),a&lt;br /&gt;
ld h,a			; H = 7654 3210&lt;br /&gt;
add hl,hl		; H = 6543 210-&lt;br /&gt;
push af			; Carry flag (bit 7) preserved&lt;br /&gt;
add hl,hl		; H = 5432 10--&lt;br /&gt;
add hl,hl		; H = 4321 0---&lt;br /&gt;
rra			; A = 5765 4321&lt;br /&gt;
ld l,a			; L = 5765 4321&lt;br /&gt;
pop af			; Carry flag (bit 7) recovered&lt;br /&gt;
ld a,h			; A = 4321 0---&lt;br /&gt;
rra			; A = 7432 10--&lt;br /&gt;
xor h			; A = (7 xor 4)*** (1 xor 0)***&lt;br /&gt;
xor l:and #88:xor l	; A = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    port_out(b, c)&lt;br /&gt;
    port_out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        port_out(b, a)&lt;br /&gt;
        d = a&lt;br /&gt;
        a = (((a &amp;lt;&amp;lt; 2 | a &amp;gt;&amp;gt; 6) ^ d) &amp;amp; 0x7F) ^ d&lt;br /&gt;
        d = (d &amp;gt;&amp;gt; 1 | d &amp;lt;&amp;lt; 7) &amp;amp; 0xFF&lt;br /&gt;
        a = ((((a &amp;lt;&amp;lt; 1 | a &amp;gt;&amp;gt; 7) ^ a) ^ d) &amp;amp; 0x88) ^ d&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def port_out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123968</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123968"/>
				<updated>2025-03-29T18:22:19Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Urusergi version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized versions =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== [[Madram]] version ==&lt;br /&gt;
&lt;br /&gt;
In Z80 Assembler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UnlockAsic&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
.loop&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD      ; a=#CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c, h, l = 0xBC, 0xFF, 0x90, 0xEA  # Initialize registers&lt;br /&gt;
    port_out(b, c)&lt;br /&gt;
    port_out(b, 0)&lt;br /&gt;
&lt;br /&gt;
    while c != 0x4D:&lt;br /&gt;
        port_out(b, c)&lt;br /&gt;
        h, l = l, ((h &amp;lt;&amp;lt; 1) | (h &amp;gt;&amp;gt; 7)) &amp;amp; 0xFF  # Rotate h and swap h,l&lt;br /&gt;
        c = ((c &amp;gt;&amp;gt; 1) &amp;amp; ~(1 &amp;lt;&amp;lt; 3)) | (l &amp;amp; 0x88)  # Modify c&lt;br /&gt;
&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
&lt;br /&gt;
def port_out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[Urusergi]] version ==&lt;br /&gt;
In Z80 Assembler:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di			; v2.0 -&amp;gt; 31 bytes!&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
.loop&lt;br /&gt;
out(c),a&lt;br /&gt;
ld h,a			; H = 7654 3210&lt;br /&gt;
add hl,hl		; H = 6543 210-&lt;br /&gt;
push af			; Carry flag (bit 7) preserved&lt;br /&gt;
add hl,hl		; H = 5432 10--&lt;br /&gt;
add hl,hl		; H = 4321 0---&lt;br /&gt;
rra			; A = 5765 4321&lt;br /&gt;
ld l,a			; L = 5765 4321&lt;br /&gt;
pop af			; Carry flag (bit 7) recovered&lt;br /&gt;
ld a,h			; A = 4321 0---&lt;br /&gt;
rra			; A = 7432 10--&lt;br /&gt;
xor h			; A = (7 xor 4)*** (1 xor 0)***&lt;br /&gt;
xor l:and #88:xor l	; A = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Python:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c = 0xBC, 0xFF&lt;br /&gt;
    port_out(b, c)&lt;br /&gt;
    port_out(b, 0)&lt;br /&gt;
    a = c&lt;br /&gt;
    &lt;br /&gt;
    while True:&lt;br /&gt;
        port_out(b, a)&lt;br /&gt;
        d = a&lt;br /&gt;
        a = (((a &amp;lt;&amp;lt; 2 | a &amp;gt;&amp;gt; 6) ^ d) &amp;amp; 0x7F) ^ d&lt;br /&gt;
        d = (d &amp;gt;&amp;gt; 1 | d &amp;lt;&amp;lt; 7) &amp;amp; 0xFF&lt;br /&gt;
        a = ((((a &amp;lt;&amp;lt; 1 | a &amp;gt;&amp;gt; 7) ^ a) ^ d) &amp;amp; 0x88) ^ d&lt;br /&gt;
        if a == c: break&lt;br /&gt;
&lt;br /&gt;
def port_out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123587</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123587"/>
				<updated>2025-03-18T15:22:04Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized version =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== In Z80 Assembler ==&lt;br /&gt;
&lt;br /&gt;
This allowed [[Madram]] to create this optimized lock-unlock routine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UnlockAsic&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
&lt;br /&gt;
.loop&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
&lt;br /&gt;
ld a,#CD      ; a=#CD for unlock, another value for lock&lt;br /&gt;
out (c),a:out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another optimized unlock routine by [[Urusergi]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld a,c&lt;br /&gt;
&lt;br /&gt;
.loop&lt;br /&gt;
out (c),a&lt;br /&gt;
ld d,a			; D = 7654 3210&lt;br /&gt;
rlca:rlca		; A = 5432 1076&lt;br /&gt;
xor d:and #7F:xor d	; A = 7432 1076&lt;br /&gt;
ld e,a&lt;br /&gt;
rlca			; A = 4321 0767&lt;br /&gt;
xor e			; A = 7432 1076 XOR 4321 0767&lt;br /&gt;
rrc d			; D = 0765 4321&lt;br /&gt;
xor d:and #88:xor d	; A = (7 xor 4)765 (1 xor 0)321&lt;br /&gt;
cp c&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== In Python ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c, h, l = 0xBC, 0xFF, 0x90, 0xEA  # Initialize registers&lt;br /&gt;
    port_out(b, c)&lt;br /&gt;
    port_out(b, 0)&lt;br /&gt;
&lt;br /&gt;
    while c != 0x4D:&lt;br /&gt;
        port_out(b, c)&lt;br /&gt;
        h, l = l, ((h &amp;lt;&amp;lt; 1) | (h &amp;gt;&amp;gt; 7)) &amp;amp; 0xFF  # Rotate h and swap h, l&lt;br /&gt;
        c = ((c &amp;gt;&amp;gt; 1) &amp;amp; ~(1 &amp;lt;&amp;lt; 3)) | (l &amp;amp; 0x88)  # Modify c&lt;br /&gt;
&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
&lt;br /&gt;
def port_out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123586</id>
		<title>Programming:Unlocking ASIC</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Unlocking_ASIC&amp;diff=123586"/>
				<updated>2025-03-18T14:51:32Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* In Z80 Assembler */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To unlock the [[ASIC]], a 17-byte &amp;quot;unlock&amp;quot; sequence must be sent to the [[CRTC]]'s selection port (&amp;amp;BC00) :&lt;br /&gt;
RQ00, 0, 255, 119, 179, 81, 168, 212, 98, 57, 156, 70, 43, 21, 138, STATE, &amp;lt;ACQ&amp;gt;&lt;br /&gt;
* RQ00 must be different from the value 0.&lt;br /&gt;
* STATE=205 for UNLOCK otherwise another value for LOCK.&lt;br /&gt;
* ACQ represents sending any value if STATE=205 (not needed otherwise).&lt;br /&gt;
&lt;br /&gt;
Note: the ASIC is already unlocked after the STATE phase, before ACQ. So ACQ is actually never needed.&lt;br /&gt;
&lt;br /&gt;
Once the ASIC is unlocked, we get access to a new [[Gate Array]] register called RMR2. It is accessible in the same way as other Gate Array registers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= BASIC version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
10 RESTORE &lt;br /&gt;
20 FOR x=0 TO 16:READ a:OUT &amp;amp;BC00,a:NEXT &lt;br /&gt;
30 DATA 255,0,255,119,179,81,168,212,98,57,156,70,43,21,138,205,238 &lt;br /&gt;
40 PRINT&amp;quot;ASIC unlocked!&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Z80 Assembler version =&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This example shows how to unlock the ASIC&lt;br /&gt;
;;&lt;br /&gt;
;; This example is designed for CPC+ only and will&lt;br /&gt;
;; not work on CPC or KC Compact.&lt;br /&gt;
;;&lt;br /&gt;
;; This example will compile with the MAXAM assembler&lt;br /&gt;
;; or the built-in assembler of WinAPE32.&lt;br /&gt;
&lt;br /&gt;
org &amp;amp;8000&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
;; Unlock CPC+ additional features&lt;br /&gt;
&lt;br /&gt;
di&lt;br /&gt;
ld b,&amp;amp;bc&lt;br /&gt;
ld hl,sequence&lt;br /&gt;
ld e,17&lt;br /&gt;
.seq &lt;br /&gt;
ld a,(hl)&lt;br /&gt;
out (c),a&lt;br /&gt;
inc hl&lt;br /&gt;
dec e&lt;br /&gt;
jr nz,seq&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
;;----------------------------------------------------------&lt;br /&gt;
;; this is the sequence to unlock the ASIC extra features&lt;br /&gt;
.sequence&lt;br /&gt;
defb &amp;amp;ff,&amp;amp;00,&amp;amp;ff,&amp;amp;77,&amp;amp;b3,&amp;amp;51,&amp;amp;a8,&amp;amp;d4,&amp;amp;62,&amp;amp;39,&amp;amp;9c,&amp;amp;46,&amp;amp;2b,&amp;amp;15,&amp;amp;8a,&amp;amp;cd,&amp;amp;ee&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Optimized version =&lt;br /&gt;
&lt;br /&gt;
The unlocking sequence can be reconstituted from simple bit operations instead of being stored in memory.&lt;br /&gt;
&lt;br /&gt;
== In Z80 Assembler ==&lt;br /&gt;
&lt;br /&gt;
This allowed [[Madram]] to create this optimized unlock routine:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UnlockAsic&lt;br /&gt;
di&lt;br /&gt;
ld bc,#BCFF&lt;br /&gt;
out (c),c&lt;br /&gt;
out (c),0&lt;br /&gt;
ld hl,%1001000011101010&lt;br /&gt;
.loop&lt;br /&gt;
out (c),c&lt;br /&gt;
ld a,h:rlca:ld h,l:ld l,a&lt;br /&gt;
srl c&lt;br /&gt;
xor c:and #88:xor c&lt;br /&gt;
ld c,a&lt;br /&gt;
cp #4D&lt;br /&gt;
jr nz,.loop&lt;br /&gt;
ld a,#CD      ; a=#CD for unlock, another value for lock&lt;br /&gt;
out (c),a : out (c),a&lt;br /&gt;
ei&lt;br /&gt;
ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== In Python ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def unlock_asic():&lt;br /&gt;
    b, c, h, l = 0xBC, 0xFF, 0x90, 0xEA  # Initialize registers&lt;br /&gt;
    port_out(b, c)&lt;br /&gt;
    port_out(b, 0)&lt;br /&gt;
&lt;br /&gt;
    while c != 0x4D:&lt;br /&gt;
        port_out(b, c)&lt;br /&gt;
        h, l = l, ((h &amp;lt;&amp;lt; 1) | (h &amp;gt;&amp;gt; 7)) &amp;amp; 0xFF  # Rotate h and swap h, l&lt;br /&gt;
        c = ((c &amp;gt;&amp;gt; 1) &amp;amp; ~(1 &amp;lt;&amp;lt; 3)) | (l &amp;amp; 0x88)  # Modify c&lt;br /&gt;
&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
    port_out(b, 0xCD)&lt;br /&gt;
&lt;br /&gt;
def port_out(port, value):&lt;br /&gt;
    print(f&amp;quot;Port: {hex(port)}xx Out: {hex(value)}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
unlock_asic()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Visual representation =&lt;br /&gt;
&lt;br /&gt;
As one may see, the nybbles in the sequence are based on two 4bit shift registers.&lt;br /&gt;
&lt;br /&gt;
[[File:AsicUnlockSequence.png]]&lt;br /&gt;
&lt;br /&gt;
Visual by [[Hwikaa]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Patent =&lt;br /&gt;
For one reason or another, Amstrad has patented the verification mechanism ([[Media:Patent GB2243701A.pdf|GB2243701A]]).&lt;br /&gt;
&lt;br /&gt;
The patent seems to focus on ''verifying'' (rather than on ''sending'') the sequence, so its legal use is a bit unclear.&lt;br /&gt;
&lt;br /&gt;
On the [[Original Arnold V Specs]] - Issue 1.5 - 10th April 1990, it is precised at §2.11 &amp;quot;Locking of enhanced features&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
it should be noted that unauthorised use of this mechanism may infringe Amstrad's patent.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;br /&gt;
[[Category:CPC Plus]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Keyboard_scanning&amp;diff=114945</id>
		<title>Programming:Keyboard scanning</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Keyboard_scanning&amp;diff=114945"/>
				<updated>2024-03-28T15:55:20Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Complete keyboard scanning routine */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware scancode table ==&lt;br /&gt;
{|{{Prettytable|width: 700px; font-size: 2em;}}&lt;br /&gt;
|'''Bit:&amp;lt;br&amp;gt;Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;40''' || F Dot || ENTER || F3 || F6 || F9 || CURDOWN || CURRIGHT || CURUP&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPY || CURLEFT&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;42''' || CONTROL || \  || SHIFT || F4 || ] || RETURN || [ || CLR&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;43''' || . || / || : || ; || P || @ || - || ^&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;44''' || , || M || K || L || I || O || 9 || 0&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;45''' || SPACE || N || J || H || Y || U || 7 || 8&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;46''' || V || B || F || G (Joy2 fire) || T (Joy2 right) || R (Joy2 left) || 5 (Joy2 down)|| 6 (Joy 2 up)&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;47''' || X || C || D || S || W || E || 3 || 4&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;48''' || Z || CAPSLOCK || A || TAB || Q || ESC || 2 || 1&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;49''' || DEL || Joy 1 Fire 3 (CPC only) || Joy 1 Fire 2 ||Joy1 Fire 1||Joy1 right||Joy1 left||Joy1 down||Joy1 up&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Computing key code ==&lt;br /&gt;
&lt;br /&gt;
System key codes (codes that are writted on the top of the disc drive on 664/6128 or in the CPC user manual) can be computed with the formula : (Line*8)+bit&lt;br /&gt;
&lt;br /&gt;
Example : for key SHIFT , Line = 2 , bit = 5 so (2*8)+5 = 21&lt;br /&gt;
&lt;br /&gt;
== Keyboard clash ==&lt;br /&gt;
&lt;br /&gt;
This is the name of the phenomenon when a &amp;quot;ghost&amp;quot; or &amp;quot;phantom&amp;quot; key is generated when you press some combinations of keys.&lt;br /&gt;
It is caused by the design of the keyboard hardware. It has been tested and confirmed that keyboard clash doesn't occur on an English CPC664 keyboard.&lt;br /&gt;
&lt;br /&gt;
For example, pressing Q,A,P will also generate :.&lt;br /&gt;
&lt;br /&gt;
The ':' key is the &amp;quot;ghost&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
The problem is much bigger in 2 player games.&lt;br /&gt;
&lt;br /&gt;
It is possible to avoid or minimize the problem by carefully choosing the controls. The problem also occurs when using digital joysticks because these are part of the keyboard matrix.&lt;br /&gt;
&lt;br /&gt;
If you visualize a rectangle in the keyboard matrix above, where 3 of the corners are 3 keys you have pressed. Then the key in the fourth corner will also be pressed this is the &amp;quot;ghost&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
On Plus it is possible to avoid it mostly by having one player on analogue joystick and the other on keyboard/digital joystick.&lt;br /&gt;
&lt;br /&gt;
== One line scanning routine ==&lt;br /&gt;
&lt;br /&gt;
This is a routine which scans one line of the keyboard directly. It is approximately 8% faster than the firmware routine and doesn't enable interrupts.&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''line (&amp;amp;amp;40 - &amp;amp;amp;49)''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A = ''hardware keyboard value''&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' BC&lt;br /&gt;
&amp;lt;pre&amp;gt;LD A,kbdline ; from &amp;amp;40 to &amp;amp;49 with bdir/bc1=01&lt;br /&gt;
LD D,0&lt;br /&gt;
LD BC,#F782 ; PPI port A out /C out &lt;br /&gt;
OUT (C),C &lt;br /&gt;
LD BC,#F40E ; Select Ay reg 14 on ppi port A &lt;br /&gt;
OUT (C),C &lt;br /&gt;
LD BC,#F6C0 ; This value is an AY index (R14) &lt;br /&gt;
OUT (C),C &lt;br /&gt;
OUT (C),D ; Validate!! out (c),0&lt;br /&gt;
LD BC,#F792 ; PPI port A in/C out &lt;br /&gt;
OUT (C),C &lt;br /&gt;
DEC B &lt;br /&gt;
OUT (C),A ; Send KbdLine on reg 14 AY through ppi port A&lt;br /&gt;
LD B,#F4 ; Read ppi port A &lt;br /&gt;
IN A,(C) ; e.g. AY R14 (AY port A) &lt;br /&gt;
LD BC,#F782 ; PPI port A out / C out &lt;br /&gt;
OUT (C),C &lt;br /&gt;
DEC B ; Reset PPI Write &lt;br /&gt;
OUT (C),D ; out (c),0&lt;br /&gt;
&lt;br /&gt;
Register A now holds the value of requested keyboard row&lt;br /&gt;
Now check for the value from the table e.g. with''''bit x,A''''and a condition e.g.''''jp z,xxxx''''or''''call z,xxxx''''&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Please note:&lt;br /&gt;
&lt;br /&gt;
* Bit = 0: Key is pressed&lt;br /&gt;
* Bit = 1: Key is not pressed&lt;br /&gt;
&lt;br /&gt;
== Complete keyboard scanning routine ==&lt;br /&gt;
&lt;br /&gt;
This routine scans the complete keyboard and writes all key status bits in a map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
keymap  ds 10  ;map with 10*8 = 80 key status bits (bit=0 key is pressed)&lt;br /&gt;
&lt;br /&gt;
keyscan di              ;1 ##%%## C P C   VERSION ##%%##&lt;br /&gt;
        ld hl,keymap    ;3&lt;br /&gt;
        ld bc,#f782     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld bc,#f40e     ;3&lt;br /&gt;
        ld e,b          ;1&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld bc,#f6c0     ;3&lt;br /&gt;
        ld d,b          ;1&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        xor a           ;1&lt;br /&gt;
        out (c),a       ;4&lt;br /&gt;
        ld bc,#f792     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld a,#40        ;2&lt;br /&gt;
        ld c,d          ;1 (+42)&lt;br /&gt;
loop    ld b,d          ;1&lt;br /&gt;
        out (c),a       ;4 select line&lt;br /&gt;
        ld b,e          ;1&lt;br /&gt;
        ini             ;5 read bits and write into KEYMAP&lt;br /&gt;
        inc a           ;1&lt;br /&gt;
        inc c           ;1&lt;br /&gt;
        jr nz,loop      ;2/3 (9*16+1*15 = 159)&lt;br /&gt;
        ld bc,#f782     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ei              ;1 (+8 = 209 microseconds)&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Developing programs that use joystick ==&lt;br /&gt;
&lt;br /&gt;
In the CPC world it is more common that a game supports both keyboard and digital joystick for those users who don't own joysticks.&lt;br /&gt;
In addition, it is also nice if the keys could be redefined but that is not necessary.&lt;br /&gt;
&lt;br /&gt;
There are some common keyboard configurations used:&lt;br /&gt;
&lt;br /&gt;
* '''Joystick''' - This configuration is compatible with all Amstrad machines, even the GX4000 and you need to scan only one keyboard line (this means you can't be faster)&lt;br /&gt;
&lt;br /&gt;
* '''Cursor keys &amp;amp; SPACE''' - This configuration is often used and is great for the CPC6128 and Plus and playing using emulators. This is '''not''' good for CPC 464 and 664 (which have uncomfortably arranged cursor keys)&lt;br /&gt;
&lt;br /&gt;
* '''Q,A,O,P,SPACE''' - (Q up, A down, O left, P right, SPACE fire) This is a good solution, and it's a sort of standard (used by many games). It is best for english QWERTY keyboards, on french AZERTY it'd be A-Q-O-P (but because the decoding of the keys is done in software, normally by the OS, the bits in the keyboard matrix are actually the same).&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]][[Category:CPC Internal Components]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Keyboard_scanning&amp;diff=105250</id>
		<title>Programming:Keyboard scanning</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Keyboard_scanning&amp;diff=105250"/>
				<updated>2020-06-15T20:39:20Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: Complete keyboard scanning routine slightly optimized&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Hardware scancode table ==&lt;br /&gt;
{|{{Prettytable|width: 700px; font-size: 2em;}}&lt;br /&gt;
|'''Bit:&amp;lt;br&amp;gt;Line''' || '''7''' || '''6''' || '''5''' || '''4''' || '''3''' || '''2''' || '''1''' || '''0'''&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;40''' || F Dot || ENTER || F3 || F6 || F9 || CURDOWN || CURRIGHT || CURUP&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;41''' || F0 || F2 || F1 || F5 || F8 || F7 || COPY || CURLEFT&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;42''' || CONTROL || \  || SHIFT || F4 || ] || RETURN || [ || CLR&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;43''' || . || / || : || ; || P || @ || - || ^&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;44''' || , || M || K || L || I || O || 9 || 0&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;45''' || SPACE || N || J || H || Y || U || 7 || 8&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;46''' || V || B || F || G (Joy2 fire) || T (Joy2 right) || R (Joy2 left) || 5 (Joy2 down)|| 6 (Joy 2 up)&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;47''' || X || C || D || S || W || E || 3 || 4&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;48''' || Z || CAPSLOCK || A || TAB || Q || ESC || 2 || 1&lt;br /&gt;
|-&lt;br /&gt;
|'''&amp;amp;49''' || DEL || Joy 1 Fire 3 (CPC only) || Joy 1 Fire 2 ||Joy1 Fire 1||Joy1 right||Joy1 left||Joy1 down||Joy1 up&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Computing key code ==&lt;br /&gt;
&lt;br /&gt;
System key codes (codes that are writted on the top of the disc drive on 664/6128 or in the CPC user manual) can be computed with the formula : (Line*8)+bit&lt;br /&gt;
&lt;br /&gt;
Example : for key SHIFT , Line = 2 , bit = 5 so (2*8)+5 = 21&lt;br /&gt;
&lt;br /&gt;
== Keyboard clash ==&lt;br /&gt;
&lt;br /&gt;
This is the name of the phenomenon when a &amp;quot;ghost&amp;quot; or &amp;quot;phantom&amp;quot; key is generated when you press some combinations of keys.&lt;br /&gt;
It is caused by the design of the keyboard hardware. It has been tested and confirmed that keyboard clash doesn't occur on an English CPC664 keyboard.&lt;br /&gt;
&lt;br /&gt;
For example, pressing Q,A,P will also generate :.&lt;br /&gt;
&lt;br /&gt;
The ':' key is the &amp;quot;ghost&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
The problem is much bigger in 2 player games.&lt;br /&gt;
&lt;br /&gt;
It is possible to avoid or minimize the problem by carefully choosing the controls. The problem also occurs when using digital joysticks because these are part of the keyboard matrix.&lt;br /&gt;
&lt;br /&gt;
If you visualize a rectangle in the keyboard matrix above, where 3 of the corners are 3 keys you have pressed. Then the key in the fourth corner will also be pressed this is the &amp;quot;ghost&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
On Plus it is possible to avoid it mostly by having one player on analogue joystick and the other on keyboard/digital joystick.&lt;br /&gt;
&lt;br /&gt;
== One line scanning routine ==&lt;br /&gt;
&lt;br /&gt;
This is a routine which scans one line of the keyboard directly. It is approximately 8% faster than the firmware routine and doesn't enable interrupts.&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A = ''line (&amp;amp;amp;40 - &amp;amp;amp;49)''&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A = ''hardware keyboard value''&lt;br /&gt;
&lt;br /&gt;
'''Destroyed:''' BC&lt;br /&gt;
&amp;lt;pre&amp;gt;LD A,kbdline ; from &amp;amp;40 to &amp;amp;49 with bdir/bc1=01&lt;br /&gt;
LD D,0&lt;br /&gt;
LD BC,#F782 ; PPI port A out /C out &lt;br /&gt;
OUT (C),C &lt;br /&gt;
LD BC,#F40E ; Select Ay reg 14 on ppi port A &lt;br /&gt;
OUT (C),C &lt;br /&gt;
LD BC,#F6C0 ; This value is an AY index (R14) &lt;br /&gt;
OUT (C),C &lt;br /&gt;
OUT (C),D ; Validate!! out (c),0&lt;br /&gt;
LD BC,#F792 ; PPI port A in/C out &lt;br /&gt;
OUT (C),C &lt;br /&gt;
DEC B &lt;br /&gt;
OUT (C),A ; Send KbdLine on reg 14 AY through ppi port A&lt;br /&gt;
LD B,#F4 ; Read ppi port A &lt;br /&gt;
IN A,(C) ; e.g. AY R14 (AY port A) &lt;br /&gt;
LD BC,#F782 ; PPI port A out / C out &lt;br /&gt;
OUT (C),C &lt;br /&gt;
DEC B ; Reset PPI Write &lt;br /&gt;
OUT (C),D ; out (c),0&lt;br /&gt;
&lt;br /&gt;
Register A now holds the value of requested keyboard row&lt;br /&gt;
Now check for the value from the table e.g. with''''bit x,A''''and a condition e.g.''''jp z,xxxx''''or''''call z,xxxx''''&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Please note:&lt;br /&gt;
&lt;br /&gt;
* Bit = 0: Key is pressed&lt;br /&gt;
* Bit = 1: Key is not pressed&lt;br /&gt;
&lt;br /&gt;
== Complete keyboard scanning routine ==&lt;br /&gt;
&lt;br /&gt;
This routine scans the complete keyboard and writes all key status bits in a map.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
keymap  ds 10  ;map with 10*8 = 80 key status bits (bit=0 key is pressed)&lt;br /&gt;
&lt;br /&gt;
keyscan di              ;1 ##%%## C P C   VERSION ##%%##&lt;br /&gt;
        ld hl,keymap    ;3&lt;br /&gt;
        ld bc,#f782     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld bc,#f40e     ;3&lt;br /&gt;
        ld e,b          ;1&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld bc,#f6c0     ;3&lt;br /&gt;
        ld d,b          ;1&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        xor a           ;1&lt;br /&gt;
        out (c),a       ;4&lt;br /&gt;
        ld bc,#f792     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ld a,#40        ;2&lt;br /&gt;
        ld c,#4a        ;2 43&lt;br /&gt;
loop    ld b,d          ;1&lt;br /&gt;
        out (c),a       ;4 select line&lt;br /&gt;
        ld b,e          ;1&lt;br /&gt;
        ini             ;5 read bits and write into KEYMAP&lt;br /&gt;
        inc a           ;1&lt;br /&gt;
        cp c            ;1&lt;br /&gt;
        jr c,loop       ;2/3 9*16+1*15=159&lt;br /&gt;
        ld bc,#f782     ;3&lt;br /&gt;
        out (c),c       ;4&lt;br /&gt;
        ei              ;1 8 =210 microseconds&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Developing programs that use joystick ==&lt;br /&gt;
&lt;br /&gt;
In the CPC world it is more common that a game supports both keyboard and digital joystick for those users who don't own joysticks.&lt;br /&gt;
In addition, it is also nice if the keys could be redefined but that is not necessary.&lt;br /&gt;
&lt;br /&gt;
There are some common keyboard configurations used:&lt;br /&gt;
&lt;br /&gt;
* '''Joystick''' - This configuration is compatible with all Amstrad machines, even the GX4000 and you need to scan only one keyboard line (this means you can't be faster)&lt;br /&gt;
&lt;br /&gt;
* '''Cursor keys &amp;amp; SPACE''' - This configuration is often used and is great for the CPC6128 and Plus and playing using emulators. This is '''not''' good for CPC 464 and 664 (which have uncomfortably arranged cursor keys)&lt;br /&gt;
&lt;br /&gt;
* '''Q,A,O,P,SPACE''' - (Q up, A down, O left, P right, SPACE fire) This is a good solution, and it's a sort of standard (used by many games). It is best for english QWERTY keyboards, on french AZERTY it'd be A-Q-O-P (but because the decoding of the keys is done in software, normally by the OS, the bits in the keyboard matrix are actually the same).&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]][[Category:CPC Internal Components]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=QuickCMD&amp;diff=101449</id>
		<title>QuickCMD</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=QuickCMD&amp;diff=101449"/>
				<updated>2018-04-05T21:20:38Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
[[Image:4487394.png|thumb|QuickCMD v2.0]]&lt;br /&gt;
&lt;br /&gt;
QuickCMD is a new shell-like user interface for disc-based Amstrad CPC computers.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
The initial goal of this software is to provide a faster way to browse disc content and launch programs. Usually, an Amstrad CPC user tends to use BASIC prompt to first display the disc content to retrieve a filename then manually launch a program. While this process is OK and functional, this can quickly become a boring task when there is a need to browse multiple discs.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Additionally to that, this program also features some interesting commands to manage disc content that are usually not accessible from BASIC prompt. This is only possible thanks to the low-level management of a disc content, that directly read and writes sectors instead of using functionalities provided by default with the firmware. Many formats are supported, including DATA, SYSTEM and PARADOS. Due to that, disc operations are faster than the ones accessible from BASIC.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Finally, QuickCMD is really respectful regarding the system. It has a very small memory footprint, and can be easily extended with already-existing RSXs (Resident System eXtension). It also features a char display routine that is faster than the standard one provided by the firmware, so commands generally performs faster than their equivalents under BASIC.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
This program requires;:&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''an Amstrad CPC 6128''';: both classic and Plus models are supported. Amstrad CPC 464s with external disc drive are currently not supported.&lt;br /&gt;
 &lt;br /&gt;
*'''a ROM box''';: such devices are RAMCARD, ROMBOX, etc. Because QuickCMD is provided as a ROM, you need to be able to extend your CPC with custom ROMs. More information about those devices can be found here.&lt;br /&gt;
&lt;br /&gt;
You can install this ROM at any place. Just make sure to not override the installed foreground ROM (BASIC ROM is default, at rom 0) or the ROM responsible of drive management (CPM ROM is default, at rom 7).&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Once installed, QuickCMD will only use &amp;amp;amp;6 bytes in memory for ROM persistent data. This is possible because QuickCMD is treated as a real ROM, meaning the code is executed from ROM, and not copied back to RAM at initialization time.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
When launched, QuickCMD will dynamically allocate &amp;amp;amp;328 bytes of data under HIMEM address, used as temporary buffer managed during run-time. As a note, it's interesting to mention it actually takes less memory to use QuickCMD than using the regular BASIC's CAT command (that internally use &amp;amp;amp;800 bytes for its temporary catalog buffer under HIMEM address).&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== Commands ==&lt;br /&gt;
&lt;br /&gt;
When user enters QuickCMD's user interface, a command-line prompt is visible to the user. People familiar with any DOS-based systems will recognize the workflow. User has to manually type commands in order to send orders to be executed by the computer. Commands are not case-sensitive.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Commands are;:&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''A: or B: ''': By typing A: or B:, the user can select the corresponding drive (drive A or B). All forthcoming disc operations will be using the selected drive.&lt;br /&gt;
 &lt;br /&gt;
*'''ABOUT ''': This gives the credits of the program. It also reports memory usage (address and length) required for QuickCMD's execution.&lt;br /&gt;
 &lt;br /&gt;
*'''CAT ''': This command behaves exactly like the regular CAT command does under BASIC. Its aim is for compatibility purpose, other programs such as BonnyDOS rely on this to display hard-drive content. Hidden files from catalog are not displayed. This command is not recommended to browse a disc, prefer the DIR command instead.&lt;br /&gt;
 &lt;br /&gt;
*'''CATART ''': This command behaves exactly like the regular CAT command does under BASIC, excepted it also reset the screen to default's startup one (blue background with yellow letters, using graphical MODE 1). This allows to display &amp;quot;cat arts&amp;quot;, which represent graphical screens displayed with CAT command. Once displayed, user can press a key to return back to default QuickCMD's screen setup. This command is internally called by DIR command when a &amp;quot;cat art&amp;quot; is automatically detected.&lt;br /&gt;
 &lt;br /&gt;
*'''CRTC ''': This command reports the CRTC type. CRTC is the graphical chip of the Amstrad CPC. The CRTC test is based on Madram's implementation. It may not be the best implementation out there, but does the work as expected. It's useful to know installed CRTC type when dealing with demos that are dedicated to a single CRTC type. &lt;br /&gt;
 &lt;br /&gt;
*'''DEL ''': This command delete a file on disc. Be aware, no confirmation is asked to the user;!&lt;br /&gt;
&lt;br /&gt;
*'''DELROM ''': This command is only compatible with RAMCARD and MEGAFLASH devices. It clears memory at specified ROM number.&lt;br /&gt;
 &lt;br /&gt;
*'''DIR ''': This command gives the list of files on disc. It shows files in the current user only. Available size in Kb is also reported. When this command requires multiple pages to display a long list of files, it will actually ask the user to press a key at each page-scroll. There is no filename sorting, files get displayed in order of apparition when parsing catalog information. The command supports Read-Only and Hidden files. It's interesting to mention that Hidden files are also treated and shown. If catalog appears to be a &amp;quot;cat art&amp;quot;, then this command will be internally redirected to CATART command.&lt;br /&gt;
 &lt;br /&gt;
*'''DIRALL ''': This command performs like the DIR command, excepted it lists files for ALL users (from user 0 to 15). This is interesting to find files that are not under the current user. User of file is displayed as a prefix to the filename.&lt;br /&gt;
 &lt;br /&gt;
*'''DIRDEL ''': This command performs like the DIR command, excepted it lists deleted files. If a file has been recently deleted and that no write access on disc have been done, it's possible to retrieve original file content using the UNDEL command.&lt;br /&gt;
 &lt;br /&gt;
*'''DISCINFO ''': This gives information about disc format. It reports the name of the format, its capacity in Kb, the number of maximum files that can be managed, the single- or double-sided info, as also sectors and tracks identifiers. Many formats are supported, including those managed by PARADOS.&lt;br /&gt;
 &lt;br /&gt;
*'''HIDE ''': This command allows to hide a file from catalog. Of course, it will be still shown under QuickCMD (flagged as a Hidden file). When using CAT command, this file will be not reported (invisible) to the user. Files hidden can be shown back to catalog by using the SHOW command.&lt;br /&gt;
 &lt;br /&gt;
*'''INFO ''': This gives information about specified file. It reports its type (BASIC, PROTECTED BASIC, BINARY and ASCII). If the type allows it, it also reports the Load Address, the length of the file and its Execution Address.&lt;br /&gt;
 &lt;br /&gt;
*'''PUTROM ''': This command is only compatible with RAMCARD devices. First parameter is the ROM's filename, second parameter is the ROM number to write to. Specified file will be put onto the rom box. User will be asked to switch on/off the corresponding write DIP switch. It makes use of default implementation provided by Ram7 (the original author of the RAMCARD). It's advised to use ROMS command before using PUTROM to make sure to not overwrite a wanted and already installed ROM.&lt;br /&gt;
 &lt;br /&gt;
*'''REN ''': This command is used to rename a file. The first parameter is the new filename, the second parameter is the current filename to rename. Be aware;! REN command under BASIC use a reverse convention (old filename before new one). Such a reversion is used for DOS-like compatibility. &lt;br /&gt;
 &lt;br /&gt;
*'''READONLY ''': This command is used to set Read-Only attribute to a specified file. Files set as Read-Only can not be deleted till this attribute got removed.&lt;br /&gt;
 &lt;br /&gt;
*'''READWRITE ''': This command is used to set Read-Write attribute to a specified file (which is the default for a file). Files set as Read-Write can be deleted or overwritten.&lt;br /&gt;
 &lt;br /&gt;
*'''ROMS ''': This lists the installed ROMs on the system. On an unexpanded CPC, ROM 0 (BASIC) and ROM 7 (CPM ROM) are listed by default. This is useful to execute this command before putting a ROM on a rom box, to know which rom number should be used. The command shows, for each installed ROM, its internal name, its version and its type (foreground, background or extension).&lt;br /&gt;
 &lt;br /&gt;
*'''RSX ''': This command allows the execution of a RSX. First parameter is the RSX's name, other parameters are optional parameters to be sent to RSX. Optional parameters are always treated as string types. QuickCMD offers the functionality to execute a RSX as a command, so this command is used to override QuickCMD's internal commands. This is an example to make it clear;: let's say the Arnor's UTOPIA ROM has a RSX called HELP. In QuickCMD, if user types HELP, the internal QuickCMD's HELP command will be executed. User typing RSX HELP will then bypass the QuickCMD's HELP command and execute the Arnor's UTOPIA's HELP RSX.&lt;br /&gt;
 &lt;br /&gt;
*'''RUN ''': This command allows the execution of a file on disc. Supported file types are BASIC, PROTECTED BASIC or BINARY. It internally makes use of the BASIC's RUN command, so it's fully compliant with all existing programs. Like the RSX command, QuickCMD offers the functionality to type a filename as a command, so this command is used to override QuickCMD's internal commands. This is an example to make it clear;: let's say we have a file on disc called HELP.BAS. In QuickCMD, if user types HELP, the internal QuickCMD's HELP command will be executed. User typing RUN HELP will then bypass the QuickCMD's HELP command and execute the file HELP.BAS located on disc.&lt;br /&gt;
 &lt;br /&gt;
*'''SETUSER ''': This command is used to set user for a specified file. First parameter is filename, second parameter is the user.&lt;br /&gt;
 &lt;br /&gt;
*'''SHOW ''': This command is used to show (unhide) a file from catalog. Shown files can be hidden back from catalog by using the HIDE command.&lt;br /&gt;
 &lt;br /&gt;
*'''UNDEL ''': This command is used to undelete a file. This command will fail if a disc write access has been performed since the file has been deleted. Deleted files can be shown through the DIRDEL command.&lt;br /&gt;
 &lt;br /&gt;
*'''USER ''': This command is used to change current user. Default user is USER 0. Note that current user is also the one used in BASIC, so if you leave QuickCMD back to BASIC, then current user will remain active.&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
QuickCMD also offers some additional features that can make user's activity easier.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== SHORTCUTS ===&lt;br /&gt;
&lt;br /&gt;
In order to maximize user workflows, some shortcuts are provided to enhance productivity;:&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''ENTER ''': if you press the ENTER key while the input command line is empty, then the screen will be cleared.&lt;br /&gt;
 &lt;br /&gt;
*'''TAB ''': this is probably one of the most interesting feature from QuickCMD. When you start typing a filename, if you press TAB key, QuickCMD will parse the catalog and try to autocomplete filename.&lt;br /&gt;
 &lt;br /&gt;
*'''TAB ''': if TAB key is pressed while the input command line is empty, then DIR command will be auto-typed (and executed).&lt;br /&gt;
 &lt;br /&gt;
*'''ESC ''': if ESC key is pressed, then the input command line's content will be cleared.&lt;br /&gt;
 &lt;br /&gt;
*'''ESC or CTRL+TAB ''': if ESC key or CTRL+TAB keys are pressed, then QuickCMD will exit back to BASIC.&lt;br /&gt;
&lt;br /&gt;
== EXPECTED WORKFLOWS ==&lt;br /&gt;
&lt;br /&gt;
The above shortcuts actually draws what should be one of the top uses of QuickCMD. It should be specifically interesting for new comers. If you find yourself a common workflow that is not listed here, feel free to report it to the author of this program;!&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''The &amp;quot;fast DIR&amp;quot; ''': when your Amstrad CPC got started, user just has to press CTRL+TAB to enter QuickCMD. Then, TAB key is expected to execute DIR command. Once the user chose a file to execute, the first characters composing the filename can be typed and then the filename can be auto-completed using the TAB key. Finally, press ENTER key to execute file. This workflow is ultra-fast, you will get quickly used to the CTRL+TAB then TAB scheme;! Way faster than typing CAT command under BASIC then using SHIFT + arrow keys to select a filename then pressing COPY key to copy/paste filename then pressing CTRL+left arrow then pressing CTRL+ENTER to RUN&amp;quot; the file.&lt;br /&gt;
 &lt;br /&gt;
*'''BASIC is still your friend ''': QuickCMD is not a replacement for BASIC. BASIC has important features that QuickCMD does not support, and vice versa. It has been made easy to the user to quickly switch from BASIC to QuickCMD (and from QuickCMD to BASIC) by using the CTRL+TAB keys. Since QuickCMD is a ROM, you can deal with large BASIC programs or data stored in BANKs without any kind of alteration.&lt;br /&gt;
 &lt;br /&gt;
*'''Recommended third-party ROMs to be used with QuickCMD ''': QuickCMD is very well integrated with Arnor's ROMs. If you need a sector editor, use UTOPIA's DEDIT command. Use UTOPIA's MEDIT command for a memory editor. Use PROTEXT to edit your source files. Use MAXAM to program your assembly source-codes. By using all these powerful tools conjointly, you will be get an efficient manner to be creative with your CPC. This is a completely safe workflow, there have been many tests during QuickCMD implementation to make sure memory was not overwritten regarding various usage of HIMEM.&lt;br /&gt;
 &lt;br /&gt;
*'''Rediscover your library ! ''': One of the obvious strength of QuickCMD is the ability to show Hidden files on disc, as also quickly get information about a file or disc format. From a developer point of view, it's fun to be curious about how &amp;quot;proper&amp;quot; is a program, cf. is it composed by one or two files or is it composed by multiple small hidden files;? etc. Those things generally does not appear when using regular CAT command.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
===v2.3===&lt;br /&gt;
*Added command history&lt;br /&gt;
*ROMS command : Fixed a crash when listing ROMs with corrupted names&lt;br /&gt;
*Another critical problem (involving stability) has been fixed with direct drive parsing&lt;br /&gt;
*Renamed RSX to |Q (for even faster switching between BASIC and QuickCMD)&lt;br /&gt;
===v2.2===&lt;br /&gt;
*Added support for Bryce's MegaFlash&lt;br /&gt;
*Renamed RO and RW commands to READONLY and READWRITE&lt;br /&gt;
*Removed CRTC command&lt;br /&gt;
*Reset screen to QuickCMD’s default if external RSX changed video mode&lt;br /&gt;
*DELROM now clears a rom with &amp;amp;FF value (was using &amp;amp;00)&lt;br /&gt;
*Fixed: was overwriting first byte after HIMEM&lt;br /&gt;
*Fixed: not assuming anymore than Amsdos area is always at &amp;amp;A700&lt;br /&gt;
===v2.1===&lt;br /&gt;
*Correctly handles missing disc in drive for all commands&lt;br /&gt;
*PUTROM command now checks for BINARY file-type/correct size and displays information about the file to be put on RAMCARD&lt;br /&gt;
*DELROM command added to clear a ROM location&lt;br /&gt;
*DIR (and derivatives) now correctly reports file sizes for double-sided formats (Parados 80, etc) - thank you Richard!&lt;br /&gt;
*RSX command now accepts integer values (decimal and hexadecimal)&lt;br /&gt;
*RSX command now accepts quote &amp;quot; &amp;quot; for string-typed values (this allows to get space characters in strings by example)&lt;br /&gt;
*Internal code refactoring for smaller memory footprint&lt;br /&gt;
===v2.0===&lt;br /&gt;
This version is a complete rewrite of version 1.0 . While the initial version was featuring the interesting concepts featured back in version 2.0, it also pointed out some negative points;:&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''too big for what it does ''': most of the program was written in C language. While being more productive that way, the program actually took too much memory.&lt;br /&gt;
*'''a ROM that isn't a ROM ''': the program was stored in a ROM. When executed, the content of the ROM was actually copied into RAM to make use of dynamic memory (it's impossible to write into a ROM). That was pretty bad, as the program was launched from BANK &amp;amp;amp;C7 as also some parts of memory from fixed &amp;amp;amp;8000 location.&lt;br /&gt;
*'''poor implementation ''': the program performed poorly. Most of disc operations were based on CAS CATALOG (the CAT command), that is slow and requires a 2Kb memory buffer.&lt;br /&gt;
*'''custom charset ''': the program made use of a custom integrated charset. Char output routine was efficient but took lots of memory space.&lt;br /&gt;
*'''and more... ''': many little details that were also polluting the code base.&lt;br /&gt;
&lt;br /&gt;
Instead of maintaining a program with lots of lacks, decision has been took to completely rewrite the program with a different approach. Here are the most interesting points;:&lt;br /&gt;
&lt;br /&gt;
*'''asm including C ''': instead of writing a C program with some assembly code inside, it has been more efficient to write the whole application using assembly code and implementing some high-level parts in C programming language. One of the best example for such a usage is the sector parsing part, that use a C's struct to iterate through the file entries.&lt;br /&gt;
*'''a ROM that is a ROM ''': writing a real ROM forced to use dynamic memory management. While this technic was interesting to implement, the most interesting part to point out is that QuickCMD's memory management got actually optimized to the maximum. The list of dynamic variables has to be kept as small as possible.&lt;br /&gt;
*'''and more... ''': many little details that, when written a second time, get suddenly clearer and much more maintainable.&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
Program written by '''Arnaud Storq''' (www.norecess.net, 2011)&lt;br /&gt;
 With the help of '''Kevin Thacker''' and '''Richard Wilson''',&lt;br /&gt;
 CRTC type detection by '''Madram''',&lt;br /&gt;
 RAMCARD management based on implementation from '''Ram7'''.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Many thanks to every person that reported me issues with version 1... This definitively helped a lot making a better implementation for version 2;!&lt;br /&gt;
&lt;br /&gt;
==Files==&lt;br /&gt;
[[File:Quickcmd-v23.zip|QuickCMD v2.3, local mirror]]&lt;br /&gt;
&lt;br /&gt;
[[File:Quickcmd-v22.zip|QuickCMD v2.2, local mirror]]&lt;br /&gt;
&lt;br /&gt;
[[File:Quickcmd-v21.zip|QuickCMD v2.1, local mirror]]&lt;br /&gt;
&lt;br /&gt;
[[File:Quickcmd-v21.pdf|QuickCMD Instruction Manual, local mirror]]&lt;br /&gt;
&lt;br /&gt;
[[File:Quickcmd-v20.zip|QuickCMD v2.0, local mirror]]&lt;br /&gt;
&lt;br /&gt;
[[File:Quickcmd-v10.zip|QuickCMD v1.0, local mirror]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
[http://norecess.cpcscene.net/quickcmd.html NoRecess' QuickCMD page]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Expansion_ROM]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=File:Quickcmd-v10.zip&amp;diff=101448</id>
		<title>File:Quickcmd-v10.zip</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=File:Quickcmd-v10.zip&amp;diff=101448"/>
				<updated>2018-04-05T21:19:28Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=File:Quickcmd-v22.zip&amp;diff=101447</id>
		<title>File:Quickcmd-v22.zip</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=File:Quickcmd-v22.zip&amp;diff=101447"/>
				<updated>2018-04-05T21:19:09Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=File:Quickcmd-v23.zip&amp;diff=101446</id>
		<title>File:Quickcmd-v23.zip</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=File:Quickcmd-v23.zip&amp;diff=101446"/>
				<updated>2018-04-05T21:17:28Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=QuickCMD&amp;diff=101445</id>
		<title>QuickCMD</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=QuickCMD&amp;diff=101445"/>
				<updated>2018-04-05T20:46:41Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
[[Image:4487394.png|thumb|QuickCMD v2.0]]&lt;br /&gt;
&lt;br /&gt;
QuickCMD is a new shell-like user interface for disc-based Amstrad CPC computers.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
The initial goal of this software is to provide a faster way to browse disc content and launch programs. Usually, an Amstrad CPC user tends to use BASIC prompt to first display the disc content to retrieve a filename then manually launch a program. While this process is OK and functional, this can quickly become a boring task when there is a need to browse multiple discs.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Additionally to that, this program also features some interesting commands to manage disc content that are usually not accessible from BASIC prompt. This is only possible thanks to the low-level management of a disc content, that directly read and writes sectors instead of using functionalities provided by default with the firmware. Many formats are supported, including DATA, SYSTEM and PARADOS. Due to that, disc operations are faster than the ones accessible from BASIC.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Finally, QuickCMD is really respectful regarding the system. It has a very small memory footprint, and can be easily extended with already-existing RSXs (Resident System eXtension). It also features a char display routine that is faster than the standard one provided by the firmware, so commands generally performs faster than their equivalents under BASIC.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
This program requires;:&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''an Amstrad CPC 6128''';: both classic and Plus models are supported. Amstrad CPC 464s with external disc drive are currently not supported.&lt;br /&gt;
 &lt;br /&gt;
*'''a ROM box''';: such devices are RAMCARD, ROMBOX, etc. Because QuickCMD is provided as a ROM, you need to be able to extend your CPC with custom ROMs. More information about those devices can be found here.&lt;br /&gt;
&lt;br /&gt;
You can install this ROM at any place. Just make sure to not override the installed foreground ROM (BASIC ROM is default, at rom 0) or the ROM responsible of drive management (CPM ROM is default, at rom 7).&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Once installed, QuickCMD will only use &amp;amp;amp;6 bytes in memory for ROM persistent data. This is possible because QuickCMD is treated as a real ROM, meaning the code is executed from ROM, and not copied back to RAM at initialization time.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
When launched, QuickCMD will dynamically allocate &amp;amp;amp;328 bytes of data under HIMEM address, used as temporary buffer managed during run-time. As a note, it's interesting to mention it actually takes less memory to use QuickCMD than using the regular BASIC's CAT command (that internally use &amp;amp;amp;800 bytes for its temporary catalog buffer under HIMEM address).&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== Commands ==&lt;br /&gt;
&lt;br /&gt;
When user enters QuickCMD's user interface, a command-line prompt is visible to the user. People familiar with any DOS-based systems will recognize the workflow. User has to manually type commands in order to send orders to be executed by the computer. Commands are not case-sensitive.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Commands are;:&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''A: or B: ''': By typing A: or B:, the user can select the corresponding drive (drive A or B). All forthcoming disc operations will be using the selected drive.&lt;br /&gt;
 &lt;br /&gt;
*'''ABOUT ''': This gives the credits of the program. It also reports memory usage (address and length) required for QuickCMD's execution.&lt;br /&gt;
 &lt;br /&gt;
*'''CAT ''': This command behaves exactly like the regular CAT command does under BASIC. Its aim is for compatibility purpose, other programs such as BonnyDOS rely on this to display hard-drive content. Hidden files from catalog are not displayed. This command is not recommended to browse a disc, prefer the DIR command instead.&lt;br /&gt;
 &lt;br /&gt;
*'''CATART ''': This command behaves exactly like the regular CAT command does under BASIC, excepted it also reset the screen to default's startup one (blue background with yellow letters, using graphical MODE 1). This allows to display &amp;quot;cat arts&amp;quot;, which represent graphical screens displayed with CAT command. Once displayed, user can press a key to return back to default QuickCMD's screen setup. This command is internally called by DIR command when a &amp;quot;cat art&amp;quot; is automatically detected.&lt;br /&gt;
 &lt;br /&gt;
*'''CRTC ''': This command reports the CRTC type. CRTC is the graphical chip of the Amstrad CPC. The CRTC test is based on Madram's implementation. It may not be the best implementation out there, but does the work as expected. It's useful to know installed CRTC type when dealing with demos that are dedicated to a single CRTC type. &lt;br /&gt;
 &lt;br /&gt;
*'''DEL ''': This command delete a file on disc. Be aware, no confirmation is asked to the user;!&lt;br /&gt;
&lt;br /&gt;
*'''DELROM ''': This command is only compatible with RAMCARD and MEGAFLASH devices. It clears memory at specified ROM number.&lt;br /&gt;
 &lt;br /&gt;
*'''DIR ''': This command gives the list of files on disc. It shows files in the current user only. Available size in Kb is also reported. When this command requires multiple pages to display a long list of files, it will actually ask the user to press a key at each page-scroll. There is no filename sorting, files get displayed in order of apparition when parsing catalog information. The command supports Read-Only and Hidden files. It's interesting to mention that Hidden files are also treated and shown. If catalog appears to be a &amp;quot;cat art&amp;quot;, then this command will be internally redirected to CATART command.&lt;br /&gt;
 &lt;br /&gt;
*'''DIRALL ''': This command performs like the DIR command, excepted it lists files for ALL users (from user 0 to 15). This is interesting to find files that are not under the current user. User of file is displayed as a prefix to the filename.&lt;br /&gt;
 &lt;br /&gt;
*'''DIRDEL ''': This command performs like the DIR command, excepted it lists deleted files. If a file has been recently deleted and that no write access on disc have been done, it's possible to retrieve original file content using the UNDEL command.&lt;br /&gt;
 &lt;br /&gt;
*'''DISCINFO ''': This gives information about disc format. It reports the name of the format, its capacity in Kb, the number of maximum files that can be managed, the single- or double-sided info, as also sectors and tracks identifiers. Many formats are supported, including those managed by PARADOS.&lt;br /&gt;
 &lt;br /&gt;
*'''HIDE ''': This command allows to hide a file from catalog. Of course, it will be still shown under QuickCMD (flagged as a Hidden file). When using CAT command, this file will be not reported (invisible) to the user. Files hidden can be shown back to catalog by using the SHOW command.&lt;br /&gt;
 &lt;br /&gt;
*'''INFO ''': This gives information about specified file. It reports its type (BASIC, PROTECTED BASIC, BINARY and ASCII). If the type allows it, it also reports the Load Address, the length of the file and its Execution Address.&lt;br /&gt;
 &lt;br /&gt;
*'''PUTROM ''': This command is only compatible with RAMCARD devices. First parameter is the ROM's filename, second parameter is the ROM number to write to. Specified file will be put onto the rom box. User will be asked to switch on/off the corresponding write DIP switch. It makes use of default implementation provided by Ram7 (the original author of the RAMCARD). It's advised to use ROMS command before using PUTROM to make sure to not overwrite a wanted and already installed ROM.&lt;br /&gt;
 &lt;br /&gt;
*'''REN ''': This command is used to rename a file. The first parameter is the new filename, the second parameter is the current filename to rename. Be aware;! REN command under BASIC use a reverse convention (old filename before new one). Such a reversion is used for DOS-like compatibility. &lt;br /&gt;
 &lt;br /&gt;
*'''READONLY ''': This command is used to set Read-Only attribute to a specified file. Files set as Read-Only can not be deleted till this attribute got removed.&lt;br /&gt;
 &lt;br /&gt;
*'''READWRITE ''': This command is used to set Read-Write attribute to a specified file (which is the default for a file). Files set as Read-Write can be deleted or overwritten.&lt;br /&gt;
 &lt;br /&gt;
*'''ROMS ''': This lists the installed ROMs on the system. On an unexpanded CPC, ROM 0 (BASIC) and ROM 7 (CPM ROM) are listed by default. This is useful to execute this command before putting a ROM on a rom box, to know which rom number should be used. The command shows, for each installed ROM, its internal name, its version and its type (foreground, background or extension).&lt;br /&gt;
 &lt;br /&gt;
*'''RSX ''': This command allows the execution of a RSX. First parameter is the RSX's name, other parameters are optional parameters to be sent to RSX. Optional parameters are always treated as string types. QuickCMD offers the functionality to execute a RSX as a command, so this command is used to override QuickCMD's internal commands. This is an example to make it clear;: let's say the Arnor's UTOPIA ROM has a RSX called HELP. In QuickCMD, if user types HELP, the internal QuickCMD's HELP command will be executed. User typing RSX HELP will then bypass the QuickCMD's HELP command and execute the Arnor's UTOPIA's HELP RSX.&lt;br /&gt;
 &lt;br /&gt;
*'''RUN ''': This command allows the execution of a file on disc. Supported file types are BASIC, PROTECTED BASIC or BINARY. It internally makes use of the BASIC's RUN command, so it's fully compliant with all existing programs. Like the RSX command, QuickCMD offers the functionality to type a filename as a command, so this command is used to override QuickCMD's internal commands. This is an example to make it clear;: let's say we have a file on disc called HELP.BAS. In QuickCMD, if user types HELP, the internal QuickCMD's HELP command will be executed. User typing RUN HELP will then bypass the QuickCMD's HELP command and execute the file HELP.BAS located on disc.&lt;br /&gt;
 &lt;br /&gt;
*'''SETUSER ''': This command is used to set user for a specified file. First parameter is filename, second parameter is the user.&lt;br /&gt;
 &lt;br /&gt;
*'''SHOW ''': This command is used to show (unhide) a file from catalog. Shown files can be hidden back from catalog by using the HIDE command.&lt;br /&gt;
 &lt;br /&gt;
*'''UNDEL ''': This command is used to undelete a file. This command will fail if a disc write access has been performed since the file has been deleted. Deleted files can be shown through the DIRDEL command.&lt;br /&gt;
 &lt;br /&gt;
*'''USER ''': This command is used to change current user. Default user is USER 0. Note that current user is also the one used in BASIC, so if you leave QuickCMD back to BASIC, then current user will remain active.&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
QuickCMD also offers some additional features that can make user's activity easier.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== SHORTCUTS ===&lt;br /&gt;
&lt;br /&gt;
In order to maximize user workflows, some shortcuts are provided to enhance productivity;:&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''ENTER ''': if you press the ENTER key while the input command line is empty, then the screen will be cleared.&lt;br /&gt;
 &lt;br /&gt;
*'''TAB ''': this is probably one of the most interesting feature from QuickCMD. When you start typing a filename, if you press TAB key, QuickCMD will parse the catalog and try to autocomplete filename.&lt;br /&gt;
 &lt;br /&gt;
*'''TAB ''': if TAB key is pressed while the input command line is empty, then DIR command will be auto-typed (and executed).&lt;br /&gt;
 &lt;br /&gt;
*'''ESC ''': if ESC key is pressed, then the input command line's content will be cleared.&lt;br /&gt;
 &lt;br /&gt;
*'''ESC or CTRL+TAB ''': if ESC key or CTRL+TAB keys are pressed, then QuickCMD will exit back to BASIC.&lt;br /&gt;
&lt;br /&gt;
== EXPECTED WORKFLOWS ==&lt;br /&gt;
&lt;br /&gt;
The above shortcuts actually draws what should be one of the top uses of QuickCMD. It should be specifically interesting for new comers. If you find yourself a common workflow that is not listed here, feel free to report it to the author of this program;!&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''The &amp;quot;fast DIR&amp;quot; ''': when your Amstrad CPC got started, user just has to press CTRL+TAB to enter QuickCMD. Then, TAB key is expected to execute DIR command. Once the user chose a file to execute, the first characters composing the filename can be typed and then the filename can be auto-completed using the TAB key. Finally, press ENTER key to execute file. This workflow is ultra-fast, you will get quickly used to the CTRL+TAB then TAB scheme;! Way faster than typing CAT command under BASIC then using SHIFT + arrow keys to select a filename then pressing COPY key to copy/paste filename then pressing CTRL+left arrow then pressing CTRL+ENTER to RUN&amp;quot; the file.&lt;br /&gt;
 &lt;br /&gt;
*'''BASIC is still your friend ''': QuickCMD is not a replacement for BASIC. BASIC has important features that QuickCMD does not support, and vice versa. It has been made easy to the user to quickly switch from BASIC to QuickCMD (and from QuickCMD to BASIC) by using the CTRL+TAB keys. Since QuickCMD is a ROM, you can deal with large BASIC programs or data stored in BANKs without any kind of alteration.&lt;br /&gt;
 &lt;br /&gt;
*'''Recommended third-party ROMs to be used with QuickCMD ''': QuickCMD is very well integrated with Arnor's ROMs. If you need a sector editor, use UTOPIA's DEDIT command. Use UTOPIA's MEDIT command for a memory editor. Use PROTEXT to edit your source files. Use MAXAM to program your assembly source-codes. By using all these powerful tools conjointly, you will be get an efficient manner to be creative with your CPC. This is a completely safe workflow, there have been many tests during QuickCMD implementation to make sure memory was not overwritten regarding various usage of HIMEM.&lt;br /&gt;
 &lt;br /&gt;
*'''Rediscover your library ! ''': One of the obvious strength of QuickCMD is the ability to show Hidden files on disc, as also quickly get information about a file or disc format. From a developer point of view, it's fun to be curious about how &amp;quot;proper&amp;quot; is a program, cf. is it composed by one or two files or is it composed by multiple small hidden files;? etc. Those things generally does not appear when using regular CAT command.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
===v2.3===&lt;br /&gt;
*Added command history&lt;br /&gt;
*ROMS command : Fixed a crash when listing ROMs with corrupted names&lt;br /&gt;
*Another critical problem (involving stability) has been fixed with direct drive parsing&lt;br /&gt;
*Renamed RSX to |Q (for even faster switching between BASIC and QuickCMD)&lt;br /&gt;
===v2.2===&lt;br /&gt;
*Added support for Bryce's MegaFlash&lt;br /&gt;
*Renamed RO and RW commands to READONLY and READWRITE&lt;br /&gt;
*Removed CRTC command&lt;br /&gt;
*Reset screen to QuickCMD’s default if external RSX changed video mode&lt;br /&gt;
*DELROM now clears a rom with &amp;amp;FF value (was using &amp;amp;00)&lt;br /&gt;
*Fixed: was overwriting first byte after HIMEM&lt;br /&gt;
*Fixed: not assuming anymore than Amsdos area is always at &amp;amp;A700&lt;br /&gt;
===v2.1===&lt;br /&gt;
*Correctly handles missing disc in drive for all commands&lt;br /&gt;
*PUTROM command now checks for BINARY file-type/correct size and displays information about the file to be put on RAMCARD&lt;br /&gt;
*DELROM command added to clear a ROM location&lt;br /&gt;
*DIR (and derivatives) now correctly reports file sizes for double-sided formats (Parados 80, etc) - thank you Richard!&lt;br /&gt;
*RSX command now accepts integer values (decimal and hexadecimal)&lt;br /&gt;
*RSX command now accepts quote &amp;quot; &amp;quot; for string-typed values (this allows to get space characters in strings by example)&lt;br /&gt;
*Internal code refactoring for smaller memory footprint&lt;br /&gt;
===v2.0===&lt;br /&gt;
This version is a complete rewrite of version 1.0 . While the initial version was featuring the interesting concepts featured back in version 2.0, it also pointed out some negative points;:&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
*'''too big for what it does ''': most of the program was written in C language. While being more productive that way, the program actually took too much memory.&lt;br /&gt;
*'''a ROM that isn't a ROM ''': the program was stored in a ROM. When executed, the content of the ROM was actually copied into RAM to make use of dynamic memory (it's impossible to write into a ROM). That was pretty bad, as the program was launched from BANK &amp;amp;amp;C7 as also some parts of memory from fixed &amp;amp;amp;8000 location.&lt;br /&gt;
*'''poor implementation ''': the program performed poorly. Most of disc operations were based on CAS CATALOG (the CAT command), that is slow and requires a 2Kb memory buffer.&lt;br /&gt;
*'''custom charset ''': the program made use of a custom integrated charset. Char output routine was efficient but took lots of memory space.&lt;br /&gt;
*'''and more... ''': many little details that were also polluting the code base.&lt;br /&gt;
&lt;br /&gt;
Instead of maintaining a program with lots of lacks, decision has been took to completely rewrite the program with a different approach. Here are the most interesting points;:&lt;br /&gt;
&lt;br /&gt;
*'''asm including C ''': instead of writing a C program with some assembly code inside, it has been more efficient to write the whole application using assembly code and implementing some high-level parts in C programming language. One of the best example for such a usage is the sector parsing part, that use a C's struct to iterate through the file entries.&lt;br /&gt;
*'''a ROM that is a ROM ''': writing a real ROM forced to use dynamic memory management. While this technic was interesting to implement, the most interesting part to point out is that QuickCMD's memory management got actually optimized to the maximum. The list of dynamic variables has to be kept as small as possible.&lt;br /&gt;
*'''and more... ''': many little details that, when written a second time, get suddenly clearer and much more maintainable.&lt;br /&gt;
&lt;br /&gt;
== Credits ==&lt;br /&gt;
&lt;br /&gt;
Program written by '''Arnaud Storq''' (www.norecess.net, 2011)&lt;br /&gt;
 With the help of '''Kevin Thacker''' and '''Richard Wilson''',&lt;br /&gt;
 CRTC type detection by '''Madram''',&lt;br /&gt;
 RAMCARD management based on implementation from '''Ram7'''.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Many thanks to every person that reported me issues with version 1... This definitively helped a lot making a better implementation for version 2;!&lt;br /&gt;
&lt;br /&gt;
==Files==&lt;br /&gt;
&lt;br /&gt;
[[File:Quickcmd-v21.zip|QuickCMD v2.1, local mirror]]&lt;br /&gt;
&lt;br /&gt;
[[File:Quickcmd-v20.zip|QuickCMD v2.0, local mirror]]&lt;br /&gt;
&lt;br /&gt;
[[File:Quickcmd-v21.pdf|QuickCMD Instruction Manual, local mirror]]&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
[http://norecess.cpcscene.net/quickcmd.html NoRecess' QuickCMD page]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Expansion_ROM]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Filling_memory_with_a_byte&amp;diff=101296</id>
		<title>Programming:Filling memory with a byte</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Filling_memory_with_a_byte&amp;diff=101296"/>
				<updated>2018-03-17T23:15:44Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Using the stack */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Using LDIR==&lt;br /&gt;
&lt;br /&gt;
From the '''The Unofficial Amstrad WWW Resource'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
;; This code snippet will show one method to fill a block&lt;br /&gt;
;; of memory with a single data byte using Z80 assembly&lt;br /&gt;
;; language.&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
;; HL = start address of block&lt;br /&gt;
ld hl,&amp;amp;4000&lt;br /&gt;
&lt;br /&gt;
;; DE = HL + 1&lt;br /&gt;
ld e,l&lt;br /&gt;
ld d,h&lt;br /&gt;
inc de&lt;br /&gt;
&lt;br /&gt;
;; initialise first byte of block&lt;br /&gt;
;; with data byte (&amp;amp;00)&lt;br /&gt;
ld (hl),&amp;amp;00&lt;br /&gt;
	&lt;br /&gt;
;; BC = length of block in bytes&lt;br /&gt;
;; HL+BC-1 = end address of block&lt;br /&gt;
&lt;br /&gt;
ld bc,&amp;amp;4000	&lt;br /&gt;
&lt;br /&gt;
;; fill memory&lt;br /&gt;
ldir&lt;br /&gt;
&lt;br /&gt;
;;--------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;; For each iteration of the LDIR command:&lt;br /&gt;
;;&lt;br /&gt;
;; 1. This command will copy the byte from the memory &lt;br /&gt;
;; address pointed to by HL to the memory address pointed to by DE.&lt;br /&gt;
;; i.e. (DE) = (HL).&lt;br /&gt;
;; 2. Then HL and DE will be incremented. BC will be decremented.&lt;br /&gt;
;;&lt;br /&gt;
;;&lt;br /&gt;
;; For the first byte:&lt;br /&gt;
;; &lt;br /&gt;
;; HL = start&lt;br /&gt;
;; DE = start+1&lt;br /&gt;
;; BC = length&lt;br /&gt;
;; (HL)=0&lt;br /&gt;
;; &lt;br /&gt;
;; For the second byte:&lt;br /&gt;
;; &lt;br /&gt;
;; HL = start + 1 (initialised to 0 by the previous iteration)&lt;br /&gt;
;; DE = start + 2&lt;br /&gt;
;; BC = length - 1&lt;br /&gt;
;;&lt;br /&gt;
;; For the third byte:&lt;br /&gt;
;;&lt;br /&gt;
;; HL = start + 2 (initialised to 0 by the previous iteration)&lt;br /&gt;
;; DE = start + 3&lt;br /&gt;
;; BC = length - 2&lt;br /&gt;
;;&lt;br /&gt;
;; etc....&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the stack==&lt;br /&gt;
&lt;br /&gt;
This method write bytes at a considerably faster rate by exploiting the speed of the stack pointer (SP) moving through RAM and its 2-byte steps. It is especially good for very rapidly clearing the screen.--[[User:Db6128|Db6128]] ([[User talk:Db6128|talk]]) 06:29, 13 December 2012 (EET)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
; Save the stack pointer&lt;br /&gt;
ld (SAVE_SP),sp        ; Only remove if you're sure you don't need the stack&lt;br /&gt;
ld sp,FINAL_ADDRESS+1  ; e.g. to fill from &amp;amp;C000 to &amp;amp;FFFF (&amp;amp;4000 bytes), set SP to &amp;amp;FFFF+1 = &amp;amp;0000&lt;br /&gt;
&lt;br /&gt;
; Define the region of RAM to be filled&lt;br /&gt;
ld hl,YOUR_BYTE_1*&amp;amp;100 + YOUR_BYTE_2      ; Use HL or whichever 16-bit register you prefer&lt;br /&gt;
ld de,LENGTH_TO_FILL/2                    ; divided by 2 because DE is 2 bytes wide and PUSH pushes both&lt;br /&gt;
&lt;br /&gt;
; Set up a fast 16-bit loop counter&lt;br /&gt;
ld b,e                 ; This method takes advantage of the fact that DJNZ leaves B as 0, which subsequent DJNZs see as 256&lt;br /&gt;
dec de                 ; B = (length/2) MOD 256, so 0 = a 512-byte block&lt;br /&gt;
inc d                  ; D = the number of 512-byte blocks to write, or just = 1 if the length is &amp;lt;512&lt;br /&gt;
                       ; Of course, if you know the length ahead of run-time, you can set B and D directly in your ASM&lt;br /&gt;
&lt;br /&gt;
; Fill the memory&lt;br /&gt;
        PUSHLOOP:&lt;br /&gt;
push hl                ; Writes HL to (SP-2) and DECs SP by 2.&lt;br /&gt;
                       ; For even more speed, use multiple PUSH HLs in a row (I like 8, = &amp;amp;10 bytes) and adjust counters to match&lt;br /&gt;
djnz PUSHLOOP&lt;br /&gt;
dec d&lt;br /&gt;
jr nz,PUSHLOOP&lt;br /&gt;
&lt;br /&gt;
; Restore the stack pointer&lt;br /&gt;
        SAVE_SP equ $+1&lt;br /&gt;
ld SP,&amp;amp;9999            ; &amp;amp;9999 will be replaced by the actual previous value&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Fast_plot&amp;diff=101295</id>
		<title>Programming:Fast plot</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Fast_plot&amp;diff=101295"/>
				<updated>2018-03-17T18:04:07Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Fast plotting routine for MODE 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fast plotting routine for MODE 0 ==&lt;br /&gt;
&lt;br /&gt;
Converted from the Mode 1 routine by [[User:Executioner|The Executioner]]&lt;br /&gt;
&lt;br /&gt;
'''Input:''' DE = ''X (0..159)'', HL = ''Y (0..199)''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMASK	EQU &amp;amp;B338		;Address for colormask&lt;br /&gt;
				;664/6128: &amp;amp;B6A3&lt;br /&gt;
						&lt;br /&gt;
FPLOT	LD A, L			;A = Lowbyte Y&lt;br /&gt;
	AND %00000111		;isolate Bit 0..2&lt;br /&gt;
	LD H, A			;= y MOD 8 to H&lt;br /&gt;
	XOR L			;A = Bit 3..7 of Y&lt;br /&gt;
	LD L, A			;= (Y\8)*8 to L&lt;br /&gt;
	LD C, A			;store in C&lt;br /&gt;
	LD B, &amp;amp;60		;B = &amp;amp;C0\2 = Highbyte Screenstart\2&lt;br /&gt;
		&lt;br /&gt;
	ADD HL, HL		;HL * 2&lt;br /&gt;
	ADD HL, HL		;HL * 4&lt;br /&gt;
	ADD HL, BC		;+ BC = Startaddress&lt;br /&gt;
	ADD HL, HL		;of the raster line&lt;br /&gt;
		&lt;br /&gt;
	SRL E			;calculate X\2, because 2 pixel per byte, Carry is X MOD 2&lt;br /&gt;
		&lt;br /&gt;
	LD C, %10101010	        ;Bitmask for MODE 0&lt;br /&gt;
	JR NC, NSHIFT		;-&amp;gt; = 0, no shift&lt;br /&gt;
SHIFT 	LD C, %01010101	        ;other bitmask for right pixel&lt;br /&gt;
		&lt;br /&gt;
NSHIFT	ADD HL, DE		;+ HL = Screenaddress&lt;br /&gt;
        LD A, (CMASK)		;get color mask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	AND C			;AND bitmask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	LD (HL), A		;new screenbyte&lt;br /&gt;
	RET			;done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fast plotting routine for MODE 1 ==&lt;br /&gt;
&lt;br /&gt;
This routine is approx. 6 times faster than the OS routine GRA PLOT, because it is dependent to MODE 1 and doesn't perform range checks. It can draw 10500 pixels per second.&lt;br /&gt;
&lt;br /&gt;
'''Input:''' DE = ''X (0..319)'', HL = ''Y (0..199)''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMASK	EQU &amp;amp;B338		;Address for colormask&lt;br /&gt;
				;664/6128: &amp;amp;B6A3&lt;br /&gt;
						&lt;br /&gt;
FPLOT	LD A, L			;A = Lowbyte Y&lt;br /&gt;
	AND %00000111		;isolate Bit 0..2&lt;br /&gt;
	LD H, A			;= y MOD 8 to H&lt;br /&gt;
	XOR L			;A = Bit 3..7 of Y&lt;br /&gt;
	LD L, A			;= (Y\8)*8 to L&lt;br /&gt;
	LD C, A			;store in C&lt;br /&gt;
	LD B, &amp;amp;60		;B = &amp;amp;C0\2 = Highbyte Screenstart\2&lt;br /&gt;
		&lt;br /&gt;
	ADD HL, HL		;HL * 2&lt;br /&gt;
	ADD HL, HL		;HL * 4&lt;br /&gt;
	ADD HL, BC		;+ BC = Startaddress&lt;br /&gt;
	ADD HL, HL		;of the raster line&lt;br /&gt;
		&lt;br /&gt;
	LD A, E			;Lowbyte X to A&lt;br /&gt;
	SRL D			;calculate X\4, because&lt;br /&gt;
	RR E			;4 pixel per byte&lt;br /&gt;
	SRL E&lt;br /&gt;
	ADD HL, DE		;+ HL = Screenaddress&lt;br /&gt;
		&lt;br /&gt;
	LD C, %10001000		;Bitmask for MODE 1&lt;br /&gt;
	AND %00000011		;A = X MOD 4&lt;br /&gt;
	JR Z, NSHIFT		;-&amp;gt; = 0, no shift&lt;br /&gt;
SHIFT 	SRL C			;move bitmask to pixel&lt;br /&gt;
	DEC A			;loop counter&lt;br /&gt;
	JR NZ,SHIFT		;-position&lt;br /&gt;
		&lt;br /&gt;
NSHIFT	LD A, (CMASK)		;get color mask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	AND C			;AND bitmask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	LD (HL), A		;new screenbyte&lt;br /&gt;
	RET			;done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast plotting routine for MODE 2 ==&lt;br /&gt;
&lt;br /&gt;
And the MODE 2 routine. Perhaps this could be improved since there are only two colours, and the pixel shift may need to operate up to 7 times (so perhaps a table would average out better).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMASK	EQU &amp;amp;B338		;Address for colormask&lt;br /&gt;
				;664/6128 - &amp;amp;B6A3&lt;br /&gt;
						&lt;br /&gt;
FPLOT	LD A, L			;A = Lowbyte Y&lt;br /&gt;
	AND %00000111		;isolate Bit 0..2&lt;br /&gt;
	LD H, A			;= y MOD 8 to H&lt;br /&gt;
	XOR L			;A = Bit 3..7 of Y&lt;br /&gt;
	LD L, A			;= (Y\8)*8 to L&lt;br /&gt;
	LD C, A			;store in C&lt;br /&gt;
	LD B, &amp;amp;60		;B = &amp;amp;C0\2 = Highbyte Screenstart\2&lt;br /&gt;
		&lt;br /&gt;
	ADD HL, HL		;HL * 2&lt;br /&gt;
	ADD HL, HL		;HL * 4&lt;br /&gt;
	ADD HL, BC		;+ BC = Startaddress&lt;br /&gt;
	ADD HL, HL		;of the raster line&lt;br /&gt;
	&lt;br /&gt;
	LD A, E			;Lowbyte X to A&lt;br /&gt;
	SRL D			;calculate X\8, because&lt;br /&gt;
	RR E			;8 pixel per byte&lt;br /&gt;
	SRL D&lt;br /&gt;
        RR E&lt;br /&gt;
        SRL E&lt;br /&gt;
	ADD HL,DE		;+ HL = Screenaddress&lt;br /&gt;
&lt;br /&gt;
	LD C,%10000000		;Bitmask for MODE 2&lt;br /&gt;
        AND %00000111		;A = X MOD 8&lt;br /&gt;
        JR Z, NSHIFT		;-&amp;gt; = 0, no shift&lt;br /&gt;
		&lt;br /&gt;
SHIFT 	SRL C	                ;move bitmask to pixel&lt;br /&gt;
	DEC A			;loop counter&lt;br /&gt;
	JR NZ,SHIFT		;-position&lt;br /&gt;
		&lt;br /&gt;
NSHIFT	LD A, (CMASK)		;get color mask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	AND C			;AND bitmask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	LD (HL), A		;new screenbyte&lt;br /&gt;
	RET			;done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Talk:Programming:Fast_plot&amp;diff=101294</id>
		<title>Talk:Programming:Fast plot</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Talk:Programming:Fast_plot&amp;diff=101294"/>
				<updated>2018-03-17T17:59:08Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Programming:Fast_plot&amp;diff=101293</id>
		<title>Programming:Fast plot</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Programming:Fast_plot&amp;diff=101293"/>
				<updated>2018-03-17T17:52:59Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: /* Fast plotting routine for MODE 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Fast plotting routine for MODE 0 ==&lt;br /&gt;
&lt;br /&gt;
Converted from the Mode 1 routine by [[User:Executioner|The Executioner]]&lt;br /&gt;
&lt;br /&gt;
'''Input:''' DE = ''X (0..159)'', HL = ''Y (0..199)''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMASK	EQU &amp;amp;B338		;Address for colormask&lt;br /&gt;
				;664/6128: &amp;amp;B6A3&lt;br /&gt;
						&lt;br /&gt;
FPLOT	LD A, L			;A = Lowbyte Y&lt;br /&gt;
	AND %00000111		;isolate Bit 0..2&lt;br /&gt;
	LD H, A			;= y MOD 8 to H&lt;br /&gt;
	XOR L			;A = Bit 3..7 of Y&lt;br /&gt;
	LD L, A			;= (Y\8)*8 to L&lt;br /&gt;
	LD C, A			;store in C&lt;br /&gt;
	LD B, &amp;amp;60		;B = &amp;amp;C0\2 = Highbyte Screenstart\2&lt;br /&gt;
		&lt;br /&gt;
	ADD HL, HL		;HL * 2&lt;br /&gt;
	ADD HL, HL		;HL * 4&lt;br /&gt;
	ADD HL, BC		;+ BC = Startaddress&lt;br /&gt;
	ADD HL, HL		;of the raster line&lt;br /&gt;
		&lt;br /&gt;
	SRL E			;calculate X\2, because 2 pixel per byte, Carry is X MOD 2&lt;br /&gt;
		&lt;br /&gt;
	LD C, %10101010	        ;Bitmask for MODE 0&lt;br /&gt;
	JR NC, NSHIFT		;-&amp;gt; = 0, no shift&lt;br /&gt;
SHIFT 	LD C, %01010101	        ;other bitmask for right pixel&lt;br /&gt;
		&lt;br /&gt;
NSHIFT	ADD HL, DE		;+ HL = Screenaddress&lt;br /&gt;
        LD A, (CMASK)		;get color mask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	AND C			;AND bitmask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	LD (HL), A		;new screenbyte&lt;br /&gt;
	RET			;done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fast plotting routine for MODE 1 ==&lt;br /&gt;
&lt;br /&gt;
This routine is approx. 6 times faster than the OS routine GRA PLOT, because it is dpendent to MODE 1 and doesn't perform range checks. It can draw 10500 pixels per second.&lt;br /&gt;
&lt;br /&gt;
'''Input:''' DE = ''X (0..319)'', HL = ''Y (0..199)''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMASK	EQU &amp;amp;B338		;Address for colormask&lt;br /&gt;
				;664/6128: &amp;amp;B6A3&lt;br /&gt;
						&lt;br /&gt;
FPLOT	LD A, L			;A = Lowbyte Y&lt;br /&gt;
	AND %00000111		;isolate Bit 0..2&lt;br /&gt;
	LD H, A			;= y MOD 8 to H&lt;br /&gt;
	XOR L			;A = Bit 3..7 of Y&lt;br /&gt;
	LD L, A			;= (Y\8)*8 to L&lt;br /&gt;
	LD C, A			;store in C&lt;br /&gt;
	LD B, &amp;amp;60		;B = &amp;amp;C0\2 = Highbyte Screenstart\2&lt;br /&gt;
		&lt;br /&gt;
	ADD HL, HL		;HL * 2&lt;br /&gt;
	ADD HL, HL		;HL * 4&lt;br /&gt;
	ADD HL, BC		;+ BC = Startaddress&lt;br /&gt;
	ADD HL, HL		;of the raster line&lt;br /&gt;
		&lt;br /&gt;
	LD A, E			;Lowbyte X to A&lt;br /&gt;
	SRL D			;calculate X\4, because&lt;br /&gt;
	RR E			;4 pixel per byte&lt;br /&gt;
	SRL E&lt;br /&gt;
	ADD HL, DE		;+ HL = Screenaddress&lt;br /&gt;
		&lt;br /&gt;
	LD C, %10001000		;Bitmask for MODE 1&lt;br /&gt;
	AND %00000011		;A = X MOD 4&lt;br /&gt;
	JR Z, NSHIFT		;-&amp;gt; = 0, no shift&lt;br /&gt;
SHIFT 	SRL C			;move bitmask to pixel&lt;br /&gt;
	DEC A			;loop counter&lt;br /&gt;
	JR NZ,SHIFT		;-position&lt;br /&gt;
		&lt;br /&gt;
NSHIFT	LD A, (CMASK)		;get color mask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	AND C			;AND bitmask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	LD (HL), A		;new screenbyte&lt;br /&gt;
	RET			;done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast plotting routine for MODE 2 ==&lt;br /&gt;
&lt;br /&gt;
And the MODE 2 routine. Perhaps this could be improved since there are only two colours, and the pixel shift may need to operate up to 7 times (so perhaps a table would average out better).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMASK	EQU &amp;amp;B338		;Address for colormask&lt;br /&gt;
				;664/6128 - &amp;amp;B6A3&lt;br /&gt;
						&lt;br /&gt;
FPLOT	LD A, L			;A = Lowbyte Y&lt;br /&gt;
	AND %00000111		;isolate Bit 0..2&lt;br /&gt;
	LD H, A			;= y MOD 8 to H&lt;br /&gt;
	XOR L			;A = Bit 3..7 of Y&lt;br /&gt;
	LD L, A			;= (Y\8)*8 to L&lt;br /&gt;
	LD C, A			;store in C&lt;br /&gt;
	LD B, &amp;amp;60		;B = &amp;amp;C0\2 = Highbyte Screenstart\2&lt;br /&gt;
		&lt;br /&gt;
	ADD HL, HL		;HL * 2&lt;br /&gt;
	ADD HL, HL		;HL * 4&lt;br /&gt;
	ADD HL, BC		;+ BC = Startaddress&lt;br /&gt;
	ADD HL, HL		;of the raster line&lt;br /&gt;
	&lt;br /&gt;
	LD A, E			;Lowbyte X to A&lt;br /&gt;
	SRL D			;calculate X\8, because&lt;br /&gt;
	RR E			;8 pixel per byte&lt;br /&gt;
	SRL D&lt;br /&gt;
        RR E&lt;br /&gt;
        SRL E&lt;br /&gt;
	ADD HL,DE		;+ HL = Screenaddress&lt;br /&gt;
&lt;br /&gt;
	LD C,%10000000		;Bitmask for MODE 2&lt;br /&gt;
        AND %00000111		;A = X MOD 8&lt;br /&gt;
        JR Z, NSHIFT		;-&amp;gt; = 0, no shift&lt;br /&gt;
		&lt;br /&gt;
SHIFT 	SRL C	                ;move bitmask to pixel&lt;br /&gt;
	DEC A			;loop counter&lt;br /&gt;
	JR NZ,SHIFT		;-position&lt;br /&gt;
		&lt;br /&gt;
NSHIFT	LD A, (CMASK)		;get color mask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	AND C			;AND bitmask&lt;br /&gt;
	XOR (HL)		;XOR screenbyte&lt;br /&gt;
	LD (HL), A		;new screenbyte&lt;br /&gt;
	RET			;done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Talk:Programming:Fast_plot&amp;diff=42778</id>
		<title>Talk:Programming:Fast plot</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Talk:Programming:Fast_plot&amp;diff=42778"/>
				<updated>2010-03-11T15:09:52Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The routines in MODE 0 and MODE 2 will not work properly due to lack of a command:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
''ADD HL, HL                    ;HL * 2''&lt;br /&gt;
&lt;br /&gt;
''ADD HL, HL                    ;HL * 2''&lt;br /&gt;
&lt;br /&gt;
''ADD HL, BC                   ;+ BC = Startaddress''&lt;br /&gt;
&lt;br /&gt;
''ADD HL, HL                    ;of the raster line''&lt;br /&gt;
&lt;br /&gt;
'''LD A, E'''&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Talk:Programming:Fast_plot&amp;diff=42777</id>
		<title>Talk:Programming:Fast plot</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Talk:Programming:Fast_plot&amp;diff=42777"/>
				<updated>2010-03-11T15:00:18Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The routines in MODE 0 and MODE 2 will not work properly due to lack of a command:&lt;br /&gt;
&lt;br /&gt;
ADD HL, HL		;HL * 2&lt;br /&gt;
ADD HL, HL		;HL * 4&lt;br /&gt;
ADD HL, BC		;+ BC = Startaddress&lt;br /&gt;
ADD HL, HL		;of the raster line&lt;br /&gt;
&lt;br /&gt;
'''LD A, E	'''&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	<entry>
		<id>https://oldwiki.cpcwiki.eu/index.php?title=Talk:Programming:Fast_plot&amp;diff=42776</id>
		<title>Talk:Programming:Fast plot</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.cpcwiki.eu/index.php?title=Talk:Programming:Fast_plot&amp;diff=42776"/>
				<updated>2010-03-11T14:49:08Z</updated>
		
		<summary type="html">&lt;p&gt;Urusergi: Created page with 'The routines in MODE 0 and MODE 2 will not work properly due to lack of a command:  ADD HL, HL		;HL * 2 ADD HL, HL		;HL * 4 ADD HL, BC		;+ BC = Startaddress ADD HL, HL		;of the r…'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The routines in MODE 0 and MODE 2 will not work properly due to lack of a command:&lt;br /&gt;
&lt;br /&gt;
ADD HL, HL		;HL * 2&lt;br /&gt;
ADD HL, HL		;HL * 4&lt;br /&gt;
ADD HL, BC		;+ BC = Startaddress&lt;br /&gt;
ADD HL, HL		;of the raster line&lt;br /&gt;
		&lt;br /&gt;
'''LD A, E	'''&lt;/div&gt;</summary>
		<author><name>Urusergi</name></author>	</entry>

	</feed>