|
Appunti informatica |
|
Visite: 1622 | Gradito: | [ Medio appunti ] |
Leggi anche appunti:Problemi di cooperazione nel modello a memoria comuneProblemi di cooperazione nel modello a memoria comune III) Scrivere un'applicazione I modelli di memoriaI modelli di memoria L'architettura hardware dei processori Intel 80x86, Scrivere funzioni di libreriaScrivere funzioni di libreria La scrittura di un programma C implica sempre |
Possiamo almeno tentare di evitare la sostituzione fisica, dal momento che qui si tratta di eliminare un problema spesso fastidioso: nessuna tastiera è configurata per gestire tutti i caratteri di cui si può avere necessità e pertanto, più o meno spesso, si è costretti a ricorrere alle scomode sequenze ALT+nnn sul tastierino numerico.
Il programma presentato in queste pagine è in grado di assegnare ai tasti nuovi scan code e ascii code, in sostituzione o in aggiunta a quelli standard. Nella maggior parte dei casi sperimentati, KBDPLUS si è rivelato di grande utilità per aggiungere le parentesi graffe e la tilde, care ai programmatori C, alle tastiere italiane e le lettere accentate alle tastiere americane; in un caso ha egregiamente trasformato in tedesca una normale tastiera italiana.
La tabella di ridefinizione dei tasti è contenuta in un normale file ASCII, ed è pertanto riconfigurabile a piacere. La sintassi della tabella è semplice: ogni riga del file ASCII rappresenta una ridefinizione di tasto e deve essere strutturata come descritto di seguito.
spazi shifts spazi scan spazi nuovo_scan spazi ascii spazi commento
spazi |
uno o più spazi o tabulazioni. Possono anche non essere presenti. |
shifts |
uno dei seguenti caratteri o una loro combinazione (senza spazi tra un carattere e l'altro): A ALT C CTRL L LEFT SHIFT R RIGHT SHIFT N Nessuno shift Lo shift N è ignorato se non e' il solo presente. |
spazi |
uno o più spazi o tabulazioni. |
scan |
scan code del tasto da ridefinire (2 cifre esadecimali). |
spazi |
uno o più spazi o tabulazioni. |
nuovo_scan |
nuovo scan code per il tasto (2 cifre esadecimali). Può essere uguale a SCAN. |
spazi |
uno o più spazi o tabulazioni. |
ascii |
ASCII code per il tasto (2 cifre esadecimali). |
spazi |
uno o più spazi o tabulazioni. |
commento |
è opzionale e non ha formato particolare. |
Si noti che utilizzando un comune editor per scrivere il file, una coppia CR LF è aggiunta al termine di ogni riga quando è premuto il tasto RETURN. La lunghezza della riga, CR_LF compreso, non può superare gli 80 caratteri. Ecco un esempio di riga valida, che ridefinisce la combinazione CTRL ALT ESC come ENTER
CA 01 1C 0D - Il tasto ESC, premuto con CTRL e ALT, equivale a ENTER.
Gli shift sono indicati all'inizio della riga: CA significa CTRL ALT. Uno spazio separa gli shift dallo scan code del tasto: è il tasto ESC. Il nuovo scan code (cioè lo scan code che viene inserito nel buffer di tastiera alla pressione di CTRL ALT ESC 1C (lo scan code del tasto RETURN). Il nuovo codice ASCII da inserire nel buffer è 0D, corrispondente anch'esso al tasto RETURN. Tutto ciò che segue 0D, sino alla fine della riga, rappresenta un commento ed è ignorato dal programma.
KBDPLUS è un programma TSR, che viene installato fornendogli come parametro (sulla command line) il nome del file contenente le ridefinizioni dei tasti; la command line è scandita a partire dall'ultimo parametro ed ognuno di essi (se ve n'è più di uno) è considerato un nome di file. Se il tentativo di apertura fallisce il processo è ripetuto con il parametro che lo precede; se nessun parametro è un nome di file esistente o non vi sono parametri, KBDPLUS cerca, nella directory in cui esso stesso si trova, il file KBDPLUS.DEF . Se anche questo tentativo fallisce, il programma non si installa e visualizza un testo di aiuto.
KBDPLUS accetta inoltre, dalla command line, due parametri particolari: il carattere ' ', che provoca la visualizzazione del testo di help senza tentativo di installazione , e il carattere ' ', che provoca la disinstallazione del programma (se già installato) e il ripristino delle funzionalità originali della tastiera
KBDPLUS è in grado di individuare se stesso in RAM ed evita quindi installazioni multiple.
Segue il listato.
KBDPLUS.C - KBDPLUS - Barninga_Z! 1991
Ridefinitore di tastiera.
Modalita' di funzionamento.
Legge un file in formato ASCII e in base al suo contenuto ridefinisce
la tastiera. Ogni riga del file deve essere lunga al massimo 80 caratteri
ed e' strutturata come segue:
shf spc scc spc nsc spc asc spc commento crlf
dove:
spc.uno o piu' blanks o tabs. Possono anche essere presenti
prima di shifts; in tal caso saranno ignorati.
shf.uno dei seguenti caratteri o una loro combinazione (senza
spazi tra un carattere e l'altro):
A ALT
C CTRL
L LEFT SHIFT
R RIGHT SHIFT
N Nessuno shift (ignorato se non e' il solo presente).
scc.scan code in esadecimale (2 cifre) del tasto da
ridefinire.
nsc.nuovo scan code in esadecimale (2 cifre) per il tasto.
Puo' essere uguale a scancode.
asc.codice ascii in esadecimale (2 cifre) per il tasto.
commento..e' opzionale e non ha formato particolare.
crlfsequenza CR LF che chiude ogni riga di testo.
Esempio di riga che ridefinisce CTRL ALT ESC:
CA 01 1C 0D - Il tasto ESC, premuto con CTRL e ALT, equivale a ENTER.
KBDPLUS accetta, alternativamente al nome di file, due parametri:
KBDPLUS ? produce la visualizzazione di uno schermo di aiuto;
KBDPLUS * provoca la disinstallazione del programma (purche'
esso sia gia' presente in RAM).
Compilato sotto BORLAND C++ 2.0:
tcc -O -d -rd -k- -Tm2 kbdplus.C
#pragma inline
#pragma warn -pia
#pragma option -k- /* attenzione: non serve la std stack frame */
#include <dos.h>
#include <stdio.h>
#include <string.h>
#define PRG 'KBDPLUS' /* nome del programma */
#define YEAR '1991' /* anno */
#define PSPENVOFF 0x2C /* offset, nel PSP, del ptr all'environment */
#define ALT_V ((char)8)
#define CTRL_V ((char)4)
#define LSHF_V ((char)2)
#define RSHF_V ((char)1)
#define NONE_V ((char)0)
#define ALT_C 'A'
#define CTRL_C 'C'
#define LSHF_C 'L'
#define RSHF_C 'R'
#define NONE_C 'N'
#define SHFMASK 0x0F /* shift status mask (elimina NumLock, etc.) */
#define INKEYPORT 0x60 /* porta di input della tastiera */
#define CTRKEYPORT 0x61 /* porta di controllo della tastiera */
#define ENABLEKBBIT 0x80 /* bit di abilitazione della tastiera */
#define E_O_I 0x20 /* segnale di fine interrupt */
#define I_CTRPORT 0x20 /* porta di controllo degli interrupt */
#define KBDOFF 0x3FE /* off di seg implicito nei puntatori - 2 */
#define MAXLEN 83 /* n. max di carat. in ogni riga del file dati */
#define BLANK ' ' /* spazio bianco (ascii 32) */
#define ARRDIM 360 /* dimensione della func-array Dummy() (90*4)*/
#define TSR_TEST 0xAD /* HANDSHAKE per TSR */
#define TSR_YES 0xEDAF /* se installato risponde cosi' al test */
#define TSR_INST 0x00 /* serv. 0 int 2Fh. Testa se installato */
#define TSR_FREE 0x01 /* serv. 1 int 2Fh. Disinstalla il TSR */
#define DEFEXT '.DEF' /* il file di default e' KBDPLUS.DEF */
#define HELP_REQUEST '?' /* opzione cmd line per richiedere help */
#define FREE_REQUEST '*' /* opzione cmd line per disinstall. TSR */
#define int09h ((void(interrupt *)())*(((long *)Dummy)+0)) /* off 0 */
#define int2Fh ((void(interrupt *)())*(((long *)Dummy)+1)) /* off 4 */
#define ShiftFlag (*((char far *)*(((int *)Dummy)+4))) /* offset 8 */
#define HeadPtr (*((int far *)*(((int *)Dummy)+5))) /* offset 10 */
#define TailPtr (*((int far *)*(((int *)Dummy)+6))) /* offset 12 */
#define StartPtr (*((int far *)*(((int *)Dummy)+7))) /* offset 14 */
#define EndPtr (*((int far *)*(((int *)Dummy)+8))) /* offset 16 */
#define nk (*(((int *)Dummy)+9)) /* offset 18 */
#define ResPSP (*(((unsigned *)Dummy)+10)) /* offset 20 */
#define keys (((struct KbDef far *)Dummy)+6) /* offset 24 */
#define int09h_asm Dummy /* usata nell'inline assembly */
#define int2Fh_asm Dummy+4 /* usata nell'inline assembly */
#define ResPSP_asm Dummy+20 /* usata nell'inline assembly */
extern unsigned cdecl _heaplen = 8000; /* riduce ingombro al caricamento */
struct KbDef ;
struct ShfFlag shf[] = ,
,
,
,
/* NONE deve essere l'ultimo item (ultimo .kv = 0) */
void Dummy(void); /* necessaria per JMP in newint09h() e newint16h() */
void far newint09h(void) /* handler int 09h */
for(i = 0; i < nk; i++)
_CH = keys[i].nwscn;
_CL = keys[i].nwasc;
*((int far *)((TailPtr)+KBDOFF)) = _CX; /* tasto --> buf */
if(TailPtr == EndPtr) /* se è in fondo al buffer */
TailPtr = StartPtr; /* aggiorna i puntatori */
asm
}
}
}
asm
_EXIT:
asm
void far newint2Fh(void) /* gestore dell'int 2Fh */
_FREETSR:
asm
_CHAIN:
asm jmp dword ptr int2Fh_asm; /* concatena gestore originale */
void Dummy(void) /* spazio dati globali e strutture KbDef */
char *hlpmsg = 'n
Type 'PRG' ? for help; 'PRG' * to uninstall.n
DATA FILE DESCRIPTION (if no name given, 'PRG' tries for 'PRG''DEFEXT'):n
Each line in the file redefines a key and has the following format:n
n
shifts spaces scan spaces newscan spaces ascii spaces comment crlfn
n
spacesone or more blanks (or tabs).n
shiftsthe combination of shift keys: one or more of the following:n
A (the ALT key)n
C (the CTRL key)n
L (the LEFT SHIFT key)n
R (the RIGHT SHIFT key)n
N (no shift has to be pressed with the redefined key)n
scan..the hex scan code of the redefined key.n
newscan..the new hex scan code for the redefined key. Can be = <scan>.n
ascii.the hex ASCII code of the char for the redefined key.n
comment..optional entry; useful to scribble some remarks.n
crlf..a CR LF seq. (End-of-line; max 80 chrs).n
n
CA 01 1C 0D Example that makes CTRL ALT ESC same as the ENTER key.
/* stringa di help */
void release_env(void) /* libera environment del TSR */
int nibble(char c) /* 2 hex digit string ===> int */
char *setcodes(char *bufptr,char far *code) /* legge i codici dal file */
void readdata(FILE *in) /* legge i codici e prepara tabella in memoria */
int readfile(int argc,char **argv) /* apre e chiude il file */
else
printf(PRG': %s not found.n',argv[argc]);
return(nk);
int resparas(void) /* calcola paragrafi residenti indispensabili */
int tsrtest(void) /* controlla se gia' residente */
_RESIDENT:
return(_AX);
void uninstall(void) /* disinstalla KBDPLUS residente */
setvect(0x09,(void(interrupt *)())(*((long far *)ResDataPtr)));
setvect(0x2F,(void(interrupt *)())(*(((long far *)ResDataPtr)+1)));
_ES = *(((unsigned far *)ResDataPtr)+10);
asm
void install(void) /* installa TSR KBDPLUS */
void main(int argc,char **argv)
else
printf(PRG': Already installed.n%s',hlpmsg);
else
if(readfile(argc,argv))
install();
else
printf(PRG': Invalid data file name or lines.n%s',hlpmsg);
Il programma installa i gestori dell'int 09h e dell'int 2Fh. L'int 2Fh ha il compito di determinare se KBDPLUS è già presente in memoria e collabora alla disintallazione: esso controlla se in ingresso AH contiene il valore della costante manifesta TSR_TEST, nel qual caso valuta AL. Se questo contiene TSR_INST (il valore è come suggerito da Microsoft) la routine restituisce in AX il valore TSR_YES, riconosciuto da tsrtest()
Se invece AL contiene TSR_FREE, il gestore dell'int 2Fh restituisce a uninstall() l'indirizzo far della Dummy() residente: uninstall() può così ripristinare i vettori e liberare la RAM allocata al PSP del codice residente.
Se AL contiene un altro valore, il gestore concatena l'int 2Fh originale.
Se KBDPLUS non è residente, main() invoca readfile(), che costruisce il nome di default per il file dati sostituendo all'estensione del nome del programma (ricavato da argv[0]) la stringa DEFEXT '.DEF') e tenta, comunque, di aprire tutti i file i cui nomi sono specificati sulla command line, a partire dall'ultimo (ogni parametro è interpretato come nome di file). Se nessuno di essi esiste o non sono stati passati parametri viene aperto il file di default. Se neppure questo esiste KBDPLUS visualizza il testo di help e termina.
Se invece un file è stato trovato ed aperto, vengono lette in memoria, una ad una, le righe che lo compongono (o, al massimo, tante righe quante sono le ridefinizioni consentite ). La decodifica di ogni riga avviene non appena questa è letta, per evitare di allocare un buffer in grado di contenere tutto il file. Sono scartati gli spazi eventualmente presenti ad inizio riga; tutti i caratteri rappresentanti gli shift sono considerati un'unica sequenza interrotta dal primo blank; gli scan code e il codice ascii sono interpretati come numeri di due cifre esadecimali e convertiti in int da nibble(), in luogo della quale sarebbe possibile utilizzare sscanf(), analoga alla fscanf() descritta a pag.
I dati decodificati sono scritti nella tabella alla quale Dummy() riserva spazio. La Dummy(), funzione fittizia (vedere pag. ), contiene anche tutti i dati globali; il suo nome (che è in pratica il puntatore alla funzione) viene all'occorrenza forzato a puntatore ai vari tipi di dato in essa contenuti: alcune macro consentono di 'nascondere' dietro a pseudo‑nomi di variabili le indirezioni e i cast necessari, a volte complessi.
Lo stratagemma attuato con la Dummy() consente di lasciare residente in RAM solo ciò che è indispensabile: newint09h() newint16h() e i dati globali (di questi, l'array che contiene le ridefinizioni è l'ultimo, per poterne troncare la parte non utilizzata). In tal modo la funzione resparas() può calcolare quanti paragrafi devono essere residenti basandosi sulla differenza tra l'indirizzo della tabella e quello del PSP, alla quale va sommato lo spazio occupato dalle ridefinizioni dei tasti (il tutto arrotondato per eccesso).
I gestori newint09h() e newint2Fh() sono dichiarati far e non interrupt: ciò consente di evitare inutili salvataggi automatici di registri non utilizzati e semplifica, nel caso di newint2Fh(), la restituzione di un valore alla routine chiamante (vedere pag. e seguenti). Nella newint09h() la variabile i non può essere dichiarata register: ne risulterebbe complicata la gestione dello stack (se DI e SI sono referenziati nella funzione il compilatore li spinge sullo stack in entrata); di qui l'utilizzo dell'opzione ‑rd in compilazione.
Quando KBDPLUS è residente, newint09h() è attivata ad ogni pressione o rilascio di tasto: viene scandita la tabella delle ridefinizioni alla ricerca di una combinazione di shift e scan code corrispondenti a quella rilevata sulla tastiera. Se la ricerca ha successo, il nuovo codice ASCII e il nuovo scan code sono inseriti nel buffer della tastiera (con conseguente aggiornamento del puntatore alla coda del buffer ) e vengono resettati la tastiera e il controllore degli interrupt. In caso contrario, o se il buffer della tastiera è pieno, viene concatenato l'int 09h originale.
Segue il listato di una versione leggermente più sofisticata del programma KBDPLUS; si tratta di una successiva release, che rimuove uno dei principali limiti della versione appena presentata: l'incapacità di distinguere tra loro i due ALT (ALT sinistro e ALT‑GR) ed i due CTRL (sinistro e destro) presenti sulla tastiera. Le modifiche al listato sono minime: compaiono le definizioni delle costanti manifeste ALTGR_V e CTRLR_V (maschere dei bit di shift), nonché ALTGR_C e CTRLR_C (caratteri da utilizzare per ridefinire un tasto mediante ALT‑GR e CTRL destro). Ne risulta, ovviamente, ampliato l'array shf di strutture ShfFlag. Il riconoscimento del tasto ALT‑GR è effettuato nella newint09h() mediante un controllo basato sul Keyboard Status Byte (pag. ), che si trova all'indirizzo (nuova costante manifesta KBSTBYTE
KBDPLUS2.C - KBDPLUS 2.5 - Barninga_Z! 14-06-93
Ridefinitore di tastiera.
Modalita' di funzionamento.
Legge un file in formato ASCII e in base al suo contenuto ridefinisce
la tastiera. Ogni riga del file deve essere lunga max. 80 caratteri
ed e' strutturata come segue:
shf spc scc spc nsc spc asc spc commento crlf
dove:
spc.uno o piu' blanks o tabs. Possono anche essere presenti
prima di shifts; in tal caso saranno ignorati.
shf.uno dei seguenti caratteri o una loro combinazione (senza
spazi tra un carattere e l'altro):
A ALT
G ALT GR
C CTRL
T CTRL RIGHT
L LEFT SHIFT
R RIGHT SHIFT
N Nessuno shift (ignorato se non e' il solo presente).
scc.scan code in esadecimale (2 cifre) del tasto da ridefinire.
nsc.nuovo scan code in esadecimale (2 cifre) per il tasto. Puo'
essere uguale a scancode.
asc.codice ascii in esadecimale (2 cifre) per il tasto.
commento..e' opzionale e non ha formato particolare.
crlfsequenza CR LF che chiude ogni riga di testo.
Esempio di riga che ridefinisce CTRL ALT ESC:
CA 01 1C 0D - Il tasto ESC, premuto con CTRL e ALT, equivale a ENTER.
Se gia' presente in RAM, KBDPLUS si riconosce e non si installa una
seconda volta.
KBDPLUS2 accetta, alternativamente al nome di file, due parametri:
?: KBDPLUS2 ? produce la visualizzazione di uno schermo di aiuto;
*: KBDPLUS2 * provoca la disinstallazione del programma (purche' esso
sia gia' presente in RAM).
Compilato sotto TURBO C++ 3.1:
tcc -O -d -rd -k- -Tm2 kbdplus2.c
#pragma inline
#pragma warn -pia
#pragma option -k- // no std stack frame!! serve per assembly!
#include <dos.h>
#include <stdio.h>
#include <string.h>
#define PRG 'KBDPLUS2' /* nome del programma */
#define VER '2.5' /* release */
#define YEAR '1993' /* anno */
#define PSPENVOFF 0x2C /* offset, nel PSP, del ptr all'environment */
#define ALT_V ((int)520) // 512 + 8
#define ALTGR_V ((int)8) // gestito con kbd st. byte (0x496)
#define CTRL_V ((int)260) // 256 + 4
#define CTRLR_V ((int)4)
#define LSHF_V ((int)2)
#define RSHF_V ((int)1)
#define NONE_V ((int)0)
#define ALT_C 'A'
#define ALTGR_C 'G'
#define CTRL_C 'C'
#define CTRLR_C 'T'
#define LSHF_C 'L'
#define RSHF_C 'R'
#define NONE_C 'N'
#define SHFMASK 0x30F /* shift status mask per entrambi i bytes */
#define INKEYPORT 0x60 /* porta di input della tastiera */
#define CTRKEYPORT 0x61 /* porta di controllo della tastiera */
#define ENABLEKBBIT 0x80 /* bit di abilitazione della tastiera */
#define E_O_I 0x20 /* segnale di fine interrupt */
#define I_CTRPORT 0x20 /* porta di controllo degli interrupt */
#define KBSTBYTE 0x496 /* puntatore al keyboard status byte */
#define KBDOFF 0x3FE /* offset di seg implicito nei puntatori - 2 */
#define MAXLEN 83 /* n. max di carat. in ogni riga del file dati */
#define BLANK ' ' /* spazio bianco (ascii 32) */
#define ARRDIM 1280 /* dimensione della func-array Dummy() (256*5) */
#define TSR_TEST 0xAD /* HANDSHAKE per TSR */
#define TSR_YES 0xEDAF /* se instal., int 16 risponde cosi' al test */
#define TSR_INST 0x00 /* serv. 0 int 2Fh. Testa se installato */
#define TSR_FREE 0x01 /* serv. 1 int 2Fh. Disinstalla il TSR */
#define DEFEXT '.DEF' /* il file di default e' KBDPLUS.DEF */
#define HELP_REQUEST '?' /* opzione cmd line per richiedere help */
#define FREE_REQUEST '*' /* opzione cmd line per disinstall. TSR */
#define int09h ((void (interrupt *)())*(((long *)Dummy)+0)) /* offset 0 */
#define int2Fh ((void (interrupt *)())*(((long *)Dummy)+1)) /* offset 4 */
#define ShiftFlag (*((int far *)*(((int *)Dummy)+4))) /* offset 8 */
#define HeadPtr (*((int far *)*(((int *)Dummy)+5))) /* offset 10 */
#define TailPtr (*((int far *)*(((int *)Dummy)+6))) /* offset 12 */
#define StartPtr (*((int far *)*(((int *)Dummy)+7))) /* offset 14 */
#define EndPtr (*((int far *)*(((int *)Dummy)+8))) /* offset 16 */
#define nk (*(((int *)Dummy)+9)) /* offset 18 */
#define ResPSP (*(((unsigned *)Dummy)+10)) /* offset 20 */
#define keys ((struct KbDef far *)DummyFkeys)
#define int09h_asm Dummy /* usata nell'inline assembly */
#define int2Fh_asm Dummy+4 /* usata nell'inline assembly */
#define ResPSP_asm Dummy+20 /* usata nell'inline assembly */
extern unsigned cdecl _heaplen = 8000;
struct KbDef ;
struct ShfFlag shf[] = ,
, // aggiunta 14-06-93
,
, // aggiunta 14-06-93
,
,
/* NONE deve essere l'ultimo item (ultimo .kv = 0) */
void Dummy(void); /* necessaria per newint09h() e newint16h() */
void DummyFkeys(void); /* necessaria per newint09h() e newint16h() */
void far newint09h(void)
for(_SI = 0; _SI < nk; _SI++)
_CH = keys[_SI].nwscn;
_CL = keys[_SI].nwasc;
*((int far *)((TailPtr)+KBDOFF)) = _CX;
if(TailPtr == EndPtr)
TailPtr = StartPtr;
asm
}
}
}
asm
_EXIT:
asm
void far newint2Fh(void)
_FREETSR:
asm
_CHAIN:
asm jmp dword ptr int2Fh_asm; /* concatena gestore originale */
void Dummy(void) /* spazio dati globali e strutture KbDef */
void DummyFkeys(void)
char *hlpmsg = 'n
Type KBDPLUS ? for help; KBDPLUS * to uninstall.n
DATA FILE DESCRIPTION (if no name given, 'PRG' searches for 'PRG''DEFEXT'):n
Each line in the file redefines a key and has the following format:n
n
shifts spaces scan spaces newscan spaces ascii spaces commentn
n
spacesone or more blanks (or tabs).n
shiftsthe combination of shift keys: one or more of the following:n
A (the ALT key)n
G (the ALT GR key)n
C (the LEFT CTRL key)n
T (the RIGHT CTRL key)n
L (the LEFT SHIFT key)n
R (the RIGHT SHIFT key)n
N (no shift has to be pressed with the redefined key)n
scan..the hex scan code of the redefined key.n
newscan..the new hex scan code for the redefined key. It can be = <scan>.n
ascii.the hex ASCII code of the char for the redefined key.n
comment..optional entry; useful to scribble some remarks.n
n
CA 01 1C 0D Example that makes CTRL ALT ESC equivalent to the ENTER key.';
void release_env(void)
int nibble(char c) /* hex digit string ===> int */
char *setcodes(char *bufptr,char far *code)
void readdata(FILE *in)
int readfile(int argc,char **argv)
else
(void)printf(PRG': %s not found.n',argv[argc]);
return(nk);
int resparas(void)
int tsrtest(void)
_RESIDENT:
return(_AX);
void uninstall(void)
setvect(0x09,(void(interrupt *)())(*((long far *)ResDataPtr)));
setvect(0x2F,(void(interrupt *)())(*(((long far *)ResDataPtr)+1)));
_ES = *(((unsigned far *)ResDataPtr)+10);
asm
void install(void)
void main(int argc,char **argv)
else
(void)printf(PRG': Already installed.n%s',hlpmsg);
else
if(readfile(argc,argv))
install();
else
(void)printf(PRG': Invalid data file name or lines.n%s',hlpmsg);
Sono state introdotte anche alcune modifiche volte ad incrementare l'efficienza complessiva del programma: in particolare, nella newint09h() il ciclo di scansione della tabella dei tasti ridefiniti è gestito esplicitamente mediante il registro SI (nella precedente versione era utilizzata una variabile automatica allocata nello stack). Detta tabella, infine, è stata scorporata dalla funzione jolly Dummy() e lo spazio ad essa necessario è ora riservato mediante una seconda funzione fittizia, la dummyFkeys(); è stata inoltre coerentemente modificata la definizione della costante manifesta keys
A corredo di KBDPLUS presentiamo un semplice programma in grado di visualizzare, nei formati decimale ed esadecimale, lo scan code ed il codice ASCII di ogni tasto premuto. KBDCODES può risultare utile nella preparazione della tabella di ridefinizioni da utilizzare con KBDPLUS
KBDCODES.C - Barninga_Z! - 1991
Visualizza scan code e ascii code del tasto premuto. Per uscire
basta premere ESC due volte di seguito.
Compilato sotto BORLAND C++ 2.0
tcc -O -d -mt -lt kbdcodes.c
#include <stdio.h>
#define ESC ((char)0x1B)
#define NORMAL ((char)0x00)
#define EXTENDED ((char)0x10)
#define NORMOPT '-'
#define EXTOPT '+'
#define YRLIMIT ((char)0x05)
#define YRADDR ((char far *)0xF000FFFCL)
char *msg[] =;
void main(int argc,char **argv)
if(argc > 1)
if(*argv[1] == NORMOPT)
else
if(*argv[1] == EXTOPT)
printf(msg[0],msg[count]);
for(count = 0; ; count < 2)
KBDCODES si basa sull'int 16h, di cui invoca il servizio 10h (tastiera estesa) se il bios della macchina è datato 1986 o piu' recente, altrimenti usa il servizio 00h. E' possibile forzare l'uso del servizio 10h invocando il programma con il parametro ' ' sulla command line; il parametro ' ', al contrario, forza l'utilizzo del servizio 00h. Per uscire dal programma è sufficiente premere il tasto ESC due volte consecutive oppure la sequenza CTRL‑BREAK
Ogni tasto può essere ridefinito più volte (ad ogni ridefinizione corrisponde una riga della tabella): in tal modo si ha la possibilità di associare ad ogni tasto più caratteri, ciascuno dei quali in corrispondenza di una certa combinazione di shift.
Appunti su: |
|