CODINGANTOINE ★ ASSEMBLEUR Z80 - Les codes spéciaux ★

Z80: Les Codes Speciaux (2/2)Coding Antoine

You remember MMPF  #5  ?  It  included  a  big  article  about  the  special instructions offered by the Z80. But the part about the codes beginning with #ED must be updated 'cause l've found some errors in my codes-table. So is there the new codes-table:

  0        1       2       3       4       5       6       7
       4  IN B,    OUT     SBC      LD     NEG     RETN   IM 0   LD I,A
           ;(C)    (C),B   HL,BC  (ADR),BC
       5  IN D,    OUT     SBC      LD     *NEG   *RETN   IM 1   LD A,I
           ;(C)    (C),D   HL,DE  (ADR),DE
       6  IN H,    OUT     SBC      LD     *NEG   *RETN  *RESET    RRD
           ;(C)    (C),H   HL,HL  (ADR),HL
       7 *IN F,   *NOP     SBC      LD     *NEG   *RETN   *NOP    *NOP
           ;(C)           ; HL,SP  (ADR),SP
           ;8        9       A       B       C       D       E       F
       4  IN C,    OUT     ADC      LD     *NEG   RETI   *NOP ?  LD R,A
           ;(C)    (C),C   HL,BC  BC,(ADR)
       5  IN E,    OUT     ADC      LD     *NEG   *RETI   IM 2   LD A,R
           ;(C)    (C),E   HL,DE  DE,(ADR)
       6  IN L,    OUT     ADC      LD     *NEG   *RETI  *RESET    RLD
           ;(C)    (C),L   HL,HL  HL,(ADR)
       7  IN A,    OUT     ADC      LD     *NEG   *RETI  *RESET   *NOP
           ;(C)    (C),A   HL,SP  SP,(ADR)

The main modification concerns the IO instructions: you can see  that  there is an instruction named IN F,(C) !! As you can guess, its function is to  import a value from the IO port adressed by BC and put it into the Flags  register.  So you can test some bits without using BIT or AND if this bit is at  the  position of one of the four testable flags (S,Z,V,C). For example, to wait for VSync, you can make:

                               ;   LD B,#F5
                             ;  VBL IN F,(C)
                               ;   JR NC,VBL

But, you will tell me, what use can be those special codes, except of  these garbage-tricks ? Well, it will help you if you wanna build your own  protections or... crack (OH !!!) other ones. A  typical  example  is  the  loader  of  Super Cauldron (Elmsoft's new game). It begins with:

                   ;#2FD1        LD   HL,#3000
                   ;#2FD4        LD   BC,#500
                   ;#2FD7        LD   IX,#1234
                   ;#2FDB        DI
                   ;#2FDC        XOR  A
                   ;#2FDD        LD   R,A
                   ;#2FDF LOOP  *INC  IXL
                   ;#2FE1        LD   A,R
                   ;#2FE3       *XOR  IXH
                   ;#2FE5        XOR  (HL)
                   ;#2FE6       *DEC  IXH
                   ;#2FE8       *NEG
                   ;#2FEA        DEC  BC
                   ;#2FEB       *NEG
                   ;#2FED       *XOR  IXL
                   ;#2FEF        XOR  C
                   ;#2FF0       *INC  IYL
                   ;#2FF2        LD   (HL),A
                   ;#2FF3       *DEC  IYH
                   ;#2FF5        INC  HL
                   ;#2FF6       *INC  IYL
                   ;#2FF8        LD   A,B
                   ;#2FF9       *DEC  IYH
                   ;#2FFB        OR   C
                   ;#2FFC       *LD   A,IYL
                   ;#2FFE        JR   NZ,LOOP
                   ;#3000         ;...

If you don't know about the special codes, you can't decode the loader.  The technique to decode it is to simulate the variations  of  the  R  register  with another register (here E is used). In this case you can forget the two NEGs (who act in opposition of each other) and the IY register manipulations 'cause IY has no function in this decoding (except to increase R of 2). The solution  to  this decoding problem is then:

         ORG  #A000                 ; ::    DEC  BC
         LD   HL,#3000               ; ::    DEFB #DD
         LD   BC,#500               ;  ::    XOR  L
         LD   IX,#1234               ; ::    XOR  C
         DI                        ;::    LD   (HL),A
         LD   E,4                   ;::    INC  HL
LOOP     DEFB #DD                   ;::    LD   A,E
         INC  L                    ;  ::    ADD  A,32
         LD   A,E                   ;::    AND  #7F
         DEFB #DD                   ;::    LD   E,A
         XOR  H                    ;  ::    LD   A,B
         XOR  (HL)                 ;  ::    OR   C
         DEFB #DD                   ;::    JR   NZ,LOOP
         DEC  H                    ;  ::    RET

    And you can now disassemble the following of the loader... Simple, eh  ?  To

finish with the non-official Z80 instructions, I would say that you  can  always

order MMPF #5 to have more precisions... We're going  on  the  assembler  serial

with the second part of the arithmetical operations, which is  (excuse  me,  but

the rest is in French)...

           ; CB 30   CB 31   CB 32   CB 33   CB 34   CB 35    CB 36     CB 37
           ; SLI B   SLI C   SLI D   SLI E   SLI H   SLI L   SLI (HL)   SLI A
             ;DD CB 36 dis      FD CB 36 dis       et n'oubliez pas que 'dis'
             ;SLI (IX+dis)      SLI (IY+dis)       est un nombre signé...

Antoine / POW pour MM&PF

★ ANNÉE: ???

CPCrulez[Content Management System] v8.7-desktop/cache
Page créée en 155 millisecondes et consultée 1557 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.