INCLUDE EQMON Appel des equates TTL LECTURE DU LIGHT-PEN ET DES INTERRUPTIONS SECT LIGHTP EXTERN COMCUR,DELAI * ***** VERSION HARD MO5 * ************************************************************************* * * * LPINT teste le bouton du light-pen et revient avec CY = 1 * * si le bouton est ferme et CY = 0 autrement. * * * * GETLP lit le light-pen. Les coordonnees sont transferees * * par X (colonne entre 0 et 319) et Y (ligne entre 0 et 199) * * La lecture valide est signalee par CY = 0, une lecture * * erronee par CY = 1. * * Les registres utilises sont : TEMP, et DECALG; un buffer * * pointe par LPBUFF est destine a recevoir au maximum 8 * * lectures par trame. * * * ************************************************************************* * ***** LECTURE DE L'INTERRUPTEUR LIGHT-PEN * INTERN LPINT LPINT EQU * LDA ,U L'etat de l'interrugteur LP se lit sur le bit 5 ANDA #%00100000 de PRA : 1=enfonce, 0=relache. PSHS A Sauvegarde etat interrupteur LDX #1250 10 Msec d'anti-rebond = 1250 X 8 Usec. JSR DELAI Boucle d'attente "LEAX -1,X etc..." LDA ,U Relecture de confirmation. ANDA #%00100000 Isole le bit 5 CMPA ,S+ Compare a l'etat precedent, et repositionne S. BNE LPINT Si l'etat a change, on refait une lecture. ADDA #$FF La carry est positionnee si A#0 RTS * ***** LECTURE DU LIGHT-PEN * INTERN GETLP GETLP EQU * ORCC #%01010000 Fermeture FIRQ et IRQ a cause des tempos. LDX FIRQPT U pointe sur PRA pour adressage indexe. PSHS X Sauve le pointeur de fast IRQ courant LDX #INTLP Pointeur routine FIRQ lightpen de saisie de STX FIRQPT mesures sur I.t. FIRQ. LDY #LPBUFF Buffer lightpen (9 mesures maxi.) LDA #%11111111 2 us. Control reg.6821: CRA-1=1, front montant. WTIHGH EQU * LDB LP7 Attente INITRAME haut. Bit7 de $A7E7 a 1 : BPL WTIHGH initrame haut. WTILOW EQU * LDB LP7 Attente INITRAME bas. Bit7 de $A7E7 a 0 : BMI WTILOW initrame bas : on est en bas d'ecran. STA CRA-PRA,U 5 us. Registre de controle 6821 programme. LDX #TOPIMG 3 us.Init. de X pour l'attente du top image JSR DELAI 8 us.Total boucle + instructions = 7192 us. TST ,U 6 us.Reset bits IRQA et IRQB du CRB. LDX #WTSCRN 3 us.Parametre attente balayage ecran visible. LDA #1 2 us.Ouverture It. LGA4. STA LP4 * Total = 894* 8us. + 40 us. traitement. ANDCC #%10111111 3 us. Demasquage FIRQ (niveau soft). * ***** Fin de la premiere boucle = attente top image. * ***** Ouverture des interruptions FIRQ ***** * JSR DELAI 8 us. Saisie de 8 mesures maximum. ORCC #%01000000 3 us. Masque les FIRQ (niveau soft). * ***** Fermeture des interruptions FIRQ ***** * ***** Fin de la deuxieme boucle = attente de 12776 us = 199*64 us. + 40 us. * ANDCC #%11101111 Reouverture des IRQ qui pouvaient affecter les LDA #%11111110 tempos. STA CRA-PRA,U Verrouille les I.t. du 6821 : CRA-0 = 0. CLR LP4 6 us.Autorise It. lightpen sur LGA. * ***** RECTIFICATION DES MESURES HORS FENETRE POUR COHERENCE DES TESTS ***** * CMPY #LPBUFF+6 Moins de deux mesures : insuffisant, on sort. BLS NOVALD ( 3 octets pour une mesure ). PSHS Y Sauvegarde du pointeur de la derniere mesure. LDB #%00010000 B = masque du Bit4 de l'adresse physique. RECTIF EQU * LDX -3,Y L'adresse physique est stockee dans X. LDA #%10000000 A = masque du compteur LT3 latche (Bit7 de $A7F6) BITA ,-Y Si LT3 = 0 , on ne peut etre dans les bords. BEQ NXTMES NXTMES : dans l'ecran, on teste la suivante. LSRA A = %01000000 = masque de INILIGNE. BITA ,Y L13 = 1 et INIL # 0, pas de probleme. BNE NXTMES On testera la mesure si LT3 = 1 eL INIL = 0. LSRA A = %00100000 = masque du Bit5 de la mesure. BITA -1,Y Ici, Bit5=1, si Bit4 l'est aussi on est a gauche. BEQ NXTMES $i Bit5 est a 0, on est a droite. BITB -1,Y Test de Bit4 : Bit4=0 ==> a droite, rien a faire, BEQ NXTMES on passe au test de la mesure suivante. LEAX -64,X On est a gauche : on ote 64 pour la coherence. NXTMES EQU * STX ,--Y Y pointe le 1er octet de la mesure testee. CMPY #LPBUFF A-t-on teste toutes les mesures ? BHI RECTIF PULS Y Restitution du Y=sommet du buffer lu. CLRA LDB DECALG Decalage par defaut ou apres reglage. STD TEMP On met dans TEMP le decalage etendu sur 16 bits LDU #LPBUFF+3 On laisse tomber la premiere mesure. LEAY -3,Y Pointe sur la derniere soisie. (1er octet du CLRB bloc de 3 octets necessaires par mesure). SAISIE EQU * LDX ,U++ X contient l'adresse dans l'ecran du point. LDA ,U+ A (3eme octet) : infos supplementaires (INIL..) LEAX 320,X Descente d'une ligne "points" (320 = 8 * 40), CMPX ,U comparee a la mesure suivante pointee par U. BHI IGNORE Mesure suiv. + a gauche,on ignore la precedente LEAX 8,X Ecart max. de un octet tolere entre 2 mesures. CMPX ,U Bien que la nouvelle mesure soit meilleure,on BCS IGNORE l'ignore car elle est "trop bonne". LEAX -8,X II faut garder la mesure precedente : X est STX ,U remis a la bonne valeur, la mesure plus STA 2,U mauvaise est remplacee par la precedente (+320) INCB 8 = compteur de remplacements. BRA NXSAIS NXSAIS : on recommence pour la mesure suivante. DROITE EQU * DEC 11,S On remonte d'une ligne, on se place dans les LEAX 320,X dernieres colonnes et il faudra soustraire le DECALC EQU * decalage. TFR X,D SUBD TEMP D = colonne - decalage BMI DEBLGN Resultat negatif: on ramene a zero CMPD #320 Au dela de 320, on ramene la colonne a 319. BCS VALIDE Mesure inferieure a 320 : OK. LDD #319 SKIP2 DEBLGN EQU * LDD BLOCZ D = colonne O. VALIDE EQU * STD 8,S FIRQPT est encore sur la pile. CLRA SKIP1 NOVALD EQU * COMA PULS X Restitution du pointeur de FIRQ oue l'on STX FIRQPT avait sauvegarde. RTS IGNORE EQU * TSTB B = 0 ==> aucune mesure n'a ete remplacee. BNE RETABL B # 0 ==> REPLAC suivi de IGNORE : on sort. NXSAIS EQU * PSHS U U : pointeur courant dans le buffer light-pen. CMPY ,S++ Y pointe toujours en fin de buffer. BNE SAISIE Retour dans la boucle de saisie de mesures. TSTB B : compteur de remplacements. BEQ NOVALD B nul : aucun remplacement ==> non valide. RETABL EQU * LDA #3 B # 0 ==> on utilise B Dour retrouver la mesure MUL ayant donne lieu au 1er remplacement. NEGB B = -3 * nombre de remplacements. LEAU B,U U pointe la 1ere mesure "fabriquee" : abscisse la LDD ,U plus a gauche et ordonnee de la precedente +320 CMPD #64000 Est-on en dehors de l'ecran, en bas ? BCC NOVALD Adresse > 64000 ==> adresse non valide. * ***** CALCUL LIGNE ET COLONNE **** * CLR 10,S Partie haute de Y a zero car 199 < 255. CLR 11,S Y (dans la pile) = ligne, initialise a 0. BCLDIV EQU * CMPD #320 On soustrait 320 Y fois. BCS CALCUL Fin de la division si dividende < 320. SUBD #320 INC 11,S Quotient de la division = ligne = 11,S BRA BCLDIV Boucle de division. CALCUL EQU * TFR D,X X contient la colonne. LDB 2,U Octet bas de la mesure + (LT3 + INIL). BITB #%10000000 Test LT3 latche : Bit7 a 0 ==> dans ecran. BEQ DECALC Dans I'ecran : on va soustraire le decalage. CMPX #63 LT3 = 1 et mesure < 63 ==> on est a droite. BCS DROITE CMPX #255 LT3 = 1 et mesure < 255 ==> dans l'ecran. BLS DECALC LT3 = 1 et autre mesure ==> on est a gauche, INC 11,S donc on passe en sequence : BRA DEBLGN On descend donc d'une ligne en colonne 0. * TTL GESTION ET RECONNAISSANCE DES INTERRUPTIONS **************************************************************** * Les interruptions sont aiguillees par un systeme de flags * * et de pointeurs en ram. FIRQ repond en priorite au light- * * pen, par defaut elle se branche en [FIRQPT]. * * Si le bit 2 de STATUS est a 1 la fonction clignotement du * * curseur est active, si le bit 1 de STATUS est a 1 la fonc- * * tion autorepeat du clavier est active : CMPTKB est incre- * * mente et le bit 3 de STATUS est positionne a 1. * **************************************************************** * ***** TRAITEMENT SWI * INTERN SWI1SB Branchement a une routine utilisateur de SWI SWI1SB EQU * JMP [SWI1PT] Par defaut, [SWI1PT] = SWITCH * * ***** TRAITEMENT FIRQ * INTERN FIRQSB FIRQSB EQU * JMP [FIRQPT] Branchement a une routine utilisateur de FIRQ * ***** SAISIE DES MESURES LIGHTPEN * INTLP EQU * CMPY #ENDLPB 5 us. Test de fin de buffer, pour ne pas BHS OUTTST 3 us. deborder du buffer LDD LP4 6 us. Saisie de l'adresse physique dans STD ,Y++ 8 us. l'ecran, rangee dans le buffer lightpen. LDA LP6 5 us. Saisie d'infos supplementaires : etat de STA ,Y+ 6 us. INILIGNE et INITRAME . OUTTST EQU * TST ,U 7 us. Reset des bits IRQA et IRQB du CRB. RTKBINT EQU * RTI 6 us. Total : 46 us. < 64 us. * ***** TRAITEMENT DES IRQ * INTERN IRQSUB IRQSUB EQU * LDB #DIRECT TFR B,DP LDU #PRA LDB STATUS Pour les differents tests a venir. LDA CRB-PRA,U Control register B 6821. BMI KBINT Si bit 7 a 1 IT curseur suivi ou non par JMP [IRQPT] deroutage timer sinon, IRQ utilisateur. KBINT EQU * INC ITCMPT Increment compteur: on inverse l'octet forme LDA ITCMPT toutes les 4 I.T. ANDA #3 On isole les 2 bits de droite pour un modulo 4. BNE EXKBINT BITB #4 Test curseur on/off. (B contient STATUS) BEQ NOCURS Bit2 = 1 ==> curseur on, Bit2=0 ==> curseur off. LDA ,U U pointe sur PRA. PSHS A Sauvegarde memoire caractere ou couleur. CALL FRM1 Mise en memoire caractere. JSR COMCUR Inversion curseur et compteur d'inversions. PULS A STA ,U Restitution memoire caractere ou couleur. NOCURS EQU * TST KEY Test autorepeat clavier. BEQ EXKBINT LDA CMPTKB CMPA LATCLV Des que CMPTKB atteint LATCLV, il reste a cette BEQ REPMAX valeur. INC CMPTKB REPMAX EQU * ANDB #$FD On remet a zero le semaphore d'autorepeat STB STATUS (Bit1 de STATUS) EXKBINT EQU * LDA PRB-PRA,U Reset de IRQB. TST TIMEPT+2 Test du flag de TIMEPT (deroutement si #0) BEQ RTKBINT JMP [TIMEPT] Deroutage interrupt timer. END