            SECTION         text,CODE


            include         'regs.i'
            include         'tools.i'
            include         'vgacst.i'


            XREF            _Interruption
            XREF            @BeginIO
            XREF            TabInstr
            XREF            _finProc
            XREF            _VBL
            XREF            tabAdrMemEcrCPC
            XREF            DecodeurAdresse
            XREF            ChangeROM
            XREF            ChangeRAM
            XREF            _EtatLigneClav
            XREF            F63_38

@ExecZ80:   MOVEM.L         D1-D7/A0-A6,-(A7)
            CLR.B           _finProc
            LEA             _EtatLigneClav,A0
;
; Toutes les lignes du clavier à 0xFF
;
            MOVE.L          #-1,(A0)+
            MOVE.L          #-1,(A0)+
            MOVE.L          #-1,(A0)+
            MOVE.L          #-1,(A0)+
            LEA             tabAdrMemEcrCPC,A2
            LEA             DONNEES,A4 ; (A4) = Acc
            LEA             TabInstr,A5
            MOVE.L          A4,A3
            ADDQ.L          #1,A3      ; (A3) = Flags
            LEA             Z80,A6
            CLR.L           (A4)       ; AF,  BC  = 0
            CLR.L           4(A4)      ; DE,  HL  = 0
            CLR.L           8(A4)      ; AF', BC' = 0
            CLR.L           12(A4)     ; DE', HL' = 0
            CLR.L           16(A4)     ; IX,  IY  = 0
            CLR.L           20(A4)     ; IR, IFFn = 0

            MOVE.B          #ROMINF_SEL,DecodeurAdresse
            BSR.W           ChangeROM
            MOVEQ           #0,D0
            BSR.W           ChangeRAM

            MOVEQ           #$E,D4    ; Mombre de décalagés à droite pour
                                      ; récupérer le n° de bank de 16K ROM/RAM
            MOVE.L          #$3FFF,D5 ; Masque pour rester dans une bank de 16K
            MOVEQ           #0,D6     ; SP = 0
            MOVEQ           #0,D7     ; PC = 0

            MOVEQ           #0,D1

;
;   Emuler interruption ?
;
Z80:        TST.B           _IntZ80
            BEQ.S           TraiteInstr
;
;   Fermeture par le CLOSE-GADGET 
;
            TST.B           _finProc
            BNE.S           fini
;
;   Passage en mode DEBUG ?
;
            TST.W           _EtatDebug
            BNE.S           Z80Dbg
;
;   "Emulation" interruption
;
            CLR.B           _IntZ80
            CLR.B           _VBL
            SUBQ.B          #1,CptInt
            BNE.S           TraiteInt
            MOVE.B          #1,_VBL
            MOVE.B          #6,CptInt
;
;       EI ? (Enable Interrupt)
;
TraiteInt:  TST.B           REG_IFF1(A4)
            BNE.W           F63_38

TraiteInstr:
            GETN            D0
            ADDQ.B          #1,REG_R(A4)
            JMP             ([A5,D0.W*4])

fini:       MOVEQ           #0,D0
            MOVEM.L         (A7)+,D1-D7/A0-A6
            CMP.B           #1,_finProc
            BEQ.W           @ExecZ80
            RTS

Z80Dbg:     MOVEM.L         D7/A3,-(A7)
            LEA             Z80Dbg,A6
            LEA             _InfosRegistres,A3
            MOVE.W          (A4),(A3)+          ; AF
            MOVE.W          REG_B(A4),(A3)+     ; BC
            MOVE.W          REG_D(A4),(A3)+     ; DE
            MOVE.W          REG_H(A4),(A3)+     ; HL
            MOVE.W          REG_A_(A4),(A3)+    ; AF'
            MOVE.W          REG_B_(A4),(A3)+    ; BC'
            MOVE.W          REG_D_(A4),(A3)+    ; DE'
            MOVE.W          REG_H_(A4),(A3)+    ; HL'
            MOVE.W          REG_IX(A4),(A3)+    ; IX
            MOVE.W          REG_IY(A4),(A3)+    ; IY
            MOVE.W          REG_I(A4),(A3)+     ; IR
            MOVE.W          D6,(A3)+            ; SP
            MOVE.W          D7,(A3)+            ; PC
            GETN            D0
            MOVE.B          D0,(A3)+
            GETN            D0
            MOVE.B          D0,(A3)+
            GETN            D0
            MOVE.B          D0,(A3)+
            GETN            D0
            MOVE.B          D0,(A3)+
            MOVEM.L         (A7)+,D7/A3

            MOVE.W          #1,_EtatDebug
WaitDbg:    TST.B           _finProc
            BNE.W           fini
            CMP.W           #1,_EtatDebug
            BEQ.S           WaitDbg
            TST.W           _EtatDebug
            BNE.W           TraiteInstr
            LEA             Z80,A6
            JMP             (A6)

;
;   Fonction appelée par l'interruption du Timer.device
;   -> *** A cet instant, A6 pointe sur l'exec.library ***
;
@tsoftcode:
            TST.B           _Interruption+4
            BNE.S           SetInt
            MOVE.B          #2,_Interruption+4
            RTS

SetInt:     MOVE.L          _Interruption,A0
            JSR             -372(A6)             ; GetMsg
            MOVE.L          D0,A1
            MOVE.B          #1,_IntZ80
            MOVE.L          _FreqInt,$24(A1)
            MOVE.L          A6,-(A7)
            MOVE.L          $14(A1),A6
            JSR             -30(A6)
            MOVE.L          (A7)+,A6
            RTS


            SECTION         data,DATA


_InfosRegistres:
            DS.B            32

_FreqInt:   DC.L            4729            ; f = (1/p) = 150 Hz (p en µsec)
_IntZ80:    DC.B            0,0,0,0
CptInt:     DC.B            6,0,0,0
_EtatDebug: DC.W            0
_vers:      DC.B            0,"$VER: AMI-CPC V0.46 - par L.DEPLANQUE",0


            XDEF            @ExecZ80
            XDEF            @tsoftcode
            XDEF            Z80
            XDEF            _InfosRegistres
            XDEF            _FreqInt
            XDEF            _EtatDebug
            XDEF            _vers
            XDEF            _IntZ80

            END
