home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
dirs
/
waitanykey_437.lzh
/
WaitAnyKey
/
WaitAnyKey.ass
< prev
next >
Wrap
Text File
|
1991-01-16
|
15KB
|
467 lines
;
;
;
; WaitAnyKey V1.00
;
;
;
;
; Copyright 1990 Roger Fischlin
; Steigerwaldweg 6
; D-6450 Hanau 7
; Germany
;
;
;
;
; This program is FREEWARE. It's still copyrighted by the author.
;
;
; This program can be freely distributed if :
; 1. the name of the author and the copyright remark remain
; unchanged.
; 2. you don't gain any profit by distributing it !
;
;
;
; This program ist PC relative and 100 % PURE (set P flag) !
;
incdir "ram:include/"
include "exec/exec_lib.i"
include "exec/memory.i"
include "libraries/dos.i"
include "libraries/dos_lib.i"
include "libraries/dosextens.i"
IFND DOSTRUE
DOSTRUE equ -1
ENDC
IFND DOSFALSE
DOSFALSE equ 0
ENDC
;
; Macro
;
DOS macro ; der alte Macro muß ersetzt
move.l a5,a6 ; werden, da ja die DOS-Library-Base
jsr _LVO\1(a6) ; an anderer Stelle (a5) vermerkt ist.
endm
;
; DOS-Library öffnen
;
_main lea.l DosName(pc),a1 ; DOS-Library
moveq.l #33,d0 ; ab Kickstart 1.2
CALLEXEC OpenLibrary ; öffnen
move.l d0,a5
tst.l d0
beq.s .Error ; Fehler !
bsr MAIN ; Hauptprogramm ausführen
move.l d0,-(sp)
move.l a5,a1 ; DOS-Library wieder schließen
CALLEXEC CloseLibrary
move.l (sp)+,d0
rts
.Error moveq.l #20,d0
rts
DosName DOSNAME
;
; Hauptprogramm
;
MAIN move.l #DOSTRUE,d0
bsr GoRAW ; CON in RAW-Modus umwandeln
.Loop DOS Input
subq.l #2,sp ; Puffer (2 Byte) anlegen
move.l d0,d1
move.l sp,d2
moveq.l #1,d3
DOS Read ; 1 Zeichen lesen (=auf ein Tastendruck warten)
addq.l #2,sp ; Stack wieder korrigieren
DOS Input
move.l d0,d1
moveq.l #1,d2 ; noch weitere Zeichen im Puffer ?
DOS WaitForChar
tst.l d0
bne.s .Loop ; gegebenenfalls weitere Zeichen auslesen
; sonst stören sie bei der späteren Eingabe
move.l #DOSFALSE,d0
bsr GoRAW ; zurück in CON-Modus
moveq.l #0,d0
rts
;
; GoRAW
;
; Enthält D0 DOSTRUE (-1) ,versetzt GoRAW die Console in den RAW-
; Modus bei DOSFALSE (0) hingen versetzt GoRAW die Console zurück
; in den CON-Modus. Bei einem Fehler ist d0 0.
;
IFND ACTION_SCREEN_MODE
ACTION_SCREEN_MODE equ 994
ENDC
GoRAW movem.l d7/a2-a5,-(sp) ; Register retten
move.l d0,d7 ; Modus retten
sub.l a1,a1
CALLEXEC FindTask ; Zeiger auf eigenen Task
move.l d0,a0
move.l pr_ConsoleTask(a0),a2 ; ID der zugehörigen Console
sub.l a0,a0 ; Reply-Port erzeugen
moveq.l #0,d0
bsr CreatePort
tst.l d0 ; Fehler ?
beq .Label1
move.l d0,a3 ; Zeiger auf Reply-Port retten
bsr CreatePacket ; StandardPacket erzeugen
tst.l d0 ; Fehler ?
beq.s .Label2
move.l d0,a4
move.l a3,sp_Pkt+dp_Port(a4) ; Reply-Port eintragen
move.l d7,sp_Pkt+dp_Arg1(a4) ; Modus eintragen
move.l #ACTION_SCREEN_MODE,sp_Pkt+dp_Type(a4)
move.l a4,a1 ; Zeiger auf Packet
move.l a2,a0 ; Zeiger auf Port
CALLEXEC PutMsg
.Label5 move.l a3,a0 ; auf Reply warten
CALLEXEC WaitPort
move.l a3,a0 ; Reply-Message holen
CALLEXEC GetMsg
tst.l d0 ; doch keine Message ?
beq.s .Label5
moveq.l #1,d0 ; kein Fehler
.Label3 move.l d0,-(sp)
move.l a4,a0
bsr DeletePacket ; Standard-Packet löschen
move.l (sp)+,d0
.Label2 move.l d0,-(sp)
move.l a3,a0
bsr DeletePort ; Reply-Port löschen
move.l (sp)+,d0
.Label1 movem.l (sp)+,d7/a2-a5
rts
;
; CreatePacket
;
; CreatePacket erzeugt ein StandardPacket,Message- und DosPacket-
; Teil werden verbunden. In d0/a0 wird er Zeiger zurückgeben,bzw.
; 0 bei einen Fehler.
;
CreatePacket moveq.l #sp_SIZEOF,d0 ; Speicher für StandardPacket reservieren
move.l #MEMF_PUBLIC!MEMF_CLEAR,d1
CALLEXEC AllocMem
tst.l d0
beq.s .Label1
move.l d0,a0
lea.l sp_Pkt(a0),a1 ; Zeiger auf Packet-Teil
move.l a1,sp_Msg+LN_NAME(a0) ; Node-Namen muß auf Packet-Teil zeigen
move.l a0,sp_Pkt+dp_Link(a0) ; DosPacket-Link muß auf Message-Teil zeigen
.Label1 rts
;
; DeletePacket
;
; DeletePacket löscht ein zuvor mit CreatePacket erzeugtes
; StandardPacket. Als Parameter wird in A0 der Zeiger auf das
; StandardPacket erwartet.
;
DeletePacket moveq.l #0,d0
cmp.l d0,a0 ; 0-Zeiger abfangen !
beq.s .NIL
move.l a0,a1
moveq.l #sp_SIZEOF,d0 ; Speicher freigeben
CALLEXEC FreeMem
.NIL rts
;
; CreatePort
;
; CreatePort erzeugt einen funktionsfähigen Msg-Port des Typs
; PA_SIGNAL mit der Priorität von D0.A0 zeigt auf den Port-Namen,
; der nicht kopiert wird. Falls A0 0 ist, wird er nicht in die
; Liste öffentlicher Ports aufgenommen. Als SigTask wird der
; eigene eingetragen. Der Funktionswert in D0 ist der Zeiger auf
; auf den Port oder bei einem Fehler 0 .
;
CreatePort move.l a2,-(sp)
movem.l d0/a0,-(sp) ; retten
moveq.l #MP_SIZE,d0 ; Speicher für Port reservieren
move.l #MEMF_PUBLIC!MEMF_CLEAR,d1
CALLEXEC AllocMem
tst.l d0
beq.s .NoMem
move.l d0,a2
moveq.l #-1,d0 ; Signal belegen
CALLEXEC AllocSignal
move.b d0,MP_SIGBIT(a2)
bmi.s .FreeMem ; kein Signal
movem.l (sp)+,d0/a0
move.b d0,MP+LN_PRI(a2) ; Priorität eintragen
move.b #NT_MSGPORT,LN_TYPE(a2)
move.l a0,MP+LN_NAME(a2) ; Name
sub.l a1,a1
CALLEXEC FindTask
move.l d0,MP_SIGTASK(a2) ; eigener Task als Signal-Empfänger
lea.l MP_MSGLIST(a2),a0
move.b #NT_MESSAGE,LH_TYPE(a0) ; Messages werden verwaltet
bsr NewList
tst.l MP+LN_NAME(a2) ; öffentlicher Port ?
beq.s .Private
move.l a2,a1
CALLEXEC AddPort ; Port in allgemeine Liste eintragen
.Private move.l a2,d0
move.l (sp)+,a2
rts
.FreeMem move.l a2,a1
moveq.l #MP_SIZE,d0 ; Speicher freigeben
CALLEXEC FreeMem
.NoMem addq.l #8,sp
move.l (sp)+,a2
moveq.l #0,d0 ; Fehler !
rts
;
; NewList
;
; NewList initialisiert eine LIST-Struktur, A0 muß auf die LIST-
; Struktur zeigen.
;
NewList move.l a0,LH_HEAD(a0) ; LH_HEAD muß auf LH_TAIL zeigen
addq.l #LH_TAIL,(a0)
clr.l LH_TAIL(a0) ; LH_TAIL muß auf 0 zeigen
move.l a0,LH_TAILPRED(a0)
rts
;
; DeletePort
;
; DeletePort löscht einen zuvor mit CreatePort erzeugten MsgPort.
; Als Parameter wird in A0 der Zeiger auf den Port erwartet.Noch
; ausstehende Messages werden zuvor reply-t.
;
DeletePort move.l a2,-(sp)
move.l a0,a2 ; Zeiger retten
CALLEXEC Forbid ; Multitasking unterbinden
.Loop move.l a2,a0
CALLEXEC GetMsg ; Msg holen
tst.l d0 ; keine (weitere) Message mehr
beq.s .AllReplied
move.l d0,a1
CALLEXEC ReplyMsg ; Message reply-en
bra.s .Loop
.AllReplied move.l MP+LN_NAME(a2),d0 ; öffentlicher Port ?
beq.s .Private
move.l a2,a1
CALLEXEC RemPort ; entfernen
.Private move.b MP_SIGBIT(a2),d0
CALLEXEC FreeSignal ; Signal freigeben
move.l a2,a1 ; Speicher freigeben
moveq.l #MP_SIZE,d0
CALLEXEC FreeMem
CALLEXEC Permit ; Multitasking wieder erlauben
move.l (sp)+,a2
rts
;
; CLIText
;
; CLIText gibt den mit einem $00-Byte abgeschlossen Text (Zeiger
; in A0) im CLI-Window aus.
;
CLIText movem.l d2/d3,-(sp) ; Register retten
move.l a0,d2 ; Zeiger nach D2
moveq.l #-1,d3 ; Länge ermitteln
.Label addq.l #1,d3
tst.b (a0)+
bne.s .Label
DOS Output ; Handle fürs CLI-Fenster
move.l d0,d1
DOS Write ; Text ausgeben
movem.l (sp)+,d2/d3
rts
;
; GetLong
;
; GetLong übersetzt den ASCII-String (Zeiger in A0) in ein Long-
; Word, welches in D0 zurückgeben wird. Anschließend zeigt A0 auf
; das erste Zeichen nach der Zalh im String. Enthält D1 0, trat
; kein Fehler auf. 1 signalisiert einen Überlauf, -1 zeigt einen
; Fehler im Aufbau an. Unterstützt werden das dezimale und das
; hexadezimale ("$") Zahlensystem.
;
GetLong movem.l d3-d3/a1-a3,-(sp) ; Register retten
bsr.s .Main
movem.l (sp)+,d3-d3/a1-a3
rts
.Main moveq.l #0,d0 ; Register löschen
moveq.l #0,d1
moveq.l #0,d2
.Label1 move.b (a0)+,d3 ; Spaces und Tabs überlesen
cmp.b #" ",d3
beq.s .Label1
cmp.b #9,d3
beq.s .Label1
cmp.b #"$",d3 ; hexadezimal ?
beq .Hex
cmp.b #"-",d3 ; negativ ?
beq.s .Negativ
cmp.b #"9",d3 ; Ziffer ?
bhi .Fehler
cmp.b #"0"-1,d3
bhi .Dezimal
.Fehler subq.l #1,a0 ; ^Fehler
moveq.l #-1,d1 ; Fehlercode
rts
.Negativ tst.b d2 ; teste,ob bereits ein "-"
bne.s .Fehler
moveq.l #1,d2 ; Flag für negativ seten
bra .Label1
.Dezimal subq.l #1,a0 ; A0 auf erste Ziffer setzen
move.l a0,a1 ; A1 ^erstes Ziffer
.Label_D2 move.b (a0)+,d3 ; nächste Zeiffer holen
cmp.b #"9",d3 ; wiederhole, bis Zahlenende
bhi.s .Label_D3 ; erreicht wird.
cmp.b #"0"-1,d3
bhi.s .Label_D2
.Label_D3 lea.l .Data10(pc),a2 ; Zeiger auf 10'er-Potenzen
subq.l #1,a0 ; A0 ^letzte Ziffer+1
move.l a0,a3 ; A3 ^letzte Ziffer+1
.Label_D5 move.l (a2)+,d4 ; Stellenzahl holen
beq.s .Overflow ; Longwordgrenze überschritten ?
moveq.l #0,d3 ; D3 löschen
move.b -(a3),d3 ; vorherige Ziffer holen
sub.b #"0"+1,d3 ; und in Zahl umwandeln (1 abziehen wegen DBRA-Schleife)
bmi.s .D_Zero ; Ziffer "0" abfangen
.Label_D4 add.l d4,d0 ; Stellenzahl so oft wie Ziffer addieren
dbra d3,.Label_D4
.D_Zero cmp.l a3,a1 ; Zahlenanfang erreicht ?
bne.s .Label_D5
.Vorzeichen tst.b d2 ; negatives Vorzeichen ?
beq.s .NotNegative
tst.l d0 ; Ist die Zahl größer als ein Longint ?
bmi .Overflow
neg.l d0 ; negativieren
.NotNegative moveq.l #0,d1 ; keine Fehler
rts
.Data10 dc.l 1
dc.l 10
dc.l 100
dc.l 1000
dc.l 10000
dc.l 100000
dc.l 1000000
dc.l 10000000
dc.l 100000000
dc.l 1000000000
dc.l 0
.Overflow moveq.l #1,d1 ; Überfluß (Zahl zu groß !)
rts
.Hex move.b (a0)+,d3 ; erste Stelle OK ?
bsr.s .Nibble
bmi .Fehler ; Fehler !
lea.l -1(a0),a1 ; A1 ^ erste Ziffer
.Label_H2 move.b (a0)+,d3
bsr.s .Nibble ; in Hexa-Ziffer übersetzen
bpl.s .Label_H2
subq.l #1,a0 ; A0 ^letzte Ziffer+1
move.l a0,a2 ; A2 ^letzte Ziffer+1
moveq.l #0,d1
.Label_H3 move.b -(a2),d3 ; vorherige Ziffer
bsr .Nibble
lsl.l d1,d4 ; Nibble an richtige Position schieben
add.l d4,d0 ; zum Ergebnis addieren
addq.l #4,d1
cmp.b #32,d1 ; 32. Bit erreicht ?
bhi .Overflow ; wenn ja, Overflow !
cmp.l a2,a1 ; Zahlenanfang erreicht ?
bne.s .Label_H3
bra .Vorzeichen
.Nibble moveq.l #0,d4
cmp.b #"a"-1,d3 ; Ziffer d3 -> Zahl d4
bls.s .N1 ; Upcase
cmp.b #"f",d3
bhi.s .N_Error
sub.b #"a"-"A",d3
.N1 sub.b #"0",d3
cmp.b #9,d3 ; Ziffer ?
bls.s .Ziffer
sub.b #"@"-"9",d3 ; Buchstabe
cmp.b #$f,d3
bhi.s .N_Error
.Ziffer move.b d3,d4
rts
.N_Error moveq.l #-1,d4 ; Fehler !
rts