SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ......

8
------------------------------------------------------- SOFTVVAR~/M o ~dTI]}Jl~® a cura di Andrea de Prisco Figura l myport = (struct MsgPort .)CreatePort("HyPort",0); myreq = (struct IOStdReq ')CreateStdIO(myport); OpenDevice("input.device",0,myreq,0); Funzione Aggiunge un Input.Handler alla catena Toglie un InputHandler Scrive un evento Setta la soglia (di che??) Setta il periodo (di che??) Setta la porta del mouse Setta il tipo di controller del mouse Setta il trigger del mouse ne in Assembly. Per acquisire questa praticità è necessario fare molto eserci- zio: prima programmi brevi, poi sempre più lunghi e complessi, fino ... alla input .device, che non è affatto un traguardo finale, ma una buona Maglia Rosa. Chi, poi, è più esperto, può addolcirsi la vita con un po' di programmazione multilin- guaggio, che non guasta mai. Nel corso dell'articolo accenneremo anche a que- sto aspetto. struct Nade ( struct Node -ln Succ; str'uct Node -In -Pred; UBYTE In_Type;- BYTE In Pri; char -ln:Name; Il nodo is_Node, cosi' strutturato: Aggiungiamo un InputHandler Come abbiamo detto, un InputHand- ler è un segmento di programma in Linguaggio Macchina (come risulta dal- l'Assembling o dalla compilazione) che il S.O. chiama automaticamente ogniqual- volta succede qualcosa, QUALUNQUE cosa. Nel caso specifico dell'Amiga, più InputHandler si uniscono per formare una «catena»: ogni «anello» della cate- na viene chiamato prima del successi- vo. L'ordine in cui gli InputHandler ven- gono chiamati è dettato da una loro priorità: gli InputHandler a priorità bassa vengono chiamati per ultimi. Se proprio ci tenete a saperlo. sappiate che la priorità di Intuition è 50: pertanto tutti gli InputHandler con priorità inferiore a 50 verranno chiamati dopo Intuition. mentre quelli con priorità superiore a 50 verranno chiamati prima. Anzitutto, vediamo come aggiungere un InputHandler alla catena. Prepariamo una struct Interrupt. così conformata: ...•.. struct lnterrupt ( struct Node is Nade; APTR is_Data; VOID ('is_Code)(); modalità di funzionamento di ciascuno dei comandi sopra visti, con particolare riguardo alla possibilità di aggiungere un Handler. Valore 9 10 11 12 13 14 15 16 Comando IND-ADDHANDLER IND_REMHANDLER IND_WRITEEVENT IND_SETIHRESH IND_SETPERIOD IND_SETMPORT IND_SETMTYPE IND_SETMTRIG Tabella A La Input.Device Per aprire la input.device la procedura è la solita: da C daremo quanto è rap- presentato in figura 1. Noterete le funzioni della libreria ami- ga.lib (CreatePort() e CreateStdIO()) nonché l'assoluta inesistenza di una in- putevent.device. Il file INCLUDE "devi- ces/inputevent.h", infatti, non corri- sponde a un omonimo device, ma con- tiene parecchie definizioni interessanti, che ci saranno utili in seguito. I comandi della input.device sono ri- portati in tabella A. Nel corso dell'articolo preciseremo le La Input.Device main() ( struct MsgPort 'myport; struct IOStdReq 'myreq; #include <exec/ports.h> #include <exec/io.h> #include <devices/input.h> #include <devices/inputevent.h> Sono le undici di sera ... dopo este- nuanti compilazioni, mi ritrovo con gli occhi sbarrati di fronte al monitor ... Ac- cidenti, non trovo i sorgenti ... ah eccoli qua, sembrano vecchi di tre anni, eppu- re li ho stampati proprio ora, si vede che la mia scrivania-ciclone invecchia le co- se (e anche me) ... Sì, ne è valsa la pena: la input.device merita altro che un'intera giornata di compilazioni ... Pe- rò, che giornata ... Impossessiamoci dell'Amiga Credere che retribuire il rivenditore di fiducia nell'acquistare un Amiga sia suf- ficiente a «possederlo» è un errore grossolano. Il «possesso» di un oggetto consiste, a mio parere, nel conoscerne - e saperne sfruttare - tutte le carat- teristiche. Un valido espediente - sebbene non facilissimo - per possedere l'Amiga è aprire la input.device e aggiungere un InputHandler nella catena del S.O. Mi spiego meglio: tramite la input.device potremo inserire un segmento del no- stro programma in una «nicchia» privile- giata e far sì che il Sistema Operativo lo chiami ogni volta che si verifica qualco- sa (in gergo un «evento»). Premetto subito che l'argomento non è dei più semplici: anzitutto bisogna avere un po' di dimestichezza con la programmazio- di Maurizio Mangrella - Eboli 244 MCmicrocomputer ~. 89 - ottobre 1989

Transcript of SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ......

Page 1: SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ... Linguaggio Macchina (come risulta dal- ... re è dotato di registri: quelli del 68000 (lasciando

-------------------------------------------------------

SOFTVVAR~/M o~dTI]}Jl~® a cura di Andrea de Prisco

Figura l

myport = (struct MsgPort .)CreatePort("HyPort",0);myreq = (struct IOStdReq ')CreateStdIO(myport);OpenDevice("input.device",0,myreq,0);

FunzioneAggiunge un Input.Handler alla catenaToglie un InputHandlerScrive un eventoSetta la soglia (di che??)Setta il periodo (di che??)Setta la porta del mouseSetta il tipo di controller del mouseSetta il trigger del mouse

ne in Assembly. Per acquisire questapraticità è necessario fare molto eserci-zio: prima programmi brevi, poi semprepiù lunghi e complessi, fino ... alla input.device, che non è affatto un traguardofinale, ma una buona Maglia Rosa. Chi,poi, è più esperto, può addolcirsi la vitacon un po' di programmazione multilin-guaggio, che non guasta mai. Nel corsodell'articolo accenneremo anche a que-sto aspetto.

struct Nade (struct Node -ln Succ;str'uct Node -In -Pred;UBYTE In_Type;-BYTE In Pri;char -ln:Name;

Il nodo is_Node, cosi' strutturato:

Aggiungiamo un InputHandlerCome abbiamo detto, un InputHand-

ler è un segmento di programma inLinguaggio Macchina (come risulta dal-l'Assembling o dalla compilazione) che ilS.O. chiama automaticamente ogniqual-volta succede qualcosa, QUALUNQUEcosa. Nel caso specifico dell'Amiga, piùInputHandler si uniscono per formareuna «catena»: ogni «anello» della cate-na viene chiamato prima del successi-vo. L'ordine in cui gli InputHandler ven-gono chiamati è dettato da una loropriorità: gli InputHandler a priorità bassavengono chiamati per ultimi. Se proprioci tenete a saperlo. sappiate che lapriorità di Intuition è 50: pertanto tuttigli InputHandler con priorità inferiore a50 verranno chiamati dopo Intuition.mentre quelli con priorità superiore a 50verranno chiamati prima.

Anzitutto, vediamo come aggiungereun InputHandler alla catena. Prepariamouna struct Interrupt. così conformata:...•..

struct lnterrupt (struct Node is Nade;APTR is_Data;VOID ('is_Code)();

modalità di funzionamento di ciascunodei comandi sopra visti, con particolareriguardo alla possibilità di aggiungere unHandler.

Valore9

10111213141516

ComandoIND-ADDHANDLERIND_REMHANDLERIND_WRITEEVENTIND_SETIHRESHIND_SETPERIODIND_SETMPORTIND_SETMTYPEIND_SETMTRIGTabella A

La Input.DevicePer aprire la input.device la procedura

è la solita: da C daremo quanto è rap-presentato in figura 1.

Noterete le funzioni della libreria ami-ga.lib (CreatePort() e CreateStdIO())nonché l'assoluta inesistenza di una in-putevent.device. Il file INCLUDE "devi-ces/inputevent.h", infatti, non corri-sponde a un omonimo device, ma con-tiene parecchie definizioni interessanti,che ci saranno utili in seguito.

I comandi della input.device sono ri-portati in tabella A.

Nel corso dell'articolo preciseremo le

La Input.Device

main() (struct MsgPort 'myport;struct IOStdReq 'myreq;

#include <exec/ports.h>#include <exec/io.h>#include <devices/input.h>#include <devices/inputevent.h>

Sono le undici di sera ... dopo este-nuanti compilazioni, mi ritrovo con gliocchi sbarrati di fronte al monitor ... Ac-cidenti, non trovo i sorgenti ... ah eccoliqua, sembrano vecchi di tre anni, eppu-re li ho stampati proprio ora, si vede chela mia scrivania-ciclone invecchia le co-se (e anche me) ... Sì, ne è valsa lapena: la input.device merita altro cheun'intera giornata di compilazioni ... Pe-rò, che giornata ...

Impossessiamoci dell'AmigaCredere che retribuire il rivenditore di

fiducia nell'acquistare un Amiga sia suf-ficiente a «possederlo» è un erroregrossolano. Il «possesso» di un oggettoconsiste, a mio parere, nel conoscerne- e saperne sfruttare - tutte le carat-teristiche.

Un valido espediente - sebbene nonfacilissimo - per possedere l'Amiga èaprire la input.device e aggiungere unInputHandler nella catena del S.O. Mispiego meglio: tramite la input.devicepotremo inserire un segmento del no-stro programma in una «nicchia» privile-giata e far sì che il Sistema Operativo lochiami ogni volta che si verifica qualco-sa (in gergo un «evento»). Premettosubito che l'argomento non è dei piùsemplici: anzitutto bisogna avere un po'di dimestichezza con la programmazio-

di Maurizio Mangrella - Eboli

244 MCmicrocomputer ~. 89 - ottobre 1989

Page 2: SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ... Linguaggio Macchina (come risulta dal- ... re è dotato di registri: quelli del 68000 (lasciando

SOFTWAREAMIGA

struct InputEvent (struct InputEvent -ie_NextEvent;UBYTE ie_Class;UBYTE ie_SubClass;UWORD ie_Code;UWORD ie_Qualifier;union (struct (

I.AX)RD ie_x;WORD ie.s;

) ie_xy;APTR ie_addr;) ie_position;struct timeval ie_TimeStamp;

Contiene informazioni interessanti,ma l'unica realmente utile è la priorità (ilcui significato abbiamo già visto). is_Da-ta contiene un dato a 32 bit (di qualun-que genere: ricordo che APTR è unpuntatore a un non meglio definito arraydi long-word, dunque potete farci quelloche volete) che ci verrà passato nelregistro A 1 (vedi dopo). mentre is_Codeè l'indirizzo del nostro InputHandler. Se,ad esempio, il nostro InputHandler sichiama HandlerlnterfaceO e l'is_Data dicui abbiamo bisogno è l'indirizzo di unastruttura XYZ, da C daremo:..•..

#define#define#define

ie_Xie_Yie_EventAddress

ie_position.ie_xy.ie_xie_position.ie_xy.ie.sie_position.ie_addr

/. Definizioni utili *;

struct Interrupt Handlerlnt;struct XYZ ( eccetera, eccetera ... )

Figura 2

dopo il pre-processing di Intuition: perriceverli dovete settare, per il vostroInputHandler, una priorità inferiore a 50.

SubClass, nelle attuali versioni delS.O., è sempre a O. Code contiene uncodice riguardante l'evento accaduto; ivalori interessanti per il nostro discorsosono rappresentati in figura 4.

Ad ogni tasto corrisponde un Codeparticolare, che - purtroppo - non èASCII: ho raffigurato i codici in figura 5.Gli altri valori si autocommentano, dun-

mento. Ricordo anche che alcu-ne Class hanno associato, in ie-

EventAddress, un indirizzo: in particola-re, quando le Preferences vengonocambiate, viene passato l'indirizzo dellenuove. Così. per le Classes degli eventilegati a una finestra, viene passato l'in-dirizzo del Window Record relativo alla

finestra interessata. Tenete co-munque presente che tutti que-sti eventi (quelli con Class mag-giore di 6) sono disponibili solo

myreq->io_Oata • (APTR)&Handlerlnt;myreq->io_Length - sizeof(struct Interruptl;myreq- >io_Comma.nd • IND_ADDHANDLER;Do IO(myreq);

Notate i cast (per evitare fiere prote-ste del compilatore) e notate inoltre ilmodo di setta re la priorità: con il valore51 il nostro Handler sarà eseguito subi-to prima di Intuition.

Infine, aggiungeremo l'Handler così:..•..

f1andlerlnt.is_Code • (VOlO o lHandlerlnterface;Handlerlnt.is_Data - (APTR)&XYZ;Handlerlnt.is_Node.ln_Pri - 51;

Figura 3

(ol Solo per il KickStart 1.2

Tutti saprete che ogni microprocesso-re è dotato di registri: quelli del 68000(lasciando da parte quelli speciali) sono16, 8 dati (numerati da DO a D7) e 8indirizzi (numerati da AO a A7). A7 èanche lo Stack Pointer (SP). ovvero ilpuntatore ad un'area di memorizzazionetemporanea dei dati con funzionamentoLIFO (Last-I n-First-Out). proprio comeuna «catasta» (stack in inglese significacatasta). Quando il S.O. chiama il nostroInputHandler ci passerà l'evento corren-te in AO, sotto forma di indirizzo ad unastruct InputEvent conformata come infigura 2.

Class è il parametro principale, indi-cante il tipo di evento accaduto; infigura 3 tutti i possibili valori.

Come vedete, la scelta è ampia. Ri-cordo che per «rinfrescare» una finestrasi intende restaurarne il contenuto dopouna operazione di resizing o di sposta-

ClassIECLASS_NULLIECLASS_RAWKEYIECLASS_RAWMOUSEIECLASS_EVENTIECLASS_POINTERPOSIECLASS_UnusedlECLASS_TIMERIECLASS_GAOGETDaWNIECLASS_GAOGETUPIECLASS_REQUESTERIECLASS_MENULISTIECLASS_CLOSEWINDOWIECLASS_SIZEWINDOWlECLASS_REfRESHWINDOWIECLASS_NEWPREfSIECLASS_DISKREMOVEDIECLASS DISKINSERTEDIECLASS-ACTI VEWI NDOWIECLASS=INACTIVEWINDOW

Valore·

I1Ixi1ll1l111xl1l lI1Ixl1l2I1Ixl1l3I1Ixl1l4i1Ixi1l5I1Ixl1l6111xl1l 7I1Ixl1lBI1Ixl1l9I1Ixl1lAI1Ixl1lBi1Ixi1lCI1Ixi1lDI1Ixl2lEI2Ixl1lf

i1Ix1i11I1Ix11I1Ix12

EventoNessun evento (interrupt spurio)Pressione/rilascio di un tastoSpostamento del mouseMandato quando una f,Jindow viene attivataPosizione del puntato re del mouseNon usatoTimer Event (mandato ogni decimo di secondo)Un gadget e' stato premutoUn gadget e' stato lasciatoE~ stato attivato un AutoRequesterE~ stata selezionatF.t.una voce da un MenuUna finestra e' stata chiusaUna finestr'a.e' sta,ta ridimensionataUna finestra e' stata "r infr'escata"Le Preferences sono st,ate cambiateUn di~chetto e' stF:lt,o espulsoUn dischetto e' stato inseritoUna finestra e' stata attivata (.)Una finestra e' stata disattivata (.)

MCmicrocomputer n. 89 - ottobre 1989 245

Page 3: SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ... Linguaggio Macchina (come risulta dal- ... re è dotato di registri: quelli del 68000 (lasciando

SOFTWAREAMIGA

.......................................................................Input.Event Test by MauriZIO Mangrella 1989

Questo programma ln Assembler e un demo della lnpul.devlce.ed e una ["lscrlttura cl, un demo di Rob Peck, COl'lllllOdore-Amlga. Inc.

La dl.mostrazlone conStste nel salvare a un file gl1 eventI passatial programma attraverso un Handler à991unto alla 'catena' d!Intu1t10n, con prlorlta maggiore di quella di IntUltlon: per-tanto li nostro Handler sara eseguito prima di Intuition (qualeonore!! J.

:--~;~~-;~~~~~;~~;-;-;~~~;-~;i-f;i;;----------------------------------"Salva gli eventI verlflcatlsl al ftle (nome del [lIeto Per como-

dita di programmaZione ho fatto U80 della redlrezlone del DOS.NOTA: Se non specifIcate la redlrezlone C')') glI evenll verranno

IndIrizzatI su _stdout, con le conseguenze lmmaglnablil. •·-- --- -- ------ --- ---- --- ------- --- --- ---- --- ---------------- --- ------_.Potrete nota re come non SI sIa Catto uso dell e di ret t i ve

STRUCTURE: in ef fett i mi e sembrata un' l nut 11 e comp I icaz ione. COSl• ,=om'e, 11 programma glra perfettamente anche llnk-ato con la sola• amlga. Ilb. RIcordo che le rOutlne di questa 11brerla sono copyright

:-~~~:~-~~~~~:~=~~~~~~-~~~~----------------------------------------_.: c by MaurIZIo Mangrella 1989,.......................................................................

• CostantI dI uso genera le

E' pronto un nuovo evento?No: aspettaResetta 11 [IagDO.L = OPreleva ClassE' un Tlmer Event?51: non lo salvaE' un RAWkey Event?No: continuaPreleva CodeE' 11 tast.o ESC rIalzato?51: termlna 11 programmaPreleva 11 Pile HandlePreleva l' lndirizzo di InpulEvent02 '" Output BufferSalta le NelltEvent81zeoflstruct InputEvent )-4Sa l va l'eventoRlcomlncla daccapo

NewEventLoopNewEventDOle Clas8,DOUECLASS TIMER,DOLoop -'l ECLASS RWKEY,DOContinuesle Code, 00tlECOOE ESC.OOEnding -Fl1eHandle,OlInputEvent,AOAO,D214,02'18,03

LVOWriteIA6)Loop

TST.WBEQ.SCLR ,WCLR.LMOVE.BCMPI.BBEQ.SCMPI.8BNE.SMOVE.WCMPI,WBEQ.SMOVE.LLEAMOVE.LADOQ.LMOVEQJSRBRA.S

Loop dl attesa. Salva gli eventlpassatl dall'Ha.ndler. Il program-ma finisce quando viene premuto erllasClato 11 totlsto ESC.

Loop

• FIne programma, Il programma to-• gIle l'Handler Sistemato, chiude• tutte le gtrutture, libraries e* devices aperte e restItuisce i I• controllo al DOS.

Contlnuea

;Rlferlmento assoluto a ExecEQU_SysBase

• Offsets per una IOStdReq

I D ADOHANDLEREQU 9IO=:REMHANOLEREQU IO

I ECLASS TI MER EQU 6IECLASS-RWKEY EQU ll ECODE_ESC EQU 545

L'Handler. Copla il prImo eventodella cotltena che gl l vIene passa-ta.L'uso dello stack ha creato pro-bleml In run-tIme. pertotlnto horlplegato su una memOriZZotIZ10netemporanea nell'area datI delprogramma,

ooSBase,AI ;OOS Base Llbrotlry POlnter_SysBase,A6 ;Una routlne dI Exec

LvocloseLlbrarylA6) ;Chlude la dos.llbraryInterrupt.AO ;lndlrlzzO dl lnterruptIOStdReq,AI ;lndlClzzo del loti nostra IOStdReqAO,io DatalA}) :IndlrlZZO ln 10 DalaUD_REMHANDLER,lo_Command(AII ;To91l l'Handler!_LVODoIO l A6 l ; Esegue i 1 comandoIOStdReq,AI ;IOStdReq Addres8 In Al_LVOCloseDevicelA61 :Chlude la Input.devlceMsgPort.-ISPI ;MsgPort Addre8s sullo stack

OeletePort :Chlude Il portt4,5P ;Agglusta lo stackIOStdReq.-(SP) :E adesso chIudIamo ..._DeleteStdlO : ' •• la IOStdReqt4,SP ;RIaggluata lo stack'0,00 ;RETURN OK

;Buonanotte~

;Salva I registrI

; Una rout I ne dI Exec;DIsab1l1tlamo glI lnterrupts: 22 bytes da copiare; COpIa. l' Event:Riabll1ta gli Interrupts;Rlprende I registri

:Rltorna l'indirlzzo dell'Event;Setta 11 [lag di 'Nuovo Evento'

AO, SaveAOAI,Sa.veAI

SysBase,A6-LVOForbld l A61'22, DO_LVOCopyMemIA6)

LVOPermltlA61saveAO,AOSaveAl,AlAO,DO'LNewEvent

MOVE.LMOVE.LJSRLEAMOVE.LMOVE.LMOVE.WJSRMOVE.LJSRMOVE.LJSRADOQ. LMOVE. LJSRADDQ.LMOVEQRTS

MOVE.LMOVE.LMOVE.LJSRMOVEQJS'JS'MOVE.LMOVE,LMOVE.LMOVE.WRTS

Endlng

MyHandler

;Comando dI aggiunta dI un handler;Comando di rimozione handler

;Clotlss di un Timer Event;Class di un RAWkey;Code del totlsto ESC rlotllzato

;Per le routlnes della otImiga.llb_SysBase

o2024283031323.4044

_LVOOpenLlbrary_LVOOutput

LVOOpenDevlce-Createport-CreateStdlO-LVODoIO

LVOWrlte::::LVOCloseLlbrary

LvocloseDevlce-oeletePort

DeleteStdIO-LVOForbld- LVOCopyMem-LvOpermlt

faremo uso

XDEF

XREFXREFXREFXREFXREFXREFXREFXREFXREFXREFXREFXREFXREFXREF

EQU

EQU

EQUEQU

EQU

EQUEQU

EQU

EQUEQU

• Routines d)

lO Meaaage10-OevlcelO-UnltlO-CommandlO-Flags10-ErrorlO-Aclual10-LengthlO-Data10::::Offaet

Loop dl pre-attesa. Attende l'ar-rlVO del primo evento e ne salvali TlmeStamp.

Sezione di Inlzlallzzazlone delloHandler. Vengono aperte librerie,porta e devlces e oppo~tunotlmentelnlZlallZZotIte. Fa USO di funZionidella llbrerla amlga.lib ICommo-dore-Amlga, lnc.l.

MOVE.LMQVEQLEA

JS'MOVE.LMOVE.LJSRMOVE.LMOVE.LPEA

JSRMOVE.LAOOQ.LMOVE,LJSRMOVE.LADDQ.LLEAMOVE.LMOVEQMOVEQMOVE. LJS'LEAMOVE.LLEAMOVE.LMOVE,LLEAMOVE.LMOVE.WJSR

SysBase,A6 ;Preleva SysBase'0,00 ;Qualunque versione va beneDosName.Al :Nome della llbrary Cdos.llbraryl

LVOOpenLibrarytA61 ;Apre la llbrerla00,A6 ;Prende 11 puntatore ...A6.D05Base ; ••. e lo mette In D05Base

LVOOutputlA61 ;'Initlal Output FIleHandle'OO,Fl1eHandle ;Lo conserva in FileHa.ndletO,-ISP) ;Flags = PA_SIGNALPortName ; Nome del port ClnputOevPort l

CreatePort ; Crea 11 portDO.MsgPort :Conserva 11 puntatore ln MsgPortt8,SP :Agglusta lo stackDO,-tSPl :Indlrlzzo del port

CreateStdIO :Crea una lostdReqDO.IOStdReq ;Conserva Il puntatore In IOStdReqI4,SP ;Aggiusta lo stackOevName, AO ; Nome de l dev ice I input. dev ice )IOStdReq,A1 ;IndlrlZZO della IOStdReq'0,00 ;Flags " O'0,01 ;Unit '" °

SysBase,A6 :Routlne di Exec- LVOOpenOev lce l A6) ; Apre Il dev lceInputEvent.AO :L'indlrlZZO del nostro InputEventAO.1S Data :Slstema l'IndiriZZO In Is_DataMyHandler,AO ;11 nostro HandlerAO,IS Code ;Ne sistema l'IndiriZZO ln ls_codeIOStdReq,A1 ;La nostra IORequestInterrupt,AO :11 nostro Interrupt StuffAO,io DatalAl) ;Indirizzo di Interrupt In io_DatafIO AODHANDLER,lO CommandCA11 ;Comando

LVODoI01A6) - ;Aggiunge l'handler

Area dati

DOSBase DC.L

MsgPort DC.LIOStdReq DC.L

FileHandJe DC.L

SaveAO DC.LSaveAl OC. L

Interrupt:u-Node -Succ DC.Li. Node Pred DC.L,.-Node ::::Type Oe.B-u-Node_ p" OC.Bu-Node -Name DC.Lu-Data DC.Lu-Code DC.L

I nputEvent:..-NextEvent DC,Lie-Cla88 DC.B,e SubClass DC,Bie-Code De.Wle.=Quallfier DC,W,e-X DC.W,e y DC.W,e -Tlme -Secs DC.L,e -Time mScs DC.L- -NewEvent DC.W

DosName DC.BPortName DC,BDevName DC.B

CNOP

END

OOO51OOO

'dos.library' ,O, I nputOevPort ' , °'input.devlce' ,O

0.2

;SpaZlo per OOS Llbrary POlnter

;SpaZlo per MsgPort POlnter:SpazIo per IOStdReq POlnter

;SpaZlo per flleHandle POlnter

;MemorlzzaZlone del registri

; Il nostro Interrupt Vector

;Un gradIno P1U su di Intultlon

; Il nostro Input Event

:Flag di 'Nuovo Evento'

;11 nome della dos.IIbrary; I I nome del nostro port; Il nome de Ila lnput .deVlce

InJtLoopMOVE.LTST.WBEQ.SCLR.WLEAMOVE.LMOVE.LMOVEQJSR

DOSBase, A6NewEventInitLoopNewEventle Tlme Sec8.AOA0702 -FlleHandle.Ol'8.03_LVOWrlteIA61

:Per le routlnes della dos.librar)';Attende l'arrivo di un evento

Reaetta 11 C lagForma l'lndlrlzzo di t.lmeval02 '" Output BufferPreleva FlleHandleSalva due long-wordsSalva Il timeval

246 MCmicrocomputer n. 89 - ottobre 1989

Page 4: SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ... Linguaggio Macchina (come risulta dal- ... re è dotato di registri: quelli del 68000 (lasciando

SOFTWARE

AMIGA

que li tralasceremo.Oualifier «qualifica» in maniera più

specifica l'evento in corso: qualificatoriimportanti sono i tasti speciali e quellidel mouse. In figura 6 i Oualifiers, unoper uno.

Più Oualifiers possono essere passaticontemporaneamente OR-andoli, o - il

che è lo stesso, nel caso specifico -sommandoli.

Ouando un tasto viene premuto, vie-ne inviato il suo normale Code; quandoviene rilasciato, viene di nuovo inviato ilsuo Code, ma maggiorato di IECO-DE_UP _PREFIX (80 hex., 128 dec.). Inquesto modo è possibile sapere quando

un tasto viene rilasciato o premuto. Iltasto di Caps Lock ha un comportamen-to particolare: riporta il valore 62 hex.quando viene premuto (accendendo ilLED). e viene considerato premuto finoa quando non viene premuto di nuovoper spegnere il LED: in tal caso vienemandato il codice E2 hex.

• Costant1 di uso generale

Rlpropone gl1 eventl registratl al file Inome del fdel. Per como-dlta dl programmazlone ho fatto uso della redlrezlone del OOS.

NOTA; Se non speclflcate la redlrezlone 1'('1 gll eventiripreSI da stdln, con le conseguenze immaglnabll1 ..·-- --- ---- - -_:: ---- --- -- --- -- --- --- --- ------- -- -- --- - -- ---- -- --- ------_.

;Preleva OOSBase;51; preleva FdeHandle;Prelev<l l' lndlrlzzo dL TlmeSt<lmp;02 = Buffer Address; Due long words;Legge II TimeStamp

OOSBase,A6 ; Preleva ooSBaseFlleHandle,DI ;Fl1eHandle In DIInputEvent,AO ;lndlr1zzo dI InputEvent'4,AO ;Salta le NextEventAO,02 ;02 '" Input Buffer'la,03 ;Lunghezza dl InputEvent - 4

LVORead l A6) ; Legge l'evento'0,00 ;Testa 00 (ntornato da ReadlllEnding ;00 (= ° (errore/fIne elle)InputEvent,AO ; Indlrizzo di InputEventIOStdReq,AI ;Indirizzo dI IOStdReqAO, io Data (Al) ; Ind. di I nputEvent In lo_Data'IO WRITEVENT, io CommandlAll ;Comando di 'stampa' eventoie Time Secs,OO - ;Secondi del l 'evento caricatoTi;e SeCB, DO ; Secondl da 110 scorso event.o'50,00 ;In cinquantesimi di secondoie TLme mSc8.01 ;Mlcrosecondl del l 'event.o car1catoTl;;;e Se'CB,OI ;Microsecondl dallo scorso evento'20000,01 ; In clnquantesLllll di secondo"SOOOOFFFF,Ol ;Preleva solo 11 quozienteDI ;EBt.ende 11 segno dI DI00,01 ;Aggiunge l due rlSultatl

LVOOelaylA61 ;Attende 11 paSBare del tempo:=&ysBaBe,A6 ;Una routlne dl Exec

LVODoIOlA61 ; 'Scatena' l'eventoTe T1me Secs,Tlme Secs ;Nuovi valorl per li tempoie -Time - mScs, Tlme - mSCBLoop - - ;Oaccapo (fino alla fine del (llel

OOSBase,A6FlleHandle,OlTlme Secs,AOAO,02ta,03

LVORead lA6)

MOVE.LMOVE.LLEAADOQ.LMOVE.LMOVEQJSRCMPI.LBLE.SLEAMOVE.LMOVE.LMOVE.WMOVE.LSUB.LMULUMOVE.LSUB.LDIVSANOI.LEXT.LAOO.LJSRMOVE.LJSRMOVE.LMOVE.LBRA

MOVE.LMOVE.LLEAMOVE.LMOVEQJSR

Loop di loading degli eventi dalfde. Legge gli eventi e li ri-propone fino alla fine del file.

Flne programma. I l programma chiudetutte le strutture, libraries e de-v lces aperte e rest i tu lace i I con-trollo al 005.

Loop

;Rlfer1mento assoluto a Exec

;Comando d1 scrlttura di un evento11

•2.242B3.31323.4.44

by M3UI'"UIO Mangrella 1989

EQUEQUEQUEQUEQUEQUEQUEQUEQUEQU

InputEvent Test

• Offsets per una IOStdReq

lO Messagelo-Devlcelo-Unlt10- Command10:=flagslO Errar10-Actua IlO-Lengthlo-Data10:=O!fset

Questo programma 10 Assembler e un demo della lnput.devlce.ed e una rlscrlttura dI un demo dl Rob Peck, Commodore-Amlga. Inc.

La dUl105trazlone consiste nel salvare a un fl.le gli eventl passatial programma attraverso un Handler aggiunto alla 'catena' dilntuition, con priOl'"lta maggiore di quella di Intuition: per-tanto .lÌ nostro Handler sara esegUIto prima di Intuitl.on (qualeonore!! l. Il presente programma riprende gli eventi salvati con

·-~~~=~~:~~~_:_::_::~:~~~=-~~~~~~:-~~~~:~~---------------------------*uso: LoadEvents ( (nome del flle)

Potrete notare come non SI sia fatto uso delle dlrettlveSTRUCTURE; In effettl mi e sembrata un'inutile complicazione. COS1

• com'e, 11 programma gira perfettamente anche link-ato con la sola• amlga. llb. Ricordo che le routlne di questa libreria sono copyright:-~::~~-~~~~~~~::=~~~~::-~~::----------------------------------------_.

Routlnes d1 CUl faremo uso

SeZ10ne d1 lnlZlallzzaZ10ne dellaInput,devlce. Vengono aperte li-brerie, ports e devices e oppor-tunamente lnlzlallzzate. Fa uso

• di funZIoni della 11brer1a• amlga.l1b ICommodore-Amlga, Inc.l.

CNOP

DOSBase OC. L

FileHandle DC.L

;11 nome della dos.library; Il nome de 1 nostro port; I I nome della lnput .dev1.ce

;Area datl per 11 conto del tempo

'dos.library' ,O'InputDevPort' ,O'input.device' ,O

6,2

; I l nost ro I nput Event

;SpaZlo per OOS Llbrary POlnter

,O,le Class ;Mandiamo un NULL EventInputEvent,AO ; Indlrizzo dl Input.EventIOStdReq,AI ;lndiClzzo di IOStdReqAO,lo_Oata(All ;lnputEvent In 10~OatatIO WRITEVENT,io Command(AII ;Comando

SysBase,A6 - ;Routine dl Exec-LVOOoIOIA61 ;Sped1Bce l'eventoDoSBase,AI ;005 Base Llbrary Pointer

LVOCloaeLibrarylA6) ;Chlude la dos.libraryIOStdReq,AI ;Indirizzo della nostra IOStdReq

LVOCloseOevicelA61 ;Chiude la input.deviceMsgPort,-ISP) ;MBgPort Address sullo stack

DeletePort ;Chiude i l port'4,SP ;Aggiusta lo at.ackIOStdReq, -I SP l ; E adesso ch ludl<lmO ...OeleteStdlO ; .•. la IOStdReq

'4,SP ;Rlagglusta lo stack'0,00 ;RETURN OK

; Buonanotte!

;Spazlo per MBgPort Pointer;Spazio per IOStdReq Pointer

;Spazio per FileHandle Pointer

MOVE.BLEAMOVE.LMOVE.LMOVE.WMOVE.LJSRMOVE.LJSRMOVE.LJSRMOVE.LJSRAOOQ.LMOVE.LJSRAOOQ.LMQVEQRTS

Area datl

I nputEvent;le NextEvent DC.Lie-Class OC.Ble -SubClass OC.Ble-Code OC.Wie-Qualifier OC.Wle-X DC.Wle -Y DC.Wle-Time Seca DC.Lle:=Time=:mScB OC. L

EndLng

DOBName OC. BPortName DC. BOevName OC. B

MsgPort OC. LIOStdReq OC. L

Tlme Secs DC. LTime=:mScs OC. L

Preleva SysBaseQualunque versione va beneNome della library Idos.library)Apre la llbrerlaPrende 11 puntatore ...•.• e lo mette ln DOSBase'Inltlal Input FlleHandle'Lo conserva In FlleHandlePlags '" PA SIGNALNome del pOrt IlnputOevPortlCrea 11 portConserva 11 punt.atore In MsgPortAggIusta lo atackIndlrizzo del portCrea una IOStdReqConserva il puntatore In IOStdReqAggiust.a lo stackNome del device l input .device)Indirizzo della IOStdReqFlaga '" OUn1t '" ORoutine di ExecApre il dev ice

sysBase,A6'0,00DosName ,Al

LVOOpenL1brary I A6)00,A6A6,OOSBase

LVOlnputlA61OO,FIleHandle'O, -ISP)PortNameCreatePort

OO,MsgPort,a.spDO, -ISPI

CreateStdIODO. IOStdReqt4,spOevName,AO10StdReq,A1'o ,DO10,01

SysBase, A6=:LVOOpenOevicelA61

_5ysBase

LVOOpenLibrary-LVOlnput- LVOOpenDev 1ce-CreatePort-CreateStdlO-LVOOoIO- LVORead

LvoDelay- LVOCloseLlbrary- LVOCl oseOev ice

DeletePortOeleteStdlO

MOVE.LMOVEQLEAJSRMOVE.LMOVE.LJSR/'1OVE.LMOVE.LPEA

JSRMOVE.LAOOQ.LMOVE.LJSRMOVE.LAOOQ.LLEAMOVE,LMOVEQMOVEQMOVE.LJSR

XREF'XREFXREF'XREFXREF'XREF'XREF'XREFXREF'XREfXREFXREF'

XOEF'

Main

InlZlallzzazlone del loop dl loaddeglI eventl. VIene car1cato II'tempo' del prImo evento e con-servato in luogo .•• freaco e a-SCIuttO .,.

END

MCmicrocomputer n. 89 - ottobre 1989 247

Page 5: SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ... Linguaggio Macchina (come risulta dal- ... re è dotato di registri: quelli del 68000 (lasciando

SOFTWAREAMIGA

struct time"al (ULONG t,,_secs;ULONG t,,_micro;

che riporta il numero di secondi e mi-crosecondi trascorsi dall'accensione delcomputer (o dall'ultimo azzera mento).

Consigli di programmazioneAnzitutto, è bene cominciare l'lnput-

HanéJler con una chiamata alla funzioneForbidO della exec.library, che inibisce ilperpetramento (aiuto mamma!) di ulte-riori Software Interrupt; poi li riabilitere-te con una chiamata alla PermitO primadi uscire dall'Handler. Vediamo unesempio in figura 7 (vedi dopo per ulte-

Il valore settato in is_Data al momen-to della sistemazione dell'lnputHandlerci viene passato (come detto) in A 1:tenete presente che potete variare apiacimento il valore di questi registri ... avostro rischio e pericolo! AI terminedell'lnputHandler, comunque, dovretepassare, in DO, l'indirizzo di una structInputEvent contenente l'evento oppor-tunamente «cucinato» dal vostro Input-Handler.

Infine, ie_TimeStamp è una structtimeval così organizzata:..•..

_LVOPermit_fprintf

XREFXREF

Programmazicme multilinguaggioNell'ambito di un programma in qua-

lunque linguaggio (in Assembly, C ePasca I sicuramente) è possibile chiama-re una funzione «esterna», cioè nondefinita all'interno del programma stes-so; in C una funzione (o un dato) sidichiara «esterna» con la Keyword ex-tern:

extern struct MsgPort *CreatePortO;

ratori di redirezione > e <l. In genere,le funzioni di formatted print (printfO,fprintfO, sprintfO e chi più ne ha più nemetta) vanno dritte alla Guru Medita-tion ...

Infine è bene NON scrivere Input-Handler in C. Infatti, quasi tutti i compi-latori disponibili per Amiga (Lattice 3.10in primis, ma anche il 5.01) creano unworkspace sullo stack con l'istruzioneL1NK $FFF2,A5 - scoperta con un di-sassemblamento selvaggio -, cioèbloccando 65522 byte (!!) sullo stack eponendone l'indirizzo in A5. Tutto vabene quando ci si trova nell'ambientedel programma, ma i «casini» succedo-no quando si va nell'lnputHandler: infat-ti viene passato un A5 NON corrispon-dente a quello atteso dalla routine.

In Assembly si fa riferimento a qual-cosa di esterno (più precisamente, auna label esterna) con la direttiva XREF(Cross Reference):

rispettivamente dichiarano esterni il rife-rimento alla routine Permit (LVO sta perLibrary Value Offset) e la funzionefprintf.

I compilatori prepongono, ai nomi del-.Ie loro funzioni, un« _ »: notate, ad

riori chiari menti).Il S.O., in genere, non passa un solo

evento alla volta, ma più di uno: i varieventi sono collegati a «catena», rispet-tando l'ordine cronologico in cui si sonopresentati. Così, il campo ie_NextEventdel primo evento punta al secondo,l'ie_NexEvent del secondo contiene l'in-dirizzo del terzo ... e così via: potreteaccorgervi della fine della «catena»quando troverete un ie_NextEvent con-tenente O. Un InputHandler scritto benedovrebbe tenere presente questa (sep-pur modesta) difficoltà.

Nel caso il vostro InputHandler ne-cessiti di più dati, potete riunirli in unastruttura e passare all'lnputHandler, at-traverso A 1, l'indirizzo di questa. Untrucchetto del genere si è visto, adesempio, nell'utility POPCLI Il by TheSoftware Distillery: in questo caso sipassava all'lnputHandler una strutturacontenente vari importanti (vitali!) pun-tatori.

Nell'ambito dell'lnputHandler sono di-sponibili (quasi) tutte le funzioni di libre-ria: tenete comunque presente che unInputHandler non è un processo, dun-que non ha, in genere, un Input e unOutput FileHandle (quelli, per intender-ci, che è possibile setta re da CLI all'attodella scrittura del comando con qli ope- ,

Significato

Prefisso per ••t~c;to ril"sci.ato"Il minore valore corri~pondente a un tbsto11 rTl8,ggl.or valore per un tastoLeft Rutton del mause premutoRight Button d~l mnU5~ premutoMiddle Button (non previ~to)Nessun bottone premuto???Requester Set (?)Requester Clp.ar (?)

Valore

I1lx811lI1lxl1ll1lI1lx77I1lx&8I1lx69I1lx&AI1lxff111x 111lI1lxl1l1ilJxl1lilJ

IECODE UP PREfIXIECODE-KEY CODE fIRSTIECODF.-J<EY-CODE-LASTlF.CODE=U'lUTION -lECODE RBUTTONIF.CODF.=MAUTTONIECODE NOBUTTONIECODE=NEWACTI VEIF.CODE._REQSETlECODE_REQCLEAR

Code

Figura 4

Layout. dell .•• l-agl-io •..·-aT~AW i<:eybo;a"...d I•...•p•.•.•.

hy H"".- ì7ìn Hang,-,.,1I0 1969

Figura 5- Codiciesadecimali restituitidalla input,device nelfield code di un'InputEvent.

8__EEEI

:SA :>B ~c :SE>3E> 3E 3F 4A2E> 21: 2F 51:.lE> .lE .1F

43BF 3C

248 MCmicrocomputer n. 89 - ottobre 1989

Page 6: SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ... Linguaggio Macchina (come risulta dal- ... re è dotato di registri: quelli del 68000 (lasciando

SOFTWARE

AMIGA

Figura 6

I EQUALI Fl ER_l.5H1FT i/Ixi/li/li/llIEQUALIFIER_R5HIFT i/Ixi/li/li/l2l EQUALI FI ER_CAP5LOCK i/Ixi/li/llll4I EQUALIFI ER_CONTROL i/Ixi/li/ii/lBI EQUALIFI ER_LALT i/Ixi/ll1lHlI EQUALI FI F.R_RALT 111xl1l11l2111IEQUALIFIER_LCOMMAND I1Ix11l11l4i/1IEQUALIFIER_RCOMMAND I1Ixi/li/l8i/1l EQUALIFI ER_NUMERl CPAD IIlxi/l!11I111IEQUALIFIER_REPEAT i/Ixl1l2111111IEQUALIFIER_INTERRUPT i/Ixi/l4i/1111I EQUALIFI ER_MUL.TIBROAnCASTi/Ixl1lBl1I11Il EQUALIFl ER_MIDBUTroN i/Ix!i/Ii/1i/1l EQUALl FI ER_RBUTTON I1Ix2111111111I EQUALIFI ER_l.EFTBIITTON I1Ix4111111111I EQUAL.!FI ER_REL.ATIVEMOU5E i/Ix8111111111

funzinnf'

4_L.VOForbid_L.VOPermit

ASSEM Prog.asm -o Prog.OALiNK FROM Prog.o TO Prog L1B lib:ami-

ga.lib

Il compito fondamentale di un linker èquello di risolvere tutti i riferimentiesterni. Avete un minuto per indovinarecosa succede in quei due programmi,una volta linkati insieme: (pausa). Nonavete capito? Vabbé, non fa niente: velo spiego io. Il programma in C chiamala funzione Handlerlnterface (ricordate il« _» preposto): questa label è resadisponibile all'esterno con la direttivaXDEF (Cross Definition). Dunque il con-trollo passa alla Handlerlnterface, che,dopo un po' di operazioni (che chiarire-mo in seguito) chiama la _rnyhandler,definita esterna con la XREF. La _rny-handler corrisponde alla funzione rny-handler() del listato C: dunque, comeavrete capito (spero! Sono io che credodi non aver capito niente!) Il C chiamal'Assembly, che, a sua volta, chima il Cdi nuovo. Bello, no? Elegante e funzio-naie. Di questi trucchetti faremo mag-gior uso in seguito.

Per assemblare e linkare un program-ma (ad esempio Prog.asm) i comandisono:

;Riferimento ad Exec

Lef t Shif t, premutoRi.l'(ht. 5hi ft pr'emutoCapc; Lock premutoCont-ro l premut,oLeft Alt premutoRight Alt premutoLeft Amign.. (Commndore) prefTlutnRight Amiga premutoTf1.sto del tastierino numericoRipetizione dj un tac,toSoftware Interrupt (non usato)Event.o inviato a piu' finestreLeft Button del mouseRight Button del mouseMi.d Button (non pr'evif'jto'Coordina.te dp.l mouse r'el1'3tive

Valore

_SysBase, A6_L.VOForbid(A6)

dell' Handler>_SysBase,A6_L.VOPermit(A6)

EQUXREFXREF

MOVE.L.JSR<restoMOVE.L.J5RRTS

Figura 7

_5ysBase

MyHandler'

Qualifier

extern void Handlerlnterface();

handlerStvff.is_Code • Handlerlnterface;

Volendo compilare un programmache fa riferimento a un oggetto in As-sembler esterno con il Lattice C 3.10 lasintassi è la seguente (posto che ilsorgente C si chiami Prog_c.c e quelliin Assembly Prog-ASM.asm):

"trvct InputEvent *myhandler(ev,myda,ta) ( etc., etc .... )

XREFXDEF

_Handlerlnterface:MOVEM.LJSRADDQ.L.RTS

Figura 8

_myhandler_Handler'l nted'ace

AI1I/Al, - (5P)_myhandler#8,SP

LC1 Prog_CLC2 Prog_CASSEM Prog-ASM.asm -o Prog-ASM.oBLiNK FROM lib:c.o+Prog_c.o+Prog-ASM.o TO Prog L1B lib: IC.lib+lib:amiga.lib.

Ora, per coloro che hanno almenoqualche rudimento sul funzionamentodel 68000, spiegherò quelle che vannosotto il nome di «C Calling Conven-tions»: come si chiama una funzione

esempio, la fprintf. Ogni label definita in '1un programma C (nome di variabile,indirizzo, funzione) è SEMPRE disponi-bile dall'esterno, cioè perché un altroprogramma possa farvi riferimento. Infigura 8 uno stralcio di un programmache molto mi ha fatto penare (alla fine vispiegherò perché).

Veramente i programmi sono due, PortAddressuno in C e uno in Assembly: dopo la Por t Namecompilazione separata di entrambi, biso-gna «Iinkarli» (Iegarli insieme, unirli) conil linker ALiNK di mamma Commodore Figura 9(O BLiNK della The Software Distillery).

XREF

MOVE,L.PEAJSRADDQ,LMOVE.L.

DC.L.DC.B

_CreatePort

#111,-(SP)PortName_CreatePort#8,5P00, Por"tAddress

o ;indirizzo del Port'MyPort' ,111 ;stringa terminata con un CHR$(I1I)

MCmicrocomputer n, 89 - ottobre 1989 249

Page 7: SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ... Linguaggio Macchina (come risulta dal- ... re è dotato di registri: quelli del 68000 (lasciando

SOFTWAREAMIGA

Figura 11 dat • GPCT_RELJOYSTICK; /* Tanto per fare un esempio ./myreq->io_Data = (APTR)&dat;myreq->io_Length = 1;myreq->io_Command = IND_SETMTYPE;DoIO(myreq);

Controller Valore TipoGPCT_NOCONTROLLERGPCT_MOUSEGPCT _RELJOYSTI CKGPCT_ABSJOYSTICK

i/Il23

Nessun controller (blocca tutto')Mouse (default)Joystick relativoJoystick assoluto

struct GamePortTrigger mytrigger;myreq->io_Data = (APTR)&mytrigger;myreq->io_Length • sizeof(struct GamePortTrigger);myreq->lo_Command • IND_SETMTRIG;DolO(myreq);

Figura lO Figura 12

LoadEvents "< (nome del file)

SaveEvents > (nome del file)

mentre il secondo si lancia con

ConclusioniIl «programma che molto mi aveva

fatto penare» è un demo della input.de-vice scritto da Rob Peck della Commo-dore-Amiga Inc., che si limitava a ripor-tare dati sugli eventi in corso. La «pe-na» derivava dall'istruzione L1NK (solotroppo tardi scoperta). i cui malefici ef-fetti si fecero sentire per circa un me-se ... fino alla stoica decisione: «Lo ri-scrivo in Assembly, tie'!!» .

In conclusione, vi presento due pro-grammi in Assembly regolarmentecommentati che, rispettivamente, salva-no e riprendono su/da un file tutto quel-lo che fate con la tastiera e/o colmouse: il primo ha la sintassi

struct Interrupt Handlerlnt;

gpLKeys specifica la sensibilità ai ta-sti: specificando solo 1 (GPD_DOWN-KEYS). verrà riportata la sola pressionedei microswitch; se aggiungiamo 2 (GP-D_UPKEYS) verrà riportato anche il lororilascio; ovviamente, settando soloGPD_UPKEYS riceveremo solo informa-zioni sul rilascio dei microswitch.gpL Timeout è il numero di Ticks (cin-quantesimi di secondo) che devono tra-scorrere tra un evento e l'altro perchésiano considerati diversi. Infine,gpLXDelta e gpL YDelta non so propriocosa siano, anche perché sembra nonservano proprio a niente ... Ciò nono-stante, è bene settarli entrambi al.

La procedura è (sic!) sempre uguale(vedi figura 12).

Possiamo spedire un evento (chepasserà regolarmente la catena degliHandler) con il comando IND_WRITEE-VENT:

myreq->io_Data • (APTR)&Handlerlnt;myreq->io_Command • IND_REMHANDLER;DoIO(myreq) ;

struct GamePortTrigger (UVXlRD gpt_Keys;UVXlRD gpt_Timeout;UVXlRD gpt_XDelta;UVXlRD gpt_YDelta;

struct lnputEvent myevent;

direzione della leva (senza far muovereil pointer, se non di un solo pixel [i]),mentre il joystick relativo sposta effetti-vamente il cursore nella direzione in cuimuoviamo la leva. AI solito, la procedu-ra è rappresentata in figura 11.

Ma le possibilità di driving non termi-nano qui: potete decidere quali eventiprendere in considerazione e in qualemodo: a questo scopo potete setta re ilTrigger, il quale è siffatto:..•..

Il programma SaveEvents salva primail timeval del primo evento (che vadunque perso). poi gli altri eventi (18byte per evento).

Per esigenze ... didattiche (aridaje!) hotralasciato alcuni particolari necessari inun programma curato (se ne vedonomolti di questo genere in giro) l'impor-tante è capirsi.

Tra i principali difetti annovero il salva-re il solo primo evento di una catena, ilnon considerare la posizione iniziale delmouse e il non bloccare gli eventi perproporre quelli registrati, insieme a tan-te altre cosucce che sarebbero stateutili ... e che non ci sono.

Comunque il palinsesto è vali-do e le modifiche non sarebberodifficili: in effetti il mio unico sco-

myreq->io_Data • (APTR)&myevent; po è quello di dimostrare l'usomyreq- >io_Length = sizeof (struct lnputEvent); del device, tutto qui.myreq->lo_Command • IND_WRI TEEVENT;DolO(myreq); Consiglio di salvare gli eventi in

RAM: per renderne più veloce la gestio-ne In fase di caricamento. Particolar-mente interessante (se non altro per laquantità di tempo speso a farla funzio-nare) è, secondo me, la parte delLoadEvents che calcola il tempo di atte-sa tra un evento e l'altro: solo setteistruzioni (potenza del 68000!). Me

Infine, ci togliamo dalle scatole (par-don!) 1'lnputHandler sistemato:..•..

Gli altri comandiQuasi dimenticavo gli altri comandi ...

Dunque, potete cambiare driver per ilvostro mouse. Anzitutto, per cambiareporta (giochi), potete dare questo:..•..

prevista per un listato C da un program-ma in Assembly. Anzitutto, gli argomen-ti vengono passati sullo stack, sottoforma di dati a 32 bit depositati su diesso in ordine inverso alla lettura (cioèdall'ultimo al primo); dunque, si chiamala funzione. Un valore eventualmenteritornato dalla funzione viene da questapassato in DO. Mi spiego con il solitoesempio (vedi figura 9).

Con la MOVE.L #0, -(SP) trasferiamosullo stack il secondo argomento (i flagdel port). mentre, con la PEA portName,trasferiamo sullo stack (sempre là!) l'in-dirizzo effettivo del nome del port (l'i-struzione PEA [Push Effective Addressl.analogamente alla LEA, forma un indiriz-zo e lo deposita sullo stack). Infine,chiamiamo la CreatePort e depositiamol'indirizzo del port in PortAddress (unalocazione dell'area dati del programma).Ecco perché, nella _Handlerlnterface dicui sopra, il DO non viene memorizzato:esso vale come ritorno per l'I nput-Handler.

Noterete anche che, dopo la chiama-ta a CreatePort, abbiamo «aggiustato»lo stack: questo perché una routine in Cnon preleva i dati dallo stack in modousuale, ma «delicatamente», senza va-riare lo Stack Pointer (SP).

Conseguentemente, alla fine bisognaaggiungere tante volte 4 quanti argo-menti abbiamo passato (nel caso di cuisopra 2*4 = 8).

Oppure potete cambiare controller:se date uno sguardo al file INCLUDE<devices/gameport.h>, troverete i tipidi controller rappresentati in figura 10.

Il joystick assoluto registra solo· la

dat * 1; /* Porta 2 (sinistra sul 50~) */myreq->io_Data • (APTR)&dat;myreq->io_Length = 1;myreq->io_Command = IND_SETMPORT;DoIO(myreq);

UBYTE dat;

250 MCmicrocomputer n. 89 - ottobre 1989

Page 8: SOFTVVAR~/M~dTI]}Jl~® cura di Andrea de Prisco · ne in Assembly. Per acquisire questa ... Linguaggio Macchina (come risulta dal- ... re è dotato di registri: quelli del 68000 (lasciando

Adaptec: le nuove prestazionidi una multiutenza intelligente

Da Contradata le soluzioni multiuserper il bus AT e Microchannel

con qualsiasi soluzione ESDI.

La multiutenza veloceè quella intelligente

In condizioni di multiutenza con gliattuali AT 286/386, spesso accade che iltraffico dati tra CPU e periferia sia moltocongestionato. In tal caso, perfino isistemi operativi più evoluti, comeXENIX e UNIX, non riescono adesprimere tutta la loro potenzialevelocità.

Per eliminare questo classico "collo dibottiglia" tra CPU e Hard Disk, Adaptec

ha appositamente••• progettato una

'1'~1iiiI ..,__ serieW • .-!II> ~-_. .;'~ ..

.&\ ••••• ~." •• ~ •• ~ ••

'""•....~ -~~~~~~completa 2!!!>!1. I!I ••• ~~.:':'.. -.di Host Adapter per ee.;,i bus AT e Microchannel,nati per supportare HDD e FDD conprotocollo SCSI in ambiente multiuser.

La loro capacità di gestire piùcomandi contemporaneamente, consentedi liberare, con tecnica Mailbox in DMA,la CPU dalla gestione di tutte leoperazioni di Input/Output, assegnandoall'Host Adapter il compito di smaltire iltrasferimento dati alle periferiche.

In ambiente UNIX e XENIX, lavelocità e l'efficacia del sistema cresconoin modo considerevole se confrontate

Adattabilità immediata a tuttii sistemi operativi multiutenza

I principali standard di multiutenza,tra cui:

SCO XENIX 2.3 GT (286) per ATSCO XENIX 2.4 (386) per AT

- SCO XENIX 286 PS/386 PS perMicrochannelISC UNIX (386/IX release 2.0 e sup.)

- MICROPORT UNIX S,supportano in modo nativo gli HostAdapter Adaptec.

Multiutenza più efficienteanche per NOVELL

Adaptec ha realizzato un driversoftware per NOVELL 2.12 (esclusoELS2) e 2.15 per bus AT eMicrochannel: da oggi anche questostandard cosÌ evoluto potrà godere dellegrandi prestazioni assicurate dalla perfettaintegrazione HW/SW firmata Adaptec.

Per ulteriori informazioni sui prodotti distribuiti daContradata, telefonate allo 039/737015 o scrivete aContradata srl, Via Monte Bianco, 4 - 20052 Monza (MI)telex 352830 CONTRA I - fax 039/735276 G3.

~-~ --- contradataPER COMPUTER CHE NON HANNO TEMPO DA PERDERE