home *** CD-ROM | disk | FTP | other *** search
-
-
- ;
- ;
- ;
- ; CLIwindow V1.00
- ;
- ;
- ;
- ;
- ; Copyright 12/1990 by Roger Fischlin
- ; Steigerwaldweg 6
- ; 6450 Hanau 7
- ; Germany
- ;
- ;
- ;
- ; This program may be freely distributed if you don't gain any
- ; profit by using and/or distributing it.
- ;
- ;
- ; This program is pc relative and 100% PURE (set P flag)
- ;
-
-
- incdir "ram:include/"
-
- include "exec/exec_lib.i"
- include "exec/memory.i"
- include "intuition/intuition_Lib.i"
- include "intuition/intuition.i"
- include "libraries/dos.i"
- include "libraries/dos_lib.i"
- include "libraries/dosextens.i"
-
-
- ;
- ; Macros
- ;
-
-
- DOS macro ; die alten Macros müssen ersetzt
- move.l Var_DOS(a5),a6 ; werden, da ja die Library-Bases
- jsr _LVO\1(a6) ; an anderer Stelle vermerkt werden.
- endm
-
- INT macro
- move.l Var_INT(a5),a6
- jsr _LVO\1(a6)
- endm
-
-
-
- ;
- ; Variablen
- ;
-
- rsreset
- Var_DOS rs.l 1 ; DOSBase
- Var_INT rs.l 1 ; IntuitionBase
- Var_Parameter rs.l 1 ; Zeiger auf Paramterstring
- Var_X rs.w 1 ; X-Ordinate
- Var_Y rs.w 1 ; Y-Ordinate
- Var_Width rs.w 1 ; Breite
- Var_Height rs.w 1 ; Höhe
- Var_Window rs.l 1 ; Zeiger aufs Window
-
- Var_SIZEOF rs.b 0
-
-
- ;
- ; Variablenspeicherplatz belegen
- ;
- ; Diese Routine belegt den Speicherplatz für die zuvor bestimmte
- ; Variablenliste. Bei einem Fehler wird das anschließende Haupt-
- ; programm nicht gestartet.
- ;
-
-
- _main clr.b -1(a0,d0) ; Paramterstring mit $00 terminieren
- move.l a0,a4
- moveq.l #Var_SIZEOF,d0 ; Variablenspeicher
- move.l #MEMF_CLEAR+MEMF_PUBLIC,d1 ; belegen
- CALLEXEC AllocMem
- tst.l d0
- beq.s .Fehler ; Fehler !
- move.l d0,a5
- move.l a4,Var_Parameter(a5)
- bsr .Programm : ins Hauptprogramm
- .Label1 move.l d0,-(sp)
- move.l a5,a1
- moveq.l #Var_SIZEOF,d0
- CALLEXEC FreeMem ; Variablenspeicher freigeben
- move.l (sp)+,d0
- rts
- .Fehler moveq.l #20,d0 ; fataler Fehler !
- bra.s .Label1
- .Programm
-
- ;
- ; Hauptprogramm
- ;
-
- MAIN bsr GetLibs ; DOS- und Intuition-Library öffnen
- tst.l d0 ; Fehler
- beq .Fehler
- bsr CLIWindow ; Zeiger auf CLI-Window
- lea.l .Text1(pc),a0
- tst.l d0
- beq .PrintText
- move.l d0,Var_Window(a5) ; Zeiger merken
-
- move.l d0,a0
- move.w wd_LeftEdge(a0),Var_X(a5) ; aktuelle Windowerte als Voreinstellung
- move.w wd_TopEdge(a0),Var_Y(a5) ; kopieren
- move.w wd_Width(a0),Var_Width(a5)
- move.w wd_Height(a0),Var_Height(a5)
-
-
- move.l Var_Parameter(a5),a0 ; X-Ordinate holen
- move.l a0,a1
- cmp.b #"?",(a0)
- beq .INFO ; Info-String ausgeben
- cmp.b #"*",(a1)+ ; aktuellen Wert übernehmen ?
- beq.s .Label1
- subq.l #1,a1 ; A0 wieder um eins vermindern
- bsr GetLong
- move.l a0,a1 ; Zeiger auf nächstes Argument
- lea.l .Text2(pc),a0
- tst.l d1 ; Fehler ?
- bne .PrintText ; Fehlermeldung ausgeben
- move.w d0,Var_X(a5)
- .Label1 cmp.b #"/",(a1)+ ; "/"-Zeichen ?
- bne .PrintText
-
- move.l a1,a0 ; Y-Ordinate holen
- cmp.b #"*",(a1)+ ; aktuellen Wert übernehmen ?
- beq.s .Label2
- subq.l #1,a1 ; A0 wieder um eins vermindern
- bsr GetLong
- move.l a0,a1 ; Zeiger auf nächstes Argument
- lea.l .Text2(pc),a0
- tst.l d1 ; Fehler ?
- bne .PrintText ; Fehlermeldung ausgeben
- move.w d0,Var_Y(a5)
- .Label2 cmp.b #"/",(a1)+ ; "/"-Zeichen ?
- bne .PrintText
-
- move.l a1,a0 ; Breite holen
- cmp.b #"*",(a1)+ ; aktuellen Wert übernehmen ?
- beq.s .Label3
- subq.l #1,a1 ; A0 wieder um eins vermindern
- bsr GetLong
- move.l a0,a1 ; Zeiger auf nächstes Argument
- lea.l .Text2(pc),a0
- tst.l d1 ; Fehler ?
- bne .PrintText ; Fehlermeldung ausgeben
- move.w d0,Var_Width(a5)
- .Label3 cmp.b #"/",(a1)+ ; "/"-Zeichen ?
- bne .PrintText
-
- move.l a1,a0 ; Höhe holen
- cmp.b #"*",(a1)+ ; aktuellen Wert übernehmen ?
- beq.s .Label12
- subq.l #1,a1 ; A0 wieder um eins vermindern
- bsr GetLong
- move.l a0,a1 ; Zeiger auf nächstes Argument
- lea.l .Text2(pc),a0
- tst.l d1 ; Fehler ?
- bne .PrintText ; Fehlermeldung ausgeben
- move.w d0,Var_Height(a5)
-
-
- .Label12 CALLEXEC Forbid ; kein anderer Task darf das Window jetzt verschieben !
- move.l Var_Window(a5),a0 ; Window-Zeiger
- move.l wd_WScreen(a0),a1 ; Screen-Zeiger
-
- move.w Var_Width(a5),d0
- cmp.w #0,d0 ; Ist die Breite >0 ?
- bgt.s .Label10 ; wenn ja, verzweige
- add.w sc_Width(a1),d0 ; sonst : echte Breite = Breite + Screen_Breite - Window_X
- sub.w Var_X(a5),d0
- move.w d0,Var_Width(a5)
- .Label10 move.w Var_Height(a5),d0
- cmp.w #0,d0 ; Ist die Höhe >0 ?
- bgt.s .Label11 ; wenn ja, verzweige
- add.w sc_Height(a1),d0 ; sonst : echte Höhe = Höhe + Screen_Höhe - Window_Y
- sub.w Var_Y(a5),d0
- move.w d0,Var_Height(a5)
- .Label11
-
- move.w Var_Width(a5),d0
- cmp.w wd_MaxWidth(a0),d0 ; Gewünschte Breite größer als erlaubte ?
- bls.s .Label6
- move.w wd_MaxWidth(a0),d0 ; erlaubte Breite
- .Label6 cmp.w wd_MinWidth(a0),d0 ; Gewünschte Breite kleiner als erlaubte ?
- bhi.s .Label7
- move.w wd_MinWidth(a0),d0 ; erlaubte Breite
- .Label7 move.w d0,Var_Width(a5)
-
-
- move.w Var_Height(a5),d0
- cmp.w wd_MaxHeight(a0),d0 ; Gewünschte Höhe größer als erlaubte ?
- bls.s .Label8
- move.w wd_MaxHeight(a0),d0
- .Label8 cmp.w wd_MinHeight(a0),d0 ; Gewünschte Höhe kleiner als erlaubte ?
- bhi.s .Label9
- move.w wd_MinHeight(a0),d0 ; erlaubte Höhe
- .Label9 move.w d0,Var_Height(a5)
-
-
- move.l wd_WScreen(a0),a0 ; Zeiger auf zugehörigen Screen
-
- move.w Var_X(a5),d0 ; X2 bestimmen
- add.w Var_Width(a5),d0
- move.w Var_Y(a5),d1 ; Y2 bestimmen
- add.w Var_Height(a5),d1
-
- cmp.w sc_Width(a0),d0 ; X2> Windowbreite ?
- bls.s .Label4
- CALLEXEC Permit ; Fehler !
- lea.l .Text3(pc),a0
- bra .PrintText
- .Label4 cmp.w sc_Height(a0),d1 ; Y2> Windowhöhe ?
- bls.s .Label5
- CALLEXEC Permit ; Fehler !
- lea.l .Text3(pc),a0
- bra .PrintText
-
-
- .Label5 move.l Var_Window(a5),a0 ; zunächst Window-Position verändern
- move.w Var_X(a5),d0 ; DeltaX = neue_X_Ordinate - X_Ordinate_Window
- move.w Var_Y(a5),d1 ; DeltaY = neue_Y_Ordinate - Y_Ordinate_Window
- sub.w wd_LeftEdge(a0),d0
- sub.w wd_TopEdge(a0),d1
- INT MoveWindow
-
- move.l Var_Window(a5),a0 ; jetzt die Window-Größe verändern
- move.w Var_Width(a5),d0 ; DeltaX = neue_Breite - alte_Breite
- move.w Var_Height(a5),d1 ; DeltaY = neue_Höhe - alte_Höhe
- sub.w wd_Width(a0),d0
- sub.w wd_Height(a0),d1
- INT SizeWindow
-
- CALLEXEC Permit ; das war's !
- lea.l .NewSize(pc),a0 ; das CLI/die SHELL soll die neuen Ausmaße übernehmen !
- bsr CLIText
-
-
- bsr CloseLibs ; zuvor geöffnete Libraries schließen
- moveq.l #0,d0 ; kein Fehler !
- rts
-
- .Fehler bsr CloseLibs ; zuvor geöffnete Libraries schließen
- moveq.l #20,d0 ; fataler Fehler !
- rts
-
- .PrintText bsr CLIText ; Fehlermeldung ausgeben
- bsr CloseLibs ; zuvor geöffnete Libraries schließen
- moveq.l #0,d0
- rts
-
- .INFO lea.l .InfoString(pc),a0 ; "?"-Funktion
- bra.s .PrintText
-
- .Text1 dc.b "Can't get window pointer !",10,0
- even
- .Text2 dc.b "Sytax error !",10,0
- even
- .Text3 dc.b "Check screen size !",10,0
- even
- .NewSize dc.b $9b,"t",$9b,"u",0
- even
- .InfoString dc.b 10," ",$9b,"4m"
- dc.b " CLIwindow V1.00 © 12/1990 Roger Fischlin "
- dc.b $9b,"0m",10,10
- dc.b " CLIwindow may be freely distributed if you don't gain an profit",10
- dc.b " by using and/or distributing it.CLIwindow will move this CLI window",10
- dc.b " and change its size.",10,10
- dc.b " Usage : CLIwindow x/y/width/height",10,10
- dc.b " use '*' for current data. CLIwindow will check MinWidth & MinHeight",10
- dc.b " and MaxWidth & MaxHeight. It also takes care of the screen size.",10
- dc.b " You may use hexadecimal numbers, too. If Width od Height are bellow",10
- dc.b " 1 then they are taken as X2 oder Y2 relative to the screen size .",10
- dc.b " For example 'CLIwindow 0/0/0/0' will use the whole screen size or",10
- dc.b " 'CLIwindow 0/0/-10/0' will leave ten rows free.",10
- dc.b 10,0
-
- ;
- ; GetLibs
- ;
- ; GetLibs öffnet die DOS- und die Intuition-Library ab Kick-
- ; start 1.2 . Tritt ein Fehler auf, so enthält D0 0.
- ;
-
- GetLibs lea.l IntName(pc),a1 ; Intuition-Library
- moveq.l #33,d0 ; ab Kickstart 1.2
- CALLEXEC OpenLibrary ; öffnen
- move.l d0,Var_INT(a5)
- beq.s .Error
- lea.l DosName(pc),a1 ; DOS-Library
- moveq.l #33,d0 ; ab Kickstart 1.2
- CALLEXEC OpenLibrary ; öffnen
- move.l d0,Var_DOS(a5)
- .Error rts
-
- IntName INTNAME ; Library-Namen
- DosName DOSNAME
-
- ;
- ; CloseLibs
- ;
- ; CloseLibs schließt die von OpenLibs geöffneten Libraries, nicht
- ; geöffnete Libraries werden abgefangen.
- ;
-
- CloseLibs move.l d2,-(sp) ; D2 retten
- moveq.l #0,d2 ; D2 als $0000000-Vergleich
- move.l Var_INT(a5),a1 ; Intuition-Library schließen
- cmp.l a0,d2 ; Wurde sie überhaupt geöffnet ?
- beq.s .Skip1
- CALLEXEC CloseLibrary
- .Skip1 move.l Var_DOS(a5),a1 ; DOS-Library schließen
- cmp.l a0,d2 ; Wurde sie überhaupt geöffnet ?
- beq.s .Skip2
- CALLEXEC CloseLibrary
- .Skip2 move.l (sp)+,d2
- rts
-
- ;
- ; CLIWindow
- ;
- ; CLIWindow ermittelt den Zeiger auf das Fenster des CLIs, bzw.
- ; liefet 0 bei einem Fehler.
- ;
-
-
- CLIWindow movem.l a2-a5,-(sp) ; Register 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
-
- moveq.l #id_SIZEOF,d0 ; Speicher für InfoData reservieren
- move.l #MEMF_PUBLIC!MEMF_CLEAR,d1
- CALLEXEC AllocMem
- tst.l d0
- beq.s .Label3
- move.l d0,a5
-
- lsr.l #2,d0 ; id-Zeiger in BCPL-Zeiger umwandeln
- move.l d0,sp_Pkt+dp_Arg1(a4) ; und ins DosPacket eintragen
- move.l #ACTION_DISK_INFO,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
-
- move.l id_VolumeNode(a5),d0 ; WindowPointer !
-
- .Label4 move.l d0,-(sp)
- move.l a5,a1 ; Speicher für InfoData
- moveq.l #id_SIZEOF,d0 ; freigeben
- CALLEXEC FreeMem
- move.l (sp)+,d0
-
- .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)+,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
-
-
-
-