HPHP48-E,*Ô**************************************************************************** JYLOG'S HPROM FILES DESASSEMBLAGE DE LA ROM partie 1: rom des interruptions et routines primaires **************************************************************************** par Laurent JOUANNEAU alias J Y L O G mis à jour le 16 septembre 1993 commentaires non encore complets pour plus de precision, lisez le fichier JYLOG.TXT et les fichiers HPROM FILES parmi les nombreuses routines decrites dans ce fichier, il y a celles du gestionnaire d'interruptions... LES INTERRUPTIONS (ou interrupt ou ints pour ecrire plus court) ================= Qu'est ce que c'est ? eh bin, le microprocesseur, à intervalle de temps (ir)regulier, pendant l'execution des programmes, assembleur ou non (de toute façon, les fonctions rpl et external sont des prog en asm), il interrompt ceux-ci (d'où le nom d'interruptions) en executant le prog asm situe en 0000F. ces interruptions peuvent etre provoque par l'horloge, les sortie IR ou serie, par l'appuie d'une touche etc ... qu'est ce que ca fait ? les interruptions permettent de gerer les appuis touches, de verifier l'integrite du contenu de la memoire (si il y a corruption, il y a alors saut aux routines provoquant les arrets systemes ou pire les memorys clear ), ou encore à l'affichage de l'horloge: l'horloge interne provoque des interruptions qui peuvent etre utiliser pour afficher l'heure en haut de l'ecran par exemple. elles servent aussi à gerer les alarmes: à chaque interruptions, le gestionnaire teste si c'est pas l'heure d'une alarme etc.. Enfin bref ca sert a pas mal de chose... C'est ce que nous allons decouvrir tout le long du dessassemblage de la rom qui contient ces prog de gestion du systeme. Et quoi de plus ? on peut interdire les interruptions masquables (les interruptions provoque par l'appui d'une touche par exemple) grace à l'instruction INTOFF. on peut les reautorise par INTON. mais cela ne permet pas d'interdire TOUTES les interruptions. Aussi pour toutes les interdires, les programmeurs de hp ont commencer leur gestionnaire d'interruptions par un test d'un drapeau ST: le numero 16. vous le mettez à zero et le gestionnaire ne continue pas et s'arrete. les interruptions ne sont plus gerer. cela permet aussi un gain en vitesse car le fait de tester qu'est ce qui a provoquer les interrupts, et ensuite executer les routines adequate, ca ralenti vos prog asm. Et enfin ? il reste plus qu'a explore le gestionnaire d'interrupts. et c'est tout ? non, encore une petite chose: vous allez peut etre trouve inutile certaine manipulation des registres, avec echange de quartet etc.. au debut du gestionnaire d'interruptions. Cela est au contraire tres utile, voir indispensable. En effet, les ints, peuvent survenir à n'importe quel moment, donc forcement au cours de l'execution d'un programme, puis il y a retour ensuite au programme. il faut donc absolument preserver les valeurs des registres. sinon, au retour au prog, il risque d'y avoir de gros gros probleme: imaginez que le prog est en train d'ecrire en ram avec D0 et qu'une ints survient, D0 se trouve changer de valeur car le gestionnaire l'utilise, il y a ensuite retour au prog, et si D0 ne retrouve pas son ancienne valeur, eh bin le prog ecrit ailleurs et ca risque de planter la machine. D'où quelques petites manip de quartets comme CPEX 1 suivit de CPEX 5 en 00057, qui permet de sauver la valeur du registre P. Mais toutes ces petites manip cesseront et il y aura sauvegarde de tout les registres en 7045C, une fois que certain test auront été effectuer. et recuperation des valeurs à la fin des progs du gestionnaire d'ints. ------------------------------ attention: le listing qui suit est sous copyright Hewlett Packard !! (sauf les commentaires bien sur..) %%%%%%% debut de la rom 00000 P= 4 00002 GOTO 001BC 00006 CLRST est-ce vraiment du code ici ou plutot de l'external ???? 00008 A=C A 0000A CDEX A 0000C R0=A %%%%%%% c'est ici que demarre le gestionnaire d'interrupts: à chaque interrupts, saut en 0000F 0000F ST=1 15 mis à 1 du drapeau 15 (indique que ints n'a pu etre 00012 GOC 00029 traite au cas où ints interdites) et saut en 00029 si carry 00015 ?ST=1 16 verifi que ints <> interdites (retour alors au 00018 GOYES 0001C prog interrompu) sinon ->0001C 0001A RTNCC 0001C RSTK=C on sauve C.A 0001E C=ID 00021 ?C#0 B 00024 GOYES 00038 00026 GONC 0003E 00029 ?ST=0 16 si le ST 16 à 0, retour au prog interrompu 0002C RTNYES (=ints interdites) 0002E RSTK=C on sauve C.A 00030 C=ID 00033 ?C=0 B 00036 GOYES 0003E *ici routine pour au cas où ID est different de 0 00038 P= 9 0003A GOTO 001BC *ici routine pour au cas où ID est egale à 0 0003E CD1EX *on sauve premier quartet de D1 en 0011E 00041 D1= 0011E 00048 DAT1=C 1 0004C D1= 0011F *on lit l'adresse de base de ram interne 00053 C=DAT1 1 00057 CPEX 1 *on place la valeur de q1 dans q5. par la meme occasion, 0005B CPEX 5 q1 possede l'ancienne valeur de P et P possede l'ancienne valeur de q5 0005F D1=C 00062 D1= 045C *D1 va en 7045C (si l'adresse de base de ram interne est 70000) 00068 CPEX 5 *on rechange les quartets 1 et 5 de C. P retrouve aussi son ancienne valeur 0006C CPEX 1 00070 DAT1=C W *sauvegarde de C (meme si chp A est dans rstk et que le champ A actuelle n'est pas la valeur originelle) 00074 C=0 A 00076 C=P 4 0007A P= 3 0007C GOC 00082 0007F C=C+1 P 00082 P= 2 00084 C=-C-1 P 00087 SETHEX 00089 P= 1 0008B ?SB=0 0008E GOYES 00093 00090 C=C+1 P *sauvegarde de tout les registres 00093 D1=D1+ 16 00096 DAT1=C A 00099 D1=D1+ 5 0009C C=RSTK 0009E DAT1=C A 000A1 D1=D1+ 5 000A4 DAT1=A W 000A8 D1=D1+ 16 000AB C=ST 000AD DAT1=C A 000B0 D1=D1+ 3 000B3 C=B W 000B6 DAT1=C W 000BA D1=D1+ 16 000BD C=D W 000C0 DAT1=C W 000C4 D1=D1+ 16 000C7 C=R0 000CA DAT1=C W 000CE D1=D1+ 16 000D1 C=RSTK 000D3 DAT1=C A 000D6 D1=D1+ 5 000D9 CD0EX 000DC DAT1=C A 000DF GOTO 00140 *****ici entre 00100 et 00140, il y a la ram systeme. (pour la composition de cette ram, voir VOYAGE AU CENTRE DE LA HP48 ) 00140 ST=1 14 *ici debute la veritable gestion des ints 00143 D0= 0012F *va au setup de l'horloge 2 0014A A=DAT0 1 0014E ?ABIT=1 1 *horloge 2 active ? 00153 GOYES 0015B oui: on continue sinon -> 01315 00155 GOLONG 01315 0015B D0= 0010E *va à la config de detection des cartes 00162 A=DAT0 1 00166 LC C 00169 DAT0=C 1 0016D ?MP=0 *si MP=0 (Module Pulled mais c'est tout ce que je sais) 00170 GOYES 0017C on continue 00172 GOSUB 002DA sinon 00176 P= 12 00178 GOTO 001BC 0017C D0= 09 *va au quartet de declenchement du test des piles 00180 LC 4 00183 DAT0=C 1 00187 D0= 08 0018B C=DAT0 1 0018F ?CBIT=0 1 si les piles sont ok on continue en 001A3 sinon 00194 GOYES 001A3 on eteint la machine puis, apres rallumage on va en 01FC6 00196 ST=1 1 00199 GOSUB 002FF 0019D P= 2 0019F GOTO 001BC 001A3 D1= 0000 on fait pointe D1 au debut de la ram 001A9 A=DAT1 A et on verifie le CMOS word 001AC P= 1 pour ainsi tester si la ram n'est pas corrompue 001AE LC A5C3F 001B5 ?A=C A 001B8 GOYES 001C3 si ok on continue en 001C3 001BA P= 8 001BC GOVLNG 01FC6 001C3 GOSUB 003C6 001C7 D0= 0011C on va au quartet d'emission IR 001CE C=DAT0 1 001D2 ?CBIT=0 3 ints non autorise buffer vide ? 001D7 GOYES 001E2 oui-> on continue 001D9 CBIT=0 3 sinon on ne les autorise pas 001DE DAT0=C 1 001E2 D0= 1A on va au quartet de reception IR 001E6 C=DAT0 1 001EA ?CBIT=0 2 ints IR non autorise ? 001EF GOYES 001FA oui on continue 001F1 CBIT=0 2 sinon on ne les autorise pas 001F6 DAT0=C 1 001FA D1= 00DB D1 pointe aux sauvegardes de la config des cartes 00200 C=DAT1 1 00204 D0= 0010F on lit la veritable config des cartes 0020B A=DAT0 1 0020F ?A=C P si les 2 config sont differentes -> ca a change 00212 GOYES 00218 00214 GOTO 00176 on effectue donc un arret systeme ? 00218 GOSBVL 0131D 0021F GOSUB 005EC mise à 0 ou pas du setup de horl1 suivant lig de comm ou etat du clavier 00223 GOSUB 00672 00227 GOSUBL 00C74 test si ON enfonce 0022D GONC 00236 va en 236 si ON pas enfonce 00230 GOLONG 00E38 sinon va en 00E38 00236 GOSUB 00768 lit les touches clavier en tenant compte si clavier inhibe ou pas 0023A GOSUB 008D8 faitpointe D& en ram interne 0023E D1= 0489 rechargement des valeurs initiales des registres 00244 C=DAT1 W 00248 B=C W 0024B D1=D1+ 16 0024E C=DAT1 W 00252 D=C W 00255 D1=D1+ 16 00258 C=DAT1 W 0025C R0=C 0025F D1=D1+ 16 00262 C=DAT1 A 00265 RSTK=C 00267 D1=D1+ 5 0026A C=DAT1 A 0026D D0=C 00270 D1= 04C3 00276 C=DAT1 X 0027A OUT=C 0027D GOSUBL 01160 00283 D1= 0486 00289 C=DAT1 A 0028C ST=C 0028E D1=D1- 16 00291 A=DAT1 W 00295 D1=D1- 5 00298 C=DAT1 A 0029B RSTK=C 0029D D1=D1- 5 002A0 C=DAT1 A 002A3 SB=0 002A6 CSR A 002A8 P= 1 002AA C=C+1 P 002AD GOC 002B2 002B0 SETDEC 002B2 P= 2 002B4 C=C-1 P 002B7 P=C 3 002BB D1= 045C 002C1 C=DAT1 W 002C5 D1= 0011E 002CC C=DAT1 1 002D0 D1=C 002D3 C=RSTK 002D5 ST=0 15 002D8 RTI fin du gestionnaire d'interruptions retour au programme interrompu **********SP au cas où MP<>0 002DA P= 1 002DC D0= 0010E 002E3 MP=0 002E6 C=0 A 002E8 C=C+1 XS 002EB C=C-1 A 002ED GONC 002EB 002F0 LC C 002F3 DAT0=C 1 002F7 ?MP=0 002FA RTNYES 002FC GONC 002E3 % SP pour eteindre la machine: le OFF % registres modifiés: C champ A, A quartet 0, D champ B, D0, D1, P 002FF D0= 00110 00306 C=0 A 00308 DAT0=C 1 on met à 0 le quartet de controle du RS232C: interdit les ints generées par la rs232C 0030C D0= 2E 00310 C=DAT0 B 00313 RSTK=C sauve dans rstk le setup de l'horloge 1 00315 P= 1 00317 C=0 A on agit maintenant sur le setup des 2 horloges: 00319 ?ST=0 1 si le st1 est à 1, alors on laisse l'horloge 2 active 0031C GOYES 00322 (en ecrivant 10h) sinon on eteint les deux horloges 0031E LC 10 00322 DAT0=C B 00325 GOSUBL 00DF8 on inhibe le clavier pour les tests utilisant SHUTDN 0032B INTOFF 0032F D0= 1C on met à 0 le quartet de controle d'emission IR 00333 C=0 A 00335 DAT0=C 1 00339 D0= 0E laisse allume le bit 3 du quartet de configuration 0033D LC 8 de la detection des cartes 00340 DAT0=C 1 00344 C=0 A met à 0 le quartet du test de batteries 00346 D0= 09 0034A DAT0=C 1 0034E GOSBVL 01BD3 execution de la routine d'extinction de l'ecran et des indicateurs 00355 SHUTDN on met la machine en veille. ici le OFF est fini d'etre effectue la machine se reveillera au prochain appui sur ON et le code qui suit sera executer 00358 D0= 09 on ecrit 4 au quartet du test des batteries 0035C LC 4 0035F DAT0=C 1 00363 D0= 2E on sauve une nouvelle fois le setup de l'horloge1 et 2 00367 C=DAT0 B 0036A RSTK=C 0036C LC 10 on allume l'horloge 2 00370 DAT0=C B 00373 D0= 38 on lit la valeur de l'horloge 2 00377 A=DAT0 1 0037B LC A 0037E A=A-C P 00381 C=DAT0 1 00385 ?A#C P et on attend 10 tops d'horloge 00388 GOYES 00381 0038A C=RSTK on remet alors le setup de l'horloge 1 et 2 sauvé dernierement 0038C D0= 2E 00390 DAT0=C B 00393 GOSBVL 01BA5 on rallume l'ecran et les indicateurs 0039A GOSBVL 019DA ? 003A1 D0= 08 on lit l'etat des piles 003A5 C=DAT0 1 003A9 ?CBIT=1 1 si elles sont tres faibles, on reeteint la machine!! 003AE GOYES 00344 ainsi, si des fois vous tenter de rallumer vot'machine et qu'elle s'eteint tout de suite apres, eh bin, faut changer vos piles ! 003B0 D0= 0E on retablit le quartet de config de detection des cartes 003B4 LC C 003B7 DAT0=C 1 003BB C=RSTK on remet le setup initial de l'horloge 1 003BD D0= 2E 003C1 DAT0=C B 003C4 RTNCC et on retourne. la routine du OFF EST TER-MI-NE ! ouf... %SP qui effectue divers test sur la prise serie 003C6 P= 1 003C8 D0= 00110 003CF A=DAT0 1 003D3 ?ABIT=0 4 retour si prise serie non active 003D8 RTNYES 003DA ABIT=0 3 n'autorise plus la generation d'ints lors de l'emission d'un chr par la prise serie 003DF DAT0=A 1 003E3 ABIT=0 4 003E8 ?A=0 P retour si ints interdites en reception d'un chr 003EB RTNYES 003ED D0= 11 003F1 A=DAT0 XS 003F5 ABIT=0 12 003FA ?A=0 XS retour si on ne recoit rien 003FD RTNYES 003FF INTOFF 00403 D0= 0C 00407 C=DAT0 1 0040B D1= 04D5 on sauve en (7)04D5 l'etat des indicateurs transmit, busy etc.. 00411 DAT1=C 1 00415 CBIT=1 2 0041A DAT0=C 1 0041E GOSUBL 0283D ? 00424 GOC 004A3 00427 D0= 0D 0042B A=0 A 0042D A=DAT0 1 lit la vitesse de transmission 00431 ABIT=0 4 00436 C=A A 00438 A=A+A A 0043A A=A+C A on la multiplie par 3 0043C LC 0048B 00443 C=C+A A puis on l'aditionne à 0048B 00445 D0=C et l'on obtient une adresse où on fait pointe D0 00448 A=DAT0 X on y lit 3 quartets 0044C D0= 00138 00453 C=DAT0 X on lit 3 quartets de la valeur de l'horloge 2 00457 C=C-A X que l'on soustrait à A 0045A D0= 38 0045E A=DAT0 X on relit 3 quartets de l'horloge 00462 ?A=C X on test si c'est egale 00465 GOYES 00473 00467 GOSUBL 0283D 0046D GOC 004A3 00470 GONC 0045A 00473 D1= 04D5 on remet les indicateurs transmit etc ..comme il faut 00479 C=DAT1 1 0047D D0= 0C 00481 DAT0=C 1 00485 INTON 00489 RTNSC et on retourne avec carry=1 ici des datas? 004A6 GOTO 0055F %big routine pour gerer le buffer pour rs232C (ecrit le chr en reception dans le buffer) 004AA D0= 14 004AE A=DAT0 B lit dans le buffer de reception rs232c 004B1 B=A A B=chr du buffer de reception 004B3 D1= 03FC 004B9 C=DAT1 7 lit les caracteristique de l'etat du buffer de stockage de la rs232c 004BD ?ABIT=0 11 004C2 GOYES 004D4 004C4 D0= 13 004C8 DAT0=A 1 annulation des erreurs de receptions en ecrivant une valeur quelconques en 00113 004CC CBIT=1 9 on arme le bit 9 de C 004D1 GONC 00539 004D4 P= 6 on double la valezr du 6eme quartet de C. servira a localiser l'endroit 004D6 A=C P de stockage du chr recu sur la rs232c 004D9 A=A+A P 004DC P= 1 004DE GONC 00539 004E1 D=C W 004E4 LA 13 004EB GOSUBL 02856 004F1 C=D W 004F4 ?A=B B 004F7 GOYES 0051D 004F9 LA 11 00500 GOSUBL 02856 00506 C=D W 00509 ?A#B B 0050C GOYES 00539 0050E P= 6 00510 A=C P 00513 LC B 00516 C=C&A P 0051A GONC 00529 0051D P= 6 0051F A=C P 00522 LC 4 00525 C=C!A P 00529 D1= 0401 0052F DAT1=C P 00533 P= 1 00535 GOTO 0041E 00539 ?C#0 XS C different de 0 (buffer plein) 0053C GOYES 0054C au va alors en 54C 0053E C=C+1 B sinon on incremente le nombre de caracteres contenu dans le buffer 00541 GONC 0054C 00544 C=C-1 B mais si il y a un depassement (buffer plein:impossible de rajouter 00547 CBIT=1 12 un chr ) alors on allume le bit 12 de C 0054C D1= 03FC 00552 DAT1=C 7 on ecrit le nouvel etat du buffer rs232 00556 ?C#0 XS si C different de 0 (buffer plein) 00559 GOYES 0057E alors on va en 57E 0055B A=C A sinon 0055D ASR A on calcul l'endroit ou on stocke le chr 0055F ASR A dans le buffer 00561 ASR A 00563 A=A+C B 00566 A=A-1 B 00569 A=A+A A 0056B D1= 01FC 00571 CD1EX 00574 C=C+A A on fait pointe D1 ou il faut stocker le chr 00576 CD1EX 00579 A=B A 0057B DAT1=A B et on y stocke le chr 0057E D1= 03FC 00584 A=DAT1 X on lit la taille du buffer et la quartet indiquant si buffer plein 00588 LC DF taille du buffer est superieur ou egal à 223 caracteres? 0058C ?C<=A B 0058F GOYES 00596 oui:on continue en 596 00591 ?A=0 XS si buffer non plein: on va en 5E6 00594 GOYES 005E6 %cas ou le buffer est plein ou presque plein (223 chr) 00596 D1= 0401 on va en 70401 0059C A=DAT1 1 on y lit un quartet 005A0 LC 3 005A3 A=A&C P on ne garde que les 2 premiers bits de ce quartet 005A7 LC 2 005AA ?A#C P ce quartet est different de 2 ? alors on va en 5E6 005AD GOYES 005E6 005AF D0= 12 sinon on lit les info sur l'emission de la rs232c 005B3 A=DAT0 1 005B7 ?ABIT=1 1 un chr est present dans le buffer d'emission ? 005BC GOYES 005D6 oui --> 5D6 005BE LA 13 005C5 GOSBVL 3114C 005CC GOSUBL 0287F 005D2 GOTO 0041E 005D6 D1=D1+ 1 on va en 70402 et on allume le bit 4 du quartet qui s'y trouve 005D9 A=DAT1 1 005DD ABIT=1 4 005E2 DAT1=A 1 005E6 GOTO 0041E on va en 0041E 005EA RTNSXM %sp: autorise ou pas le reveil ou la generation d'une interrupt lors du passage %à 0 de l'horloge 1 selon l'etat du clavier, d'indic de la ligne de commande %avec incrementation d'un compteur % mais pourquoi faire ???? zat is ze qouaichtyonne.... 005EC P= 1 005EE SETHEX 005F0 D0= 0012E %on test si horloge 1 necessite un traitement 005F7 A=DAT0 1 005FB ?ABIT=1 4 00600 GOYES 00604 00602 RTNCC %non: retour avec carry=0 00604 GOSUB 008DF %D1=sur la ram interne 00608 D1= 074E 0060E C=DAT1 1 %decremente le quartet en (7)074E 00612 C=C-1 P %si depassement, on ne le memorise pas 00615 GOC 0061C 00618 DAT1=C 1 0061C LA 0683 00625 LC 287 0062A A=C B 0062D D1=A %D1 pointe sur le quartet d'indic de la ligne de commande ? 00630 A=DAT1 XS 00634 A=A&C XS 00638 ?A#0 XS 0063B GOYES 00655 0063D D1= 04DD %test l'etat des touches 00643 C=0 W 00646 C=DAT1 13 0064A ?C#0 W 0064D GOYES 00655 %si aucune touche appuyée: 0064F DAT0=C 1 % mise à 0 du quartet setup de l'horloge 1 (passage à 0 ne provoque rien) 00653 RTNSC %et retour avec la carry=1 00655 D0= 0012E 0065C P= 1 0065E LC 6 %on autorise le reveil et interrupt lors du passage à 0 de l'horloge 00661 DAT0=C 1 00665 D0= 37 %on met à 0 l'horloge 1 00669 LC 0 0066C DAT0=C 1 00670 RTNSC %retour avec carry=1 %%% mouuhaii... ca me laisse perplexe cette routine 00672 GOSUB 00735 lit la config des cartes 00676 CSR A on met la config au quartet 1 00678 CSR A 0067A C=C+C A 0067C C=C+C A 0067E CBIT=1 2 00683 GOSUB 006ED verifie pile 00687 B=A B A contient les piles 0068A BSR A 0068C GOSUB 008D8 D1 va sur la ram interne 00690 D1= 06C2 00696 C=DAT1 1 on lit le quartet en 706C2 0069A C=C&B P 0069E A=A!C P 006A2 D1= 06B5 on lit en B5 et B4 et on fait un or.. 006A8 A=DAT1 XS 006AC D1= 06B4 006B2 C=DAT1 XS 006B6 A=A!C XS 006BA ?A=0 XS ..si c'est <>0 on incremente et on le memorise... 006BD GOYES 006C1 006BF A=A+1 A 006C1 D1= 06C2 ..en C2 006C7 DAT1=A 1 006CB D1= 06C3 006D1 C=DAT1 B 006D4 CBIT=0 4 006D9 ?A=0 P 006DC GOYES 006E3 006DE CBIT=1 4 006E3 DAT1=C B 006E6 GOVLNG 01E79 %SP verifie le niveau des piles 006ED B=C A sauve C dans B. à chaque bit de C correspond un element de la machine a tester (alim general, carte etc..) 006EF D0= 00109 006F6 LC C 006F9 DAT0=C 1 on declenche le test des piles 006FD D0= 08 00701 LC 50F 00706 A=C A A=sur quartet 1: chaque bit correspond à l'etat reels des piles de chaque elements 00708 C=DAT0 1 on lit l'etat des piles 0070C C=C&B P on ne retient pas que les bits des elements à tester.. 00710 A=A&C P on ne retient que les bits des elements dont le bit etait allume (donc pile=faible) au dernier test 00714 CSL B on decale quartet1 vers quartet 2 00717 A=A!C B pour le copier dans quartet2 dans A 0071B C=C-1 XS 0071E GONC 00708 le test est effectue 6 fois 00721 D0= 09 on desactive le test des piles 00725 LC 4 00728 DAT0=C 1 0072C ?ABIT=1 2 00731 RTNYES 00733 RTN retour avec la carry=1 si alim interne=faible dans A: quartet1 et surtout 2: si different de 0: pile faible %SP lit la config des cartes de facon 'extra correct', clean quoi... 00735 P= 1 00737 SETHEX 00739 D0= 0010E %on va au quartet de config de detection de cartes 00740 LC C %où on ecrit la valeur C 00743 DAT0=C 1 00747 D0= 38 %on va à l'horloge 2 0074B A=DAT0 1 0074F LC 5 00752 A=A-C P 00755 C=DAT0 1 00759 ?A#C P %on fait une pause de 5 tops d'horloge 0075C GOYES 00755 0075E D0= 0F %puis on lit la config des cartes 00762 C=DAT0 XS %que l'on met dans C.XS 00766 RTNCC %retour 00768 GOSUB 008D8 %D1 va en ram interne 0076C D1= 04DC 00772 C=DAT1 S %lit le quartet 'disable keyboard' 00776 ?C=0 S 00779 GOYES 0077F 0077B P= 1 0077D RTNCC %retour si clavier inhibe 0077F GOSUB 008E6 00783 B=A W 00786 ?A#0 W 00789 GOYES 007A6 0078B D1= 04DD %on lit le KEY STATE 00791 C=0 W 00794 C=DAT1 13 00798 ?C#0 W %des touches sont appuyés 0079B GOYES 007A6 %->on continue 0079D RSI %sinon retour 007A2 P= 1 007A4 RTNCC 007A6 GOSUB 009A5 007AA ?ABIT=0 1 007AF GOYES 007B5 007B1 GOTO 008C4 007B5 GOSUB 008D8 007B9 LC 3 007BC ?B=0 W 007BF GOYES 007DC 007C1 ?B#0 P 007C4 GOYES 007CC 007C6 BSR W 007C9 GONC 007BC 007CC B=B+B P 007CF GONC 007CC 007D2 C=C-1 P 007D5 GONC 007C1 007D8 GOTO 008C9 007DC GOSUB 009E1 007E0 D=C S 007E3 D1= 04DD 007E9 C=0 W 007EC C=DAT1 13 007F0 DAT1=A 13 007F4 ?A#0 W 007F7 GOYES 007FD 007F9 GOTO 0079D 007FD ?A#C W 00800 GOYES 00806 00802 GOTO 008C9 00806 P= 13 00808 C=-C-1 WP 0080B A=A&C WP 0080F ?A#0 W 00812 GOYES 00818 00814 GOTO 008C9 00818 GOSUB 009E1 0081C B=C S 0081F LC 7DF7FF 00827 P= 6 00829 A=A&C WP 0082D P= 1 0082F ASRB 00832 ?A#0 W 00835 GOYES 0084B 00837 C=B S 0083A GOSUB 00A09 0083E GONC 00845 00841 GOTO 008C0 00845 B=C W 00848 GONC 00892 0084B C=D S 0084E GOSUB 00A09 00852 D=C A 00854 GOC 008C0 00857 D0= 00A83 0085E B=0 W 00861 GONC 00867 00864 ASR W 00867 D0=D0+ 8 0086A ?A=0 P 0086D GOYES 00864 0086F SB=0 00872 ASRB 00875 ?SB=0 00878 GOYES 0088A 0087A BSL W 0087D BSL W 00880 C=DAT0 B 00883 C=C!D B 00887 B=C B 0088A D0=D0+ 2 0088D ?A#0 W 00890 GOYES 0086A 00892 C=B A 00894 GOSUB 00D9F 00898 GOC 008A9 0089B BSR W 0089E BSR W 008A1 ?B#0 W 008A4 GOYES 00892 008A6 GONC 008C9 008A9 GOSBVL 0D809 008B0 ?ST=1 5 008B3 GOYES 008C0 008B5 LC FB 008B9 GOSBVL 01AD7 008C0 GOSUB 00D3B 008C4 RSI 008C9 GOSUB 00655 008CD GOSUB 00A37 008D1 RTNC 008D4 GOTO 00768 008D8 GOVLNG 0C183 008DF GOVLNG 0C1A1 %SP test de touche mais vu comment il fait je n'ai pas encore % compris pourquoi il fait comme ca, le but final quoi.. 008E6 P= 1 008E8 LC 001 008ED ACEX W 008F0 C=A X 008F3 OUT=C %on teste les touches de masque 001 008F6 C=IN 008F9 CSRC %on effectue une rotation des quartets: le 1 devient le 16 008FC SB=0 %SB: Sticky Bit 008FF CSRB %on divise par 2 00902 ?SB=0 00905 GOYES 0091C 00907 CPEX 16 %on allume le 4eme bit du quartet 16 de C 0090B C=P 1 %mais pourquoi ne pas utiliser l'instruction CSLC 0090F CBIT=1 4 %puis changer le bit, puis faire ensuite un CSRC ? 00914 P=C 1 %peut etre tout simplement que la technique utilise 00918 CPEX 16 %ici est plus rapide ... 0091C ?ABIT=1 4 %on teste toutes les touches de masque 001 à 008 00921 GOYES 0093F 00923 A=A+A X 00926 C=A X 00929 OUT=C 0092C C=IN 0092F CSRC %en sauvegardant à chaque fois le masque de sortie 00932 CSRC % sur un quartet et demi dans C 00935 C=C+C W 00938 C=C+C W 0093B GOTO 0091C 0093F ?ABIT=1 9 %on continue de tester les touches de masque 008 à 0100 00944 GOYES 0097C 00946 A=A+A X 00949 C=A X 0094C OUT=C 0094F C=0 X 00952 C=IN 00955 CSRC %on ne sauvegarde le masque de sortie que sur 3 bit 00958 SB=0 0095B CSRB 0095E ?SB=0 00961 GOYES 0093F 00963 CPEX 16 00967 C=P 1 0096B CBIT=1 4 00970 P=C 1 00974 CPEX 16 00978 GONC 0093F 0097B 0 0097C LC 1FF on teste finalement l'ensemble du clavier 00981 OUT=C 00984 C=IN 00987 CSR W 0098A CSR W 0098D CSR W 00990 CSRB 00993 CSRB 00996 CSRB 00999 ACEX W 0099C ?ABIT=1 1 009A1 RTNYES 009A3 RTNCC 009A5 C=RSTK 009A7 D=C A on sauve l'adresse de retour 009A9 D0= 00139 009B0 C=DAT0 S lit un quartet de l'horloge 2 009B4 P= 15 009B6 LC 5 009B9 A=DAT0 S 009BD ?A=C S attente de 009C0 GOYES 009B9 009C2 C=A S 009C5 GOSUB 008E6 009C9 ABEX W 009CC ?A#B W 009CF GOYES 009B0 009D1 P= 15 009D3 C=C-1 P 009D6 GONC 009B9 009D9 P= 1 009DB C=D A 009DD PC=C 009E1 C=A W 009E4 CSR W 009E7 CSL X 009EA P= 4 009EC C=C+C P 009EF C=C+C P 009F2 P= 14 009F4 C=C+C S 009F7 C=C+C XS 009FA GONC 00A00 009FD C=C+1 S 00A00 CSR A 00A02 P=P+1 00A04 GONC 009F4 00A07 RTNCC %SP on lit les datas en 00A2F suivant la valeur du quartet 16 de C 00A09 D0= 00A2F 00A10 P=C 16 00A14 C=0 W 00A17 C=DAT0 1 00A1B D0=D0+ 1 00A1E P=P-1 00A20 GONC 00A17 00A23 P= 1 00A25 C=C+1 P 00A28 C=C-1 P 00A2B CSL A 00A2D RTN 00A2F %datas $084FCFFF ? les datas finissent probablement en A37 %SP il lit et fait des test sur les valeurs des horloges mais je n'ai pas encore compris l'interet de tout ceci ... 00A37 D0= 0012E %on va à l'horloge 1 00A3E A=DAT0 1 00A42 P= 1 00A44 LC 6 00A47 A=A&C P 00A4B ?A=C P % on teste si le passage à 0 de l'horloge provoquera 00A4E GOYES 00A52 % une interrupt et un reveil de la machine 00A50 RTNCC %si ce n'est pas le cas: retour 00A52 D0= 37 %on lit ensuite la valeur de l'horloge 1 00A56 C=0 A 00A58 C=DAT0 1 00A5C ?CBIT=1 4 %il y a retour si le bit 4 est allume 00A61 RTNYES %pour continuer la valeur doit etre comprise entre 0 et 7 00A63 ?C=0 A %il y a retour si l'horloge n'est pas à 0 00A66 GOYES 00A6A %bizarre bizarre.. pourquoi ne pas tester tout de suite 00A68 RTNCC %si C=0, au lieu de tester d'abord si c'est inferieur à 8 00A6A LC 1FF 00A6F A=C A 00A71 D0= 38 00A75 C=DAT0 X 00A79 A=A&C X 00A7D LC 137 00A82 ?C>=A X 00A85 RTNYES 00A87 RTNCC %ici, voici des datas sur les codes de touches. % en premier, vous avez les codes de touches utilisés pour la memorisation %dans le buffer clavier. vous pouvez remarquer que ces codes ne sont pas memorises %dans le meme ordre que les touches. Ils sont en fait rangés par ordre %croissant des masques d'entrée des touches, et pour chaque masque d'entrée, %par ordre croissant des masques de sortie. %on a ainsi le code de la touche ON, puis + SPC . 0 % puis ' - 3 2 1 A shiftbleu etc ... #A89 D2 13 03 F2 E2 D0 C2 B2 A2 92 10 0C 72 62 52 42 70 04 22 12 02 F1 31 08 D1 C1 B1 A1 91 81 71 61 51 41 21 11 01 F0 E0 C0 B0 A0 90 80 60 50 40 30 20 %vous trouvez ensuite tout les masques de toutes les touches (masque d'entrée %suivit du masque de sortie), en commencant par ceux de la touche A #AEB 200010 001010 001800 001400 001200 001100 400010 080010 080800 080400 080200 080100 100010 040010 040800 040400 040200 040100 800010 020010 020800 020400 020200 020100 010010 010800 010400 010200 010100 800020 800800 800400 800200 800100 400020 400800 400400 400200 400100 200020 200800 200400 200200 200100 000000 100800 100400 100200 100100 %on trouve encore ici les codes des touches pour le buffer clavier, en commencant par la touche A. #C11 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 01 11 21 31 41 51 61 71 81 91 A1 B1 C1 D1 08 F1 02 12 22 04 42 52 62 72 0C 92 A2 B2 C2 D2 E2 F2 03 13 %ici des 0 en trop (?) 00 0 %SP qui test si ON est enfoncé 00C74 C=IN 00C77 ?CBIT=1 16 %ON est enfonce->retour avec carry=1 00C7C RTNYES 00C7E RTN %SP 00C80 GOSUB 009A5 00C84 ?ABIT=1 1 00C89 RTNYES 00C8B RTN %SP permet de tester une touche par son code buffer %argument: A=numero de code de la touche à tester (code buffer) %comme les codes buffer des touches ne sont pas tous numeriquement %dans l'ordre des touches elles meme, donc dans l'ordre des masques, %alors ils faut faire quelques tests au prealable, pour charger alors %le 'vrai' numero qui permettra d'acceder de facon mathematique %aux masques de la touche correspondante 00C8D P= 1 00C8F LC 80 %on teste si le code = celui de alpha 00C93 ?A#C B 00C96 GOYES 00C9F 00C98 LC 1E %oui -> A=1E 00C9C A=C B 00C9F LC 40 00CA3 ?A#C B %on teste si le code = celui de shift orange 00CA6 GOYES 00CAF 00CA8 LC 23 %oui -> A=23 00CAC A=C B 00CAF LC 2D 00CB3 ?A=C B %on teste si le code = celui de ON 00CB6 GOYES 00D12 %oui -> on quitte: la touche ON n'est pas testée 00CB8 ?A=0 B 00CBB GOYES 00D12 00CBD LC 31 00CC1 ?C on quitte. 00CC6 C=0 A %sinon on peut teste la touche maintenant 00CC8 C=A B %on multiplie A par 6 00CCB C=C+C A 00CCD A=C A 00CCF C=C+C A 00CD1 A=A+C A 00CD3 LC 00AE5 %que l'on ajoute à AE5 00CDA A=A+C A %et l'on obtient l'adresse des masques de la touche 00CDC D1=A %dont le code était dans A 00CDF C=DAT1 X %on lit les masques 00CE3 D1=D1+ 3 % C=masque d'entrée et A=masque de sortie 00CE6 A=DAT1 X 00CEA P= 5 %on lit l'adresse de base de la ram interne 00CEC D1= 0011F 00CF3 C=DAT1 P 00CF7 D1=C 00CFA P= 1 00CFC GOSUB 00E21 %on memorise le masque d'entrée et on teste la touche 00D00 A=A&C X %on effectue un and pour ne prendre que le masque de sortie de la touche concernée (pour au cas ou plusieurs touches sont appuyés en meme temp) 00D04 LC 1FF %on retest sur l'ensemble du clavier 00D09 GOSUB 00E21 00D0D ?A#0 X %si la touche etait appuyé, retour avec la carry mise à 1 00D10 RTNYES 00D12 RTNCC %ainsi au retour, on trouve: A=resultat du masque de sortie de la touche testé, C=resultat du masque de sortie du clavier et si la touche testée est appuyée -> carry allumée %SP:les trois routines suivantes permet de tester les touches % alpha ,shift bleue ou shift orange % si la touche est appuyé: retour avec carry=1 %test shift orange 00D14 LC 004 00D19 GOTO 00D2B %test shift bleu 00D1D LC 002 00D22 GOTO 00D2B %test alpha 00D26 LC 008 00D2B OUT=C 00D2E GOSUB 01160 00D32 ?CBIT=1 6 00D37 RTNYES 00D39 RTN %efface la zone KEY STATE 00D3B D1= 0011B 00D42 C=DAT1 A 00D45 D1=C 00D48 D1= 04DD 00D4E C=0 W 00D51 DAT1=C 13 00D55 RTN %SP vide le buffer clavier 00D57 D1= 0011B 00D5E C=DAT1 A 00D61 D1=C 00D64 D1= 04EA 00D6A C=0 A 00D6C DAT1=C A 00D6F RTNCC 00D71 point d'entrée: vide le buffer clavier 00D76 CD1EX 00D79 RSTK=C %on sauve la valeur de D1 00D7B GOSUB 00D57 %on vide le buffer 00D7F C=RSTK %on restaure la valeur de D1 00D81 D1=C 00D84 A=DAT0 A %on retourne au rpl 00D87 D0=D0+ 5 00D8A PC=(A) remarque: on ne fait pas appel aux routines 0679B et 067D2 car la routine en 00D57 n'utilise que D1 et C. on n'economise donc du temps en ne sauvegardant que la valeur de D1 (C n'ayant pas de valeur importante pour le rpl), au lieu de tout sauvegarder comme le font les routines 0679B et 067D2 %SP met à 0 le compteur d'appui sur ON 00D8E GOSUB 008D8 00D92 D1= 0679 00D98 C=0 A 00D9A DAT1=C A 00D9D RTN %SP on ajoute une touche dans le buffer clavier %argument: C=code de la touche %si impossible de memorise (buffer plein) alors carry=1 ou 0 sinon 00D9F A=C A %on sauve C 00DA1 D1= 0011B %comme toujours, on lit l'adresse de base de la ram interne 00DA8 C=DAT1 A 00DAB D1=C 00DAE C=A B %on recharge C 00DB1 CSL A 00DB3 D1= 04EA %on lit le numero de la 'case' de la premiere touche du buffer clavier 00DB9 A=DAT1 1 00DBD D1=D1+ 1 00DC0 C=DAT1 1 %on lit le n° de la premier 'case' libre 00DC4 P= 1 00DC6 A=A-C P % on calcul la difference en enlevant aussi 1 00DC9 A=A-1 P 00DCC ?A=0 P %si c'est 0 ( buffer plein) 00DCF RTNYES %retour avec carry=1 00DD1 C=C+1 P %on incremente le numero de la premiere case libre 00DD4 DAT1=C 1 %on memorise ce numero en (7)04EB 00DD8 P=C 1 %et aussi dans P 00DDC P=P-1 00DDE CSR A 00DE0 A=C B 00DE3 CD1EX %pour calcul l'adresse de la case libre 00DE6 C+P+1 00DE9 C+P+1 00DEC C=C-1 A 00DEE CD1EX %et on y fait pointe D1 00DF1 P= 1 00DF3 DAT1=A B %on peut alors memoriser le code de la touche 00DF6 RTNCC %retour avec carry=0 % sp inhibe le clavier pour les tests utilisant le SHUTDN 00DF8 D1= 0011B 00DFF C=DAT1 A 00E02 D1=C %on fait pointe D1 à l'adresse de base de la ram interne 00E05 C=0 A %en fait, meme si on lit 5 quartets en 0011B, seul le quartet en 0011F est important 00E07 GOTO 00E21 %on definit un masque de sortie à 0 (ainsi, pour les SHUTDN, impossible de 'reveiller' la machine par un appui sur les touches) %routine appelée entre autre par la routine du OFF % sp desinhibe le clavier pour les tests utilisant le SHUTDN 00E0B D1= 0011B 00E12 C=DAT1 A 00E15 D1=C 00E18 P= 1 00E1A C=0 A 00E1C LC 1FF 00E21 D1= 04C3 %on memorise un masque de sortie pour test clavier donné en argument 00E27 DAT1=C X %entre autre par les routines en 00DF8 ou 00E0B 00E2B OUT=C 00E2E C=IN 00E31 ?C#0 A % si une touche correspondant au masque precedent 00E34 RTNYES % est appuyé, retour avec la carry allumée 00E36 RTN clavier pour les tests utilisant le SHUTDN 00E0B D1= 0011B 00E12 C=DAT1 A 00E15 D1=C 00E18 P= 1 00E1A C=0 A 00E1C LC 1FF 00E21 D1= 04C3 %on memorise un masque de sortie pour test clavier donné en argument 00E27 DAT1=C X %entre autre par les routines en 00DF8