            IFND            TOOLS_I


TOOLS_I     SET             1


            include         'vga.i'


;
; Récupère la valeur du PC sur la pile (ex: instruction "RET")
;
POPPC       MACRO
            MOVE.W          D6,D0
            ADDQ.W          #2,D6
            PEEK16          D0,D7
            ENDM


;
; Sauvegarde la valeur du PC sur la pile (ex :avant un "CALL")
;
PUSHPC      MACRO
            SUBQ.W          #1,D6
            MOVE.W          D6,D0
            MOVE.W          D7,D1
            LSR.W           #8,D1
            POKE8           D1
            SUBQ.W          #1,D6
            MOVE.W          D6,D0
            POKE8           D7
            ENDM


;
; Lit 1 octet à l'adresse du PC (pour décodage instructions et autre)
;
GETN        MACRO
            MOVE.W          D7,D0
            PEEK8           \1
            ADDQ.W          #1,D7
            ENDM


;
; Lit 2 octets à l'adresse du PC (ex: "LD HL,nnnn")
;
GETNN       MACRO
            MOVE.W          D7,D0
            PEEK16          D0,\1
            IFNC            '\1','D7'
            ADDQ.W          #2,D7
            ENDC
            ENDM


;
;           A = A + nn (D1=nn)
;
ADD_R8      MACRO
;            MOVE.B          (A4),D2
;            AND.B           #$0F,D2
            ADD.B           D1,(A4)
            MOVE            CCR,D3
            MOVE.B          FLAGS(A4,D3.W),(A3)
;            AND.B           #$0F,D1
;            ADD.B           D1,D2
;            AND.B           #FLAG_H,D2
;            OR.B            D2,(A3)
            ENDM


;
;           A = A - nn (D1=nn)
;
SUB_R8      MACRO
;            MOVE.B          (A4),D2
;            AND.B           #$0F,D2
            SUB.B           D1,(A4)
            MOVE            CCR,D3
            MOVE.B          N_FLAGS(A4,D3.W),(A3)
;            NEG.B           D1
;            AND.B           #$0F,D1
;            ADD.B           D1,D2
;            AND.B           #FLAG_H,D2
;            OR.B            D2,(A3)
            ENDM


;
;           A = A + nn + Flag.C (D1=nn)
;
ADC_R8      MACRO
            MOVE.B          (A4),D0
            MOVE.B          D0,D2
            AND.B           #$0F,D2
            MOVE.B          (A3),D3
            AND.W           #1,D3
            LSR.B           #1,D3
            ADDX.B          D1,D0
            MOVE            CCR,D3
            MOVE.B          FLAGS(A4,D3.W),(A3)
            AND.B           #$0F,D1
            MOVE.B          D0,(A4)
            ADD.B           D1,D2
            AND.B           #FLAG_H,D2
            OR.B            D2,(A3)
            ENDM


;
;           A = A - nn - Flag.C (D1=nn)
;
SBC_R8      MACRO
            MOVE.B          (A4),D0
;            MOVE.B          D0,D2
;            AND.B           #$0F,D2
            MOVE.B          (A3),D3
            AND.W           #1,D3
            LSR.B           #1,D3
            SUBX.B          D1,D0
            MOVE            CCR,D3
            MOVE.B          N_FLAGS(A4,D3.W),(A3)
;            NEG.B           D1
;            AND.B           #$0F,D1
            MOVE.B          D0,(A4)
;            ADD.B           D1,D2
;            AND.B           #FLAG_H,D2
;            OR.B            D2,(A3)
            ENDM


;
;           Compare AF et nn (D1=nn)
;
CP_R8       MACRO
            MOVE.B          (A4),D2
            CMP.B           D1,D2
            MOVE            CCR,D3
            MOVE.B          N_FLAGS(A4,D3.W),(A3)
;            NEG.B           D1
;            AND.B           #$0F,D1
;            AND.B           #$0F,D2
;            ADD.B           D1,D2
;            AND.B           #FLAG_H,D2
;            OR.B            D2,(A3)
            ENDM


;
;           Positionne les flags après une opération logique (AND, OR, XOR)
;
FLAG_LOG    MACRO
            MOVE            CCR,D0
            MOVE.B          L_FLAGS(A4,D0.W),D1
            MOVE.B          (A4),D0
            OR.B            PARITE(A4,D0.W),D1
            MOVE.B          D1,(A3)
            ENDM


;
; Positionnement des flags après une instruction "INC r".
; Les lignes mises en commentaires (;) servent normalement au positionnement
; du flag H (pour l'instruction DAA). Il semble qu'il n'y ai jamais
; d'utilisation de l'instruction DAA après une instruction "INC r", c'est
; pourquois ces lignes sont ignorées, mais conservées si jamais un problème
; apparaissait dans des opérations BCD.
;
FLAG_INC    MACRO
            IFNC            '\1','D2'
            MOVE            CCR,D3
;            MOVE.B          \1,D2
            ENDC
            MOVE.B          INC_FLAGS(A4,D3.W),D0
            MOVE.B          (A3),D3
            AND.B           #FLAG_C,D3
            OR.B            D0,D3
;            AND.B           #$0F,D2
;            BNE.S           .INC\@
;            OR.B            #FLAG_H,D3
.INC\@:     MOVE.B          D3,(A3)
            ENDM


;
; Positionnement des flags après une instruction "DEC r".
; Les lignes mises en commentaires (;) servent normalement au positionnement
; du flag H (pour l'instruction DAA). Il semble qu'il n'y ai jamais
; d'utilisation de l'instruction DAA après une instruction "DEC r", c'est
; pourquois ces lignes sont ignorées, mais conservées si jamais un problème
; apparaissait dans des opérations BCD.
;
FLAG_DEC    MACRO
            IFNC            '\1','D2'
            MOVE            CCR,D3
;            MOVE.B          \1,D2
            ENDC
            MOVE.B          DEC_FLAGS(A4,D3.W),D0
            MOVE.B          (A3),D3
            AND.B           #FLAG_C,D3
            OR.B            D0,D3
;            AND.B           #$0F,D2
;            CMP.B           #$0F,D2
;            BNE.S           .DEC\@
;            OR.B            #FLAG_H,D3
.DEC\@:     MOVE.B          D3,(A3)
            ENDM


;
;   Copie du flag C 68K -> Z80
;
C_CARRY     MACRO
            BCC.S           .P_NOC\@
            OR.B            #FLAG_C,(A3)
.P_NOC\@    
            ENDM


            ENDC
