INCLUDE EQMON Appel des equates SECT CASSET TTL CONTROLEUR DE CASSETTE, NOUVELLE VERSION EXTERN INCRUS,NOINCR * ***** VERSION HARD MO5 ***** * ***************************************************************************** * * Ce module contient les quatre routines correspondant aux diverses * operations a effectuer avec le lecteur de cassette : * * 1) GESTION DU MOTEUR * Le point d'entree commum est K7MOT. Si le Bit0 de A est a 0, * on arrete le moteur : branchement a K7OFF. Sinon, on continue en * sequence (moteur on): * * Mise en route du moteur : correspond a un "OPEN" * de la cassette. Le moteur est mis en route par la mise a 0 du Bit3 * de CRA. Si le Bit1 de A est a 1, cette mise en route est suivie d'une * temporisation de une seconde pour attendre que la vitesse se stabilise. * S'il est a 0, il n'y a pas de temporisation. Un test est fait sur la * presence du lecteur de K7. S'il est absent, le CY est mis à 1; sinon, * il est mis a O. * * * Arret du moteur : correspond a un "CLOSE" de la * cassette. Avant d'arreter le moteur par la mise a 1 du Bit3 de CRA, * on fait une temporisation de l/2 seconde. Aucun test n'est effectue. * * 2) ENTREES/SORTIES CASSETTE * Le point d'entree commum est K7CONT. Si A=0, on se branche * a K7WRIT pour ecriture, sinon on passe en sequence (K7READ). * * * K7READ : lecture d'un "bloc". Ce bloc est constitue : * - d'une serie d'octets de synchro. $01 * - d'un pattern bien particulier : $3C5A, soit en * binaire : %00111100/01011010. * - d'un octet donnant le type de fichier : cet octet * sera renvoye dans l'accumulateur A. * - d'un octet donnant la longueur du bloc (2 + data) * - des octets de "donnees" . * - d'un octet de checksum * * Principe general de lecture : une synchro bit est effectuee par * detection des changements de niveau, puis une synchro octet par * detection de $01. Si la serie de $01 eat bien suivie par $3C5A, * on transfere le bloc dans le buffer cassette pointe par Y et un * checksum (sur les data et le checksum) est calcule et renvoye dans A. * Le type de fichier est renvoye dans B. * * * K7WRIT : ecriture d'un bloc. On envoie une serie de $01, * suivie par le pattern $3C5A, suivi par le type de fichier et la * longueur du bloc. Le checksum calcule sur les data, puis complemente * est ecrit apres les donnees. * * Principe general d'ecriture : * - envoi d'un zero : inversion de niveau, attente de * 833 Usec. et inversion de niveau. * - envoi d'un un : inversion de niveau, attente de * 417 USec., inversion de niveau, attente de 417 USec. * * En lecture comme en ecriture, aucun test n'est effectue sur * la cassette ( lecteur present ou non, motor on ou off ...). C'est * au programme appelant de faire ces tests. * * En resume : * * lecture : entree Y pointe sur le buffer lecture * A # 0 * sortie A contient le checksum (0 si lecture bonne) * B contient le type de fichier * ***************************************************************************** * ***** LECTURE CASSETTE ***** * INTERN K7CONT K7CONT EQU * ORCC #%11010000 Inhibition IT et bit E=1 pour un RTI general. TST 3,S BEQ K7WRIT K7READ EQU * LDA ,U Stockaqe du niveau initial. U Pointe sur PRA. LDB #$FF $FF dans TEMP+1 pour etre sur que le 1er $01 STD TEMP vient de la cassette et non du hasard. SYNBIT EQU * BSR RDBITS Lecture du dernier bit entre. TSTA A vaut 0 si un zero est arrive. BNE SYNBIT On boucle jusqu'a ce qu'on lise un zero. SYNBYT EQU * BSR RDBITS On a eu un zero: on continue a lire en decalant LDA TEMP+1 Test de l'octet obtenu apres un decalage. CMPA #$01 Est-ce un octet de synchro $01 ? BNE SYNBYT Si non: on continue a decaler et a tester. WAIT3C EQU * BSR RDBYTE On va maintenant lire les 8 bits suivants. CMPA #$01 Est-ce toujours un octet de synchro ? BEQ WAIT3C Si oui, on continue a lire les octets. CMPA #$3C Si non, c'est obligatoirement $3C. BNE K7READ Serie de $01 non suivie par $3C ==) erreur. BSR RDBYTE Lecture de l'octet suivant qui doit etre $5A. CMPA #$5A Si ce n'est pas $5a, on retourne a la synchro BNE K7READ bits. BSR RDBYTE Saisie ce l'octet suivant qui donne le type STA 4,S de fichier, range dans B dans la pile. BSR RDBYTE Saisie de la longueur du buffer. STA ,Y+ Cette longueur est rangee en tete du buffer. STA K7LENG et dans K7LENG qui sera decremente. CLR 3,S STBUFF EQU * DEC K7LENG Arrive en fin de buffer ? BEQ OUTRW Si oui, sortie generale en OUTRW. BSR RDBYTE Pas encore arrive au bout: l'octet suivant STA ,Y+ est saisi et delicatement range dans le buffer. ADDA 3,S STA 3,S BRA STBUFF On remet ca. * ***** ECRITURE CASSETTE ***** * K7WRIT EQU * LDD #$0110 3 us. $01 dans K7DATA et $10 dans k7LENG STD K7DATA 5 us. pour envoi de $10 fois $01 ENTETE EQU * LDA K7DATA 4 us. $01 envoye dans TEMP+1 . BSR WRBYTE 7 us. Ecriture sur la bande DEC K7LENG 6 us. Compteur de $01 a envoyer. BNE ENTETE 3 us. LDA #$3C 2 us. 1er pattern particulier. BSR WRBYTE 7 us. LDA #$5A 2 us. 3eme pattern particulier BSR WRBYTE 7 us. LDA 4,S 5 us. Type de fichier dans B dans la pile. BSR WRBYTE 7 us. LDA ,Y 4 us. Longueur des donnees en tete de buffer. STA K7LENG 4 us. stockee dans le compteur K7LENG. WRDATA EQU * LDA ,Y+ 6 us. Longueur envoyee a la suite de l'entete. BSR WRBYTE 7 us. Ecriture sur la bande DEC K7LENG 6 us. Compteur de donnees. BNE WRDATA 3 us. Ecriture donnee suivante. OUTRW EQU * RTS * ***** SAISIE D'UN BIT ***** * RDBITS EQU * LDA ,U 4 us. Lecture de PRA pour detection d'un front. EORA TEMP 4 us. A = 1XXXXXXX ; I=0 si meme niveau, 1 sinon BPL RDBITS 3 us. Boucle d'attente d'un front LDX #WTHEOR 5 us. Attente de 2/3 de la periode theorique. BSR DELAI 7 us. DELAI : boucle d'attente. LDA ,U 4 us. Saisie PRA : Bit7 = read cassette. EORA TEMP 4 us. Si changement de niveau, B=$80, 0 sinon. BPL RDONE 3 us. b7=0 ==> niveau change de nouveau ==> 1. COM TEMP 6 us. On inverse le niveau --> Bit7 de TEMP. CLRA 2 us. Clear de la carry pour decal. dans TEMP+1. SKIP1 3 us. (code du BRN). RDONE EQU * COMA 2 us. ou 0 us. si inclus dans le skip. SEC. ROL TEMP+1 6 us. Entree de la carry (0 ou 1) dans TEMP+1. RTS 5 us. * ***** SAISIE D'UN OCTET ***** * RDBYTE EQU * LDB #8 2 us. Compteur de bits RDECAL EQU * BSR RDBITS 7 us. Saisie bit et decalage dans TEMP+1. DECB 2 us. BNE RDECAL 3 us. LDA TEMP+1 2 us. TEMP+1 contient l'octet lu. RTS 5 us. * ***** MOTOR ON ***** * INTERN K7MOT K7MOT EQU * LDB CRA-PRA,U U pointe sur PRA, donc B = CRA. LSRA Si Bit0=0 en entree, motor off. Motor on sinon. BCC K7OFF TST ,U BMI K7HERE Si Bit7 est a 0, LEP non present. COMA CY a 1 si le LEP est absent. RTS K7HERE EQU * ANDB #%11110111 Bit3 de CRA a 0 ==> motor on STB CRA-PRA,U LSRA Si Bit1=0, pas de temporisation. BCC OUTMOT BSR WAITK7 2 * 1/2 seconde soit une seconde. WAITK7 EQU * LDX #MOTEMP (LDX # : 3 us.), negligeable. INTERN DELAI Tempo d'une seconde. DELAI EQU * LEAX -1,X 5 us. BNE DELAI 3 us. CLRA 2 us. CLC OUTMOT EQU * RTS 5 us. * ***** MOTOR OFF : PRECEDE D'UNE DEMI-SECONDE DE TEMPORISATION ***** * K7OFF EQU * ORB #%00001000 Bit3 de CRA a 1 ==> motor off. BSR WAITK7 Tempo d'une 1/2 seconde. STB CRA-PRA,U RTS * ***** ECRITURE D'UN OCTET ***** * WRBYTE EQU * STA TEMP+1 4 us. dans TEMP+A pour la routine WRBITS. LDB #8 2 us. Compteur de bits. WRBITS EQU * BSR INVNIV 7 us. 1ere inversion de niveau. ) partie LDX #TIMCOM 5 us. Attente de 417 us. ) commune au BSR DELAI 7 us. Boucle d'attente ) 0 et au 1. LDX #TIMDIF 5 us. TIMDIF = valeur 2eme 1/2 periode du 0. LSL TEMP+1 6 us. Le bit a ecrire va dans la carry. BCC WRZERO 3 us. Carry clear ==> envoi d'un zero. BSR INVNIV 7 us. 3eme inversion de niveau apres 1/2 periode. LEAX -3,X 5 us. Pour un 1, X = TIMDIF - 3 . WRZERO EQU * BSR DELAI 7 us. Attente 2eme 1/2 periode. DECB 2 us. BNE WRBITS 3 us. Envoi bit suivant. RTS 5 us. * ***** INVERSION DE NIVEAU ***** * INVNIV EQU * LDA #$40 2 us. Masque pour inversion du bit 6. EORA ,U 4 us. Inversion du bit 6 = bit d'ecriture K7. STA ,U 4 us. Envoi de Bit6 (write cassette) sur PRA. RTS 5 us. END