
;**********************************************************************
;*								      *
;*		      DezHexBin - PUBLIC DOMAIN 		      *
;*								      *
;*			     Version 1.1			      *
;*								      *
;*		    (C) Michael Djavidan 7.1.1990                     *
;*	       St.Kolomann 7, 8059 Wörth, West Germany		      *
;*			  Phone: 08123/1288			      *
;*								      *
;*								      *
;*		       Assembler: ASM68K (-CC)                        *
;*								      *
;*								      *
;**********************************************************************



;***** LIBRARY BASE OFFSETS *******************************************

;***** Exec Library Base Offsets

OPENLIBRARY:	equ -552
CLOSELIBRARY:	equ -414
FORBID: 	equ -30-102
FINDTASK:	equ -294
WAITPORT:	equ -384
GETMSG: 	equ -372
REPLYMSG:	equ -378

;***** DOS Library Base Offsets

Write:		equ -48
Output: 	equ -60

;***** Intuition Library Offsets

OpenWindow:	equ -204
CloseWindow:	equ -72
RefreshGadgets: equ -222
SetWindowTitles:	equ -276
SetMenuStrip:	equ -264
ModifyIDCMP:	equ -150
DisplayBeep:	equ -96

;***** Graphics Library Base Offsets

SETAPEN:	equ -342
SETBPEN:	equ -348
MOVE:		equ -240
TEXT:		equ -60


;***** Sonstige Deklarationen ****************************************

Sysbase:	equ 4

rp_FgPen:	equ $19 	;Rastport
rp_LinePtrn:	equ $22

;***** INTUITION-Message *****

im_Class:	equ $14
im_Code:	equ $18
im_IAddress:	equ $1C

;***** Zeichenmodi *****

RP_JAM1:	equ 0
RP_JAM2:	equ 1
RP_COMPLEMENT:	equ 2
RP_INVERSVID:	equ 4

;***** WINDOWS *****

WINDOWSIZING:		equ $1
WINDOWDRAG:		equ $2
WINDOWDEPTH:		equ $4
WINDOWCLOSE:		equ $8
BORDERLESS:		equ $800
ACTIVATE:		equ $1000
SIMPLE_REFRESH: 	equ $40

;IDCMP-Flags:

MOUSEBUTTONS:		equ $8
MENUPICK:		equ $100
IDCMPCLOSEWINDOW:	equ $200
NEWSIZE:		equ $2
MOUSEMOVE:		equ $10
INACTIVEWINDOW: 	equ $80000
ACTIVEWINDOW:		equ $40000

WD_RPORT:		equ $32
WD_USERPORT:		equ 86		;Für WAIT()
MP_SIGBIT:		equ 15

;***** Gadgets *****

GADGHCOMP:	equ 0
GADGHBOX:	equ 1
GADGHIMAGE:	equ 2
GADGHNONE:	equ 3

RELVERIFY:	equ $1
GADGDISABLED:	equ $0100
GADGIMMEDIATE:	equ $2
SELECTED:	equ $80
FOLLOWMOUSE:	equ $8
TOGGLESELECT:	equ $100
GADGETUP:	equ $40 	;Int-Message (im_Class)
GADGETDOWN:	equ $20

BOOLGADGET:	equ 1
GADGET0002:	equ 2
PROPGADGET:	equ 3
STRGADGET:	equ 4

gg_GadgetID:	equ $26


;*****	Makro-Definitionen  ******************************************

CallInt: macro
   move.l IntBase,a6
   jsr	  \1(a6)
   endm

CallExec: macro
   move.l SysBase,a6
   jsr	  \1(a6)
   endm

CallGfx: macro
   move.l GfxBase,a6
   jsr	  \1(a6)
   endm

CallDos: macro
   move.l DosBase,a6
   jsr	  \1(a6)
   endm

* Makro zum Öffnen einer Library
OpenLib: macro
   move.l #\1,a1
   moveq  #0,d0
   move.l Sysbase,a6
   jsr	  OpenLibrary(a6)
   tst.l  d0
   endm

CloseLib: macro
   move.l \1,a1
   move.l SysBase,a6
   jsr	  CloseLibrary(a6)
   endm

;Aufruf PUTS ^Text
PUTS:	macro
	lea \1,a0
	bsr PUTS_
	endm

* Aufruf: Window,x,y,^String(abgeschlossen mit \0)
DRAWTEXT:  macro
	move.l \1,a1
	lea \4,a0
	move.l #\2,d0
	move.l #\3,d1
	bsr _DRAWTEXT
	endm

* Aufruf: Window,FarbNr.
PenA: macro
   movem.l d0/a1/a6,-(sp)
   move.l \1,a1
   move.l wd_RPort(a1),a1
   move.l #\2,d0
   move.l GfxBase,a6
   jsr	  SetAPen(a6)
   movem.l (sp)+,d0/a1/a6
   endm
PenB: macro
   movem.l d0/a1/a6,-(sp)
   move.l \1,a1
   move.l wd_RPort(a1),a1
   move.l #\2,d0
   move.l GfxBase,a6
   jsr	  SetBPen(a6)
   movem.l (sp)+,d0/a1/a6
   endm

* AUFRUF: Window,^WindowText,^ScreenText
WINDOWTITLE: macro
	movem.l d0/a0/a1/a2/a6,-(sp)
	move.l \1,a0
	lea \2,a1
	lea \3,a2
	move.l IntBase,a6
	jsr SetWindowTitles(a6)
	movem.l (sp)+,d0/a0/a1/a2/a6
	endm

;*********************************************************************
;*     CodeTeil 						     *
;*********************************************************************


;***** STARTUP-CODE **************************************************

	movem.l d0/a0,-(sp)     ;Parameter retten
	clr.l WorkbenchMsg

;Test, von wo aufgerufen wurde
	sub.l a1,a1
	CALLEXEC FindTask
	move.l d0,a4
	tst.l $ac(a4)          ;Workbench ?
	beq.s Workbench

;Start aus dem CLI
	movem.l (sp)+,d0/a0
	bra.s Start

;Start von Workbench
Workbench:
	lea $5c(a4),a0
	CALLEXEC WaitPort
	lea $5c(a4),a0
	CALLEXEC GetMsg
	move.l d0,WorkbenchMsg
	movem.l (sp)+,d0/a0
Start:
	bsr.s Begin		;Programmstart
	move.l d0,-(sp)         ;Returncode retten
	tst.l WorkbenchMsg
	beq.s Exit
	CALLEXEC Forbid
	move.l WorkbenchMsg,a1
	CALLEXEC ReplyMsg
Exit:
	move.l (sp)+,d0
	rts




;***** DHB - Begin ***************************************************

Begin:

; Libraries öffnen

	OpenLib Intname
	beq    NoIntuition
	move.l d0,IntBase

	OpenLib Gfxname
	beq    NoGraphics
	move.l d0,GfxBase

	OpenLib Dosname
	beq    NoDos
	move.l d0,DosBase

; Fenster öffnen

	lea NewWindow,a0		;Window-Definition
	CALLINT OpenWindow
	tst.l  d0			;alles O.K.?
	beq    NoWindow
	move.l d0,Window1		;Windowzeiger retten
	move.l d0,a0
	move.l $2e(a0),Screen           ;^Screen holen

; Menue einbauen

	move.l Window1,a0
	lea  My_Menu,a1
	CALLINT SetMenuStrip


	clr.l d0
	bsr RefreshWindow		;Fenster füllen



;***** Auf Signal warten *********************************************

EVENT:

	move.l Window1,a0
	move.l WD_USERPORT(a0),a0       ;Offset für Zeiger auf Userport
	move.l a0,a5
	CallExec WaitPort

; Event ermitteln
	move.l	 a5,a0
	CALLEXEC GetMsg
	move.l	 d0,a1
	move.l	 im_Class(a1),d4        ;Typ der Message
	move.w	 im_Code(a1),d5         ;Unter...?
	move.l	 im_IAddress(a1),a4     ;Antwort
	CALLEXEC ReplyMsg


; Verzweigen zu zuständigem Programmteil für Event

	cmpi.l	 #IDCMPCLOSEWINDOW,d4	;Closegadget
	beq	 ChooseClose

	cmpi.l	 #GADGETUP,d4		;Gadget Up
	beq	 ChooseGadUp

	cmpi.l	 #GADGETDOWN,d4 	;Gadget down
	beq	 ChooseGadDown

	cmpi.l	 #MENUPICK,d4		;Menu angewählt
	beq	 ChooseMenu

	cmpi.l	 #INACTIVEWINDOW,d4	;Fenster deaktiviert
	beq	 ChooseWindowOFF

	cmpi.l	 #ACTIVEWINDOW,d4	;Fenster aktiviert
	beq	 ChooseWindowON


	bra Event



;***** Events bearbeiten *********************************************



;***** GADGET gedrückt *****

ChooseGadDown:
	move.w gg_GadgetID(a4),d0
	cmp.w  #0,d0
	bne.L DezNo
		move.l ZAHL,d0
		bsr RefreshWindow
		move.l $22(a4),a0       ;String Info
		move.l 0(a0),a0         ;^Textpuffer
		move.b #0,(a0)          ;Endekennzeichen

		lea Gadget0,a0
		move.l Window1,a1
		move.l #0,a2
		CALLINT RefreshGadgets
		PENB Window1,3
		DRAWTEXT Window1,64,17,Cursor
		PENB Window1,0
	bra Event


DezNo:	cmp.w  #1,d0
	bne.L HexNo
		move.l ZAHL,d0
		bsr RefreshWindow
		move.l $22(a4),a0       ;String Info
		move.l 0(a0),a0         ;^Textpuffer
		move.b #0,(a0)          ;Endekennzeichen

		lea Gadget0,a0
		move.l Window1,a1
		move.l #0,a2
		CALLINT RefreshGadgets
		PENB Window1,3
		DRAWTEXT Window1,173,17,Cursor
		PENB Window1,0
	bra Event


HexNo:	cmp.w  #2,d0
	bne.L BinNo
		move.l ZAHL,d0
		bsr RefreshWindow
		move.l $22(a4),a0       ;String Info
		move.l 0(a0),a0         ;^Textpuffer
		move.b #0,(a0)          ;Endekennzeichen

		lea Gadget0,a0
		move.l Window1,a1
		move.l #0,a2
		CALLINT RefreshGadgets
		PENB Window1,3
		DRAWTEXT Window1,12,27,Cursor
		PENB Window1,0
	bra Event


BinNo:	cmp.w  #3,d0
	bne  AscNo
		move.l ZAHL,d0
		bsr RefreshWindow
		move.l $22(a4),a0       ;String Info
		move.l 0(a0),a0         ;^Textpuffer
		move.b #0,(a0)          ;Endekennzeichen

		lea Gadget0,a0
		move.l Window1,a1
		move.l #0,a2
		CALLINT RefreshGadgets
		PENB Window1,3
		DRAWTEXT Window1,260,17,Cursor
		PENB Window1,0
	bra Event

AscNo:


	bra  Event



;***** GADGET Losgelassen *****

ChooseGadUp:
	move.w gg_GadgetID(a4),d0
	cmp.w  #0,d0
	bne NoDez
		lea DezPuf,a0
		bsr ADez_Bin
		cmp.w #-1,d1
		beq.s Dez_Err1
		cmp.w #-2,d1
		beq.s Dez_Err2

		clr.w ShiftCount
		move.l d0,ZAHL		;Eingelesene Zahl retten
		bsr RefreshWindow
		bra Event

Dez_Err1:	WINDOWTITLE Window1,Title_InvChar,About
		lea Gadget0,a0
		move.l Window1,a1
		move.l #0,a2
		CALLINT RefreshGadgets
		bra Event

Dez_Err2:	WINDOWTITLE Window1,Title_Overflow,About
		lea Gadget0,a0
		move.l Window1,a1
		move.l #0,a2
		CALLINT RefreshGadgets
		bra Event



NoDez:	cmp.w  #1,d0
	bne.s  NoHex
		lea HexPuf,a0
		bsr AHex_Bin
		tst.w d1
		beq.s Hex_NoErr
			WINDOWTITLE Window1,Title_InvChar,About
			lea Gadget0,a0
			move.l Window1,a1
			move.l #0,a2
			CALLINT RefreshGadgets
			bra Event
Hex_NoErr:	clr.w ShiftCount
		move.l d0,ZAHL		;Eingelesene Zahl retten
		bsr RefreshWindow
		bra Event


NoHex:	cmp.w  #2,d0
	bne.s  NoBin
		lea BinPuf,a0
		bsr ABIN_BIN
		tst.w d1
		beq.s Bin_NoErr
			WINDOWTITLE Window1,Title_InvChar,About
			lea Gadget0,a0
			move.l Window1,a1
			move.l #0,a2
			CALLINT RefreshGadgets
			bra Event
Bin_NoErr:	clr.w ShiftCount
		move.l d0,ZAHL		;Eingelesene Zahl retten
		bsr RefreshWindow
		bra Event



NoBin:	cmp.w  #3,d0
	bne.s  NoAsc
		clr.l d0
		lea AscPuf,a0
		move.b (a0),d0
		clr.w ShiftCount
		move.l d0,ZAHL		;Eingelesene Zahl retten
		bsr RefreshWindow
		bra Event



NoAsc:	cmp.w  #4,d0
	bne.s  NoVZ
		move.l #VZOnTxt,GadText4+12
		move.w VZFlag,d1
		move.w #1,VZFlag
		tst.w d1
		beq.s VZ_Set
		   move.l #VZOffTxt,GadText4+12
		   clr.w VZFlag
VZ_Set: 	move.l Zahl,d0
		bsr RefreshWindow
		bra Event


NoVZ:	cmp.w  #5,d0
	bne.s  NoBWL
		add.w #1,BWLFlag		;Ein Format weiter
		cmp.w #2,BWLFlag
		bls.s BWL_M1
		   clr.w BWLFlag
BWL_M1: 	tst.w BWLFlag
		bne.s BWL_W
		   move.l #$000000FF,Maske
		   move.l #ByteTxt,GadText5+12
		   bra.s BWL_M2
BWL_W:		cmp.w #1,BWLFlag
		bne.s BWL_L
		   move.l #$0000FFFF,Maske
		   move.l #WordTxt,GadText5+12
		   bra.s BWL_M2
BWL_L:		move.l #$FFFFFFFF,Maske
		move.l #LongTxt,GadText5+12

BWL_M2: 	move.l ZAHL,d0
		bsr RefreshWindow
		bra Event


NoBWL:	cmp.w  #6,d0
	bne.s SHRNo
		move.l Zahl,d0
		add.w #1,ShiftCount
		cmp.w #33,ShiftCount
		blt.s SHR_OK
		   sub.w #1,ShiftCount
		   move.l Screen,a0
		   CALLINT DisplayBeep
SHR_OK: 	bsr RefreshWindow
	bra Event

SHRNo:	cmp.w  #7,d0
	bne.s SHLNo
		move.l Zahl,d0
		sub.w #1,ShiftCount
		cmp.w #-33,ShiftCount
		bgt.s SHL_OK
		   add.w #1,ShiftCount
		   move.l Screen,a0
		   CALLINT DisplayBeep
SHL_OK: 	bsr RefreshWindow
	bra Event

SHLNo:
	bra  Event



;***** Menu gewählt **************************************************

ChooseMenu:
	cmp.w #$FFFF,d5 	;Kein Menue angewählt ?
	beq Event

;Nur ein wählbarer Punkt vorhanden !

	move.l Window1,a0
	move.l $52(a0),d0       ;IDCMP's aus der Windowstruktur

	move.w I1_Check,d1	;Prüfen wie der Menupunkt steht
	btst #8,d1		;"Checked" testen
	beq GD_Aus
	or.l #GADGETDOWN,d0	;Reaktion auf Gadgetdrücken EIN
	bra GD_Weiter
GD_Aus: and.l #~GADGETDOWN,d0	;Reaktion AUS
GD_Weiter:
	CALLINT ModifyIDCMP
	bra Event


;***** Anderes Window angeklickt *************************************

ChooseWindowOFF:
	move.l ZAHL,d0
	bsr RefreshWindow
	WINDOWTITLE Window1,Title_Aus,About
	bra Event

;***** Wieder Activiert *****

ChooseWindowON:
	WINDOWTITLE Window1,Title_OK,About
	bra Event



;*********************************************************************



ChooseClose:

;***** NACHPROGRAMM **************************************************

; Fenster schließen
	move.l Window1,a0
	CallInt CloseWindow

; Libraries schließen
NoWindow:
	CloseLib DosBase

NoDos:
	CloseLib GfxBase

NoGraphics:
	CloseLib IntBase

NoIntuition:
	moveq #0,d0

	rts			;Programmende





;*********************************************************************
;*   Unterprogramme						     *
;*********************************************************************

;***** Fensterinhalt aufbauen (Bei sizing) ***************************

RefreshWindow:

	WINDOWTITLE Window1,Title_OK,About

	move.w ShiftCount,d1
	bmi RightShift
	lsr.l d1,d0
	bra SH_Weiter
RightShift:
	move.w #64,d2
	sub.w d1,d2
	lsl.l d2,d0
SH_Weiter:

	move.l Maske,d1
	move.w VZFlag,d2

	lea DezPuf,a0
	bsr Bin_ADez

	lea HexPuf,a0
	bsr Bin_AHex

	lea BinPuf,a0
	bsr Bin_ABin

	lea AscPuf,a0
	move.b d0,(a0)


	DRAWTEXT Window1,55,17,DezZei
	DRAWTEXT Window1,164,17,HexZei
	DRAWTEXT Window1,4,27,BinZei
	DRAWTEXT Window1,249,17,AscZei

	lea Gadget0,a0
	move.l Window1,a1
	move.l #0,a2
	CALLINT RefreshGadgets
	rts




;***** Zeichnen eines Textes (abgeschlossen mit \0) ******************

;A: ^String -> a0; Window -> a1; X,Y -> d0,d1;
;R: -

_DRAWTEXT:
	movem.l d0-d3/a0/a3/a5/a6,-(sp)

	move.l a0,a3
;Länge des Strings ermitteln
	move.l #-1,d3
DTL:	addq.l #1,d3
	cmp.b #0,(a0)+
	bne.s DTL

	move.l WD_RPort(a1),a1  ; Adresse des Rastports holen
	move.l a1,a5
	move.l GfxBase,a6
	jsr Move(a6)            ;Grafikcursor setzen
	move.l a5,a1
	move.l a3,a0
	move.l d3,d0
	jsr Text(a6)

	movem.l (sp)+,d0-d3/a0/a3/a5/a6
	rts




;***** DIVISION 32 BIT DURCH 32 BIT **********************************
;A: Divident(long) -> d0; Divisor(long) -> d1  ( d0 / d1 !)
;R: Ergebnis(long) -> d0; Rest(long) -> d1
Divu32:
	movem.l d2/d3/d4,-(sp)

	clr.l d2
	clr.l d3
	move.l #32-1,d4 	;Zähler

DivLoop:
	lsl.l #1,d0		;Bit 31 von d0 nach
	roxl.l #1,d2		;Bit 0 von d2 und beide shiften

;	andi.b #$ef,SR		;X-Flag löschen
	cmp.l d2,d1		;Wenn Divident größer d2 dann
	bhi.s BitIs0		; ist diese Ziffer = 0
	sub.l d1,d2		;Divident von Zwischenwert subtrahier.
	ori.b  #$10,SR		;X-Flag setzen
BitIs0: roxl.l #1,d3		;X-Flag ins Ergebnis rollen
	dbra d4,DivLoop

	move.l d3,d0
	move.l d2,d1

	movem.l (sp)+,d2/d3/d4
	rts





;*********************************************************************
;*     ASCII-String -> binäre Zahl				     *
;*********************************************************************

;***** DEZIMALEN ASCII-STRING IN BINAERE ZAHL *****

;A: ^ASCII-Puffer in -> a0;
;R: Long-Zahl in -> d0; Fehlercode in -> d1
;   (0 = OK; -1 = keine Dez-Zahl; -2 = Overflow)

ADez_Bin:
	movem.l d2-d5/a0,-(sp)

; *** Zuerst Vorzeichen suchen (erstes Zeichen das nicht Space ist)
	clr.l d1		;Fehlercode mit 0 vorbelegen
	clr.l d4		;VZ-Flag
	move.l #11-1,d2 	;Zähler
ADB_VZLoop:
	move.b (a0),d3
	cmp.b #0,d3		;Auf Endekennzeichen testen
	beq  ADB_Er
	cmp.b #' ',d3           ;Space überspringen
	beq.s ADB_S1
	cmp.b #'-',d3           ;Minus Zeichen ?
	beq.s ADB_Mi
	cmp.b #'+',d3           ;Plus Zeichen ?
	beq.s ADB_Pl
	bra.s ADB_Weiter	;Alles andere später prüfen
ADB_S1: addq.l #1,a0
	dbra  d2,ADB_VZLoop
	bra.s ADB_Er		;11. Zeichen darf kein Minus sein

ADB_Mi: move.w #1,d4		;VZ negativ
ADB_Pl: addq.l #1,a0		;VZ überspringen

ADB_Weiter:
	clr.l d0		;Zahl auf 0 setzen
	clr.l d3
ADB_Loop:
	move.b (a0)+,d3
	cmp.b #0,d3		;Auf Endekennzeichen testen
	beq.s ADB_End
	cmp.b #' ',d3           ;Space überspringen
	beq.s ADB_Sp
	cmp.b #'0'-1,d3         ;Zwischen 0-9 ?
	bls.s ADB_Er
	cmp.b #'9',d3
	bhi.s ADB_Er
	sub.b #'0',d3           ;ASCII in Binär wandeln

	move.w d0,d5		;Multiplikation:
	mulu  #10,d5		;   32 Bit-Zahl * 10 =
	swap d0 		; = LSW*10 + MSW*10*2^16 =
	mulu  #10,d0		; = 32 Bit-Zahl
	   cmp.l #$ffff,d0	;Wenn größer als Wort
	   bhi ADB_Er2		; dann Overflow
	bvs ADB_Er2
	swap d0
	clr.w d0
	add.l d5,d0		;Wenn Ergebnis größer 32 Bit
	bcs ADB_Er2		; dann Overflow


	add.l d3,d0
ADB_SP: dbra d2,ADB_Loop
	bra.s ADB_End
ADB_Er2:
	move.l #-2,d1		;Fehlercode für Overflow
	clr.l d0		;Ergebnis löschen
	bra ADB_End

ADB_Er: move.l #-1,d1		;Fehlercode wenn keine Dezimalziffer
	clr.l d0		;Ergebnis = 0

ADB_End:
	tst.w d4		;VZ-Flag testen
	beq.s ADB_Pos
	neg.l d0		;Wenn "-" dann Zahl negieren
ADB_Pos:
	movem.l (sp)+,d2-d5/a0
	rts



;***** HEXADEZIMALEN ASCII-STRING IN BINäARE ZAHL *****

;A: ^ASCII-Puffer in -> a0;
;R: Long-Zahl in -> d0; Fehlercode in -> d1 (0=OK, -1=Fehler)
AHex_Bin:
	movem.l d2/d3/a0,-(sp)

	clr.l d0
	clr.l d1
	move.l #8-1,d2		;Zähler
AHB_Loop:
	move.b (a0)+,d3
	cmp.b #0,d3		;Auf Endekennzeichen testen
	beq.s AHB_End
	cmp.b #' ',d3           ;Space überspringen
	beq.s AHB_Sp
	cmp.b #'0'-1,d3         ;Zwischen 0-9 ?
	bls.s AHB_Er
	cmp.b #'9',d3
	bls.s AHB_Za
	and.b #%11011111,d3	;Umwandeln in Großbuchstaben
	cmp.b #'A'-1,d3         ;Zwischen A-F ?
	bls.s AHB_Er
	cmp.b #'F',d3
	bhi.s AHB_Er
	sub.b #7,d3
AHB_Za: sub.b #'0',d3           ;Umwandeln in 4-BIT-Zahl
	lsl.l #4,d0		;Ein Nibble weiter
	or.b  d3,d0		;Zum Ergebnis addieren
AHB_Sp: dbra d2,AHB_Loop
	bra.s AHB_End

AHB_Er: move.l #-1,d1		;Fehlercode wenn keine Hexziffer
	clr.l d0		;Ergebnis = 0
AHB_End:
	movem.l (sp)+,d2/d3/a0
	rts



;***** BINäREN ASCII-STRING IN BINäARE ZAHL *****
;A: ^ASCII-Puffer in -> a0;
;R: Long-Zahl in -> d0; Fehlercode in -> d1 (0=OK, -1=Fehler)
ABin_Bin:
	movem.l d2/a0,-(sp)

	clr.l d0
	clr.l d1
	move.l #32-1,d2 	;Zähler
ABB_Loop:
	cmp.b #0,(a0)           ;Auf Endekennzeichen testen
	beq.s ABB_End
	cmp.b #' ',(a0)         ;Space überspringen
	beq.s ABB_Sp
	cmp.b #'0',(a0)
	beq.s ABB_0
	cmp.b #'1',(a0)
	beq.s ABB_1
	bra.s ABB_Er		;Alles außer 0," ","0","1", -> Fehler
ABB_0:	lsl.l #1,d0
	bra.s ABB_Sp
ABB_1:	lsl.l #1,d0
	bset #0,d0
ABB_Sp: addq.l #1,a0
	dbra d2,ABB_Loop
	bra.s ABB_End

ABB_Er: move.l #-1,d1		;Fehlercode
	clr.l d0		;Ergebnis = 0
ABB_End:
	movem.l (sp)+,d2/a0
	rts





;*********************************************************************
;*     binäre Zahl -> ASCII-String				     *
;*********************************************************************

;***** BINÄRE ZAHL IN DEZIMALEN ASCII-STRING *****

;A: ^ASCII-Puffer in -> a0; Long-Zahl in -> d0; Maske(b,w,l) in -> d1;
;A: VorzeichenFlag (VZ beachten ja=1, nein=0) -> d2.w;
;R: --
Bin_ADez:
	movem.l d0-d4/a0,-(sp)

	move.b #' ',d3
	tst.w d2		;Vorzeichen beachten ?
	beq.s BAD_POS

	btst #31,d1		;Vorzeichenbit ermitteln
	beq.s Not31
	   move.l #31,d4
	   bra.s BAD_VZ
Not31:	btst #15,d1
	beq.s Not15
	   move.l #15,d4
	   bra.s BAD_VZ
Not15:	move.l #7,d4

BAD_VZ: move.b #'+',d3          ;VZ-Merker
	btst d4,d0
	beq  BAD_POS
	neg.l d0
	move.b #'-',d3
BAD_POS:
	and.l d1,d0

	move.l #11-1,d2 	;Zähler (11 Zeichen!)
BAD_Fill:
	move.b #' ',(a0)+       ;Puffer mit Spaces füllen
	dbra  d2,BAD_Fill	;Danach steht a0 am Ende des Puffers

	tst.l d0		;Wenn Zahl=0 dann wenigstens eine
	beq.s BAD_Null		; Null ausgeben
	move.l #10-1,d2 	;Zähler (10 Ziffern)

BAD_Loop:
	tst.l d0		;Führende Nullen unterdrücken
	beq.s BAD_End
	moveq #10,d1		;d0 durch 10 teilen
	bsr Divu32		;32-Bit Division
	add.b #'0',d1           ;In ASCII umwandeln
	move.b d1,-(a0)
	dbra d2,BAD_Loop
	bra.s BAD_End
BAD_Null:
	move.b #'0',-(a0)       ;Einzelne Null ausgeben
BAD_End:
	move.b d3,-(a0)         ;VZ ausgeben

	movem.l (sp)+,d0-d4/a0
	rts




;***** BINÄRE ZAHL IN HEXADEZIMALEN ASCII-STRING *****

;A: Long-Zahl in -> d0; ^ASCII-Puffer in -> a0; Maske(b,w,l) in -> d1;
;R: --
Bin_AHex:
	movem.l d0/d1/d2/d3/a0,-(sp)

	add.l #8,a0		;ans Pufferende
	move.l #8-1,d2		;Zähler
BAH_Loop:
	lsr.l #4,d1		;Maske shiften
	bcs.s BAH_Weiter
	move.b #' ',-(a0)       ;Space setzen
	bra.s BAH_end
BAH_weiter:
	move.l d0,d3		;d0 muß erhalten bleiben
	and.b  #$0F,d3		;Unterstes Nibble stehenlassen
	add.b  #'0',d3
	cmp.b  #'9',d3
	bls    BAH_Z		;Wenn d3<=9 dann Zahl
	add.b  #7,d3		;Sonst Buchstabe
BAH_Z:	move.b d3,-(a0)
	lsr.l  #4,d0
BAH_end:
	dbra d2,BAH_loop

	movem.l (sp)+,d0/d1/d2/d3/a0
	rts



;***** BINÄRE ZAHL IN BINäREN ASCII-STRING *****

;A: Long-Zahl in -> d0; ^ASCII-Puffer in -> a0; Maske(b,w,l) in -> d1;
;R: --
Bin_ABin:
	movem.l d0/d1/d2/a0,-(sp)

	add.l #32,a0			;ans Pufferende
	move.l #32-1,d2 		;Zähler
BAB_loop:
	lsr.l #1,d1			;Maske shiften
	bcs.s BAB_weiter
	move.b #' ',-(a0)               ;Space setzen
	bra.s BAB_end
BAB_weiter:
	lsr.l #1,d0
	bcc.s BAB_null
	move.b #'1',-(a0)               ;1 setzen
	bra.s BAB_end
BAB_null:
	move.b #'0',-(a0)               ;0 setzen
BAB_end:
	dbra d2,BAB_loop

	movem.l (sp)+,d0/d1/d2/a0
	rts






;*********************************************************************
;*  Vereinbarungsteil						     *
;*********************************************************************


;***  STRINGS  *******************************************************

About:		ASCII 'DezHexBin V1.1     \169 Michael Djavidan'
		ASCII ' 1/90 \0'
Title_OK:	ASCII ' OK                     \0'
Title_Overflow: ASCII ' Overflow               \0'
Title_InvChar	ASCII ' Invalid Character      \0'
Title_Aus:	ASCII ' Standby                \0'

M1_Title:	ASCII '  DHB\0'
Item1_Txt:	ASCII 'Auto-Clear\0'

Cursor: 	ASCII ' \0'

DezZei: 	ASCII 'd\0'
HexZei: 	ASCII '$\0'
BinZei: 	ASCII '%\0'
AscZei: 	ASCII 'a\0'

DezPuf: 	ASCII '\0          \0'                       ;11 + \0
HexPuf: 	ASCII '\0       \0'                          ;8 + \0
BinPuf: 	ASCII '\0                               \0'  ;32 + \0
AscPuf: 	ASCII '\0\0'                                 ;1 + \0
UndoPuf:	ASCII 'UNDO-UNDO-UNDO-UNDO-UNDO-UNDO-UNDO'

VZOnTxt:	ASCII "±\0"
VZOffTxt:	ASCII '+\0'
ByteTxt:	ASCII 'B\0'
WordTxt:	ASCII 'W\0'
LongTxt:	ASCII 'L\0'
SHRTxt: 	ASCII "»\0"
SHLTxt: 	ASCII "«\0"

Intname:	ASCII 'intuition.library\0'
Gfxname:	ASCII 'graphics.library\0'
Dosname:	ASCII 'dos.library\0'
		cnop 2


;***  Variablen  *****************************************************

WorkbenchMsg:	dc.l 0		;Message vom Startup-Code

DosBase:	dc.l 0
IntBase:	dc.l 0
GfxBase:	dc.l 0

Window1:	dc.l 0		;Adresse der Windowstruktur
Screen: 	dc.l 0		;Adresse der Screenstruktur

ZAHL:		dc.l 0		;UM DIESE ZAHL DREHT SICH ALLES
ShiftCount:	dc.w 0		;Anzahl Stellen der Verschiebung

VZFlag: 	dc.w 0		;Vorzeichen ein/aus
BWLFlag:	dc.w 2		;Format der Anzeige (B/W/L = 0/1/2)
Maske:		dc.l $FFFFFFFF	;Maske zur Anzeige der Stellen


;*****	Strukturen  **************************************************

;***** WINDOW *****

IDCMP1: 	equ IDCMPCLOSEWINDOW!GADGETUP!MENUPICK!GADGETDOWN
WIND1IDCMP:	equ IDCMP1!INACTIVEWINDOW!ACTIVEWINDOW

WFlags1:	equ ACTIVATE!WINDOWCLOSE!WINDOWDRAG
WFlags: 	equ WFLAGS1!WINDOWDEPTH

NewWindow:
	dc.w	200,100 		;links-oben
	dc.w	279,30			;Breite, Höhe
	dc.b	2,-1			;Screenpens
	dc.l	WIND1IDCMP		;IDCMP-Flags
	dc.l	WFlags			;Window-Flags
	dc.l	Gadget0 		;User-Gadgets
	dc.l	0			;User-Checkmark
	dc.l	Title_OK		;Titel
	dc.l	0			;Eigener Screen
	dc.l	0			;Super Bitmap
	dc.w	100,20			;Min.
	dc.w	640,200 		;Max.
	dc.w	1			;WBscreen benutzen



;***** GADGETS ******************************************************

;***** STRINGGADGET FüR DEZIMALE EINGABE *****

Gadget0:
	dc.l	Gadget1 	;noch eins
	dc.w	64,11		;x,y
	dc.w	96,8		;breit,hoch
	dc.w	0		;flags
	dc.w	RELVERIFY!GADGIMMEDIATE ;Aktivierung
	dc.w	STRGADGET	;Typ
	dc.l	Border0 	;^Border-Strukt.
	dc.l	0
	dc.l	0		;^Text-Strukt.
	dc.l	0
	dc.l	Str0Info
	dc.w	0		;ID
	dc.l	0
Border0:
	dc.w	0,-1		;x,y
	dc.b	1,0		;Pens (BackPen ohne Wirkung)
	dc.b	RP_JAM1
	dc.b	9		;Paare
	dc.l	Koord0		;^Liste
	dc.l	0		;kein Border mehr
Koord0:
	dc.w	-11,-1		;Koord.-Liste
	dc.w	-11,9
	dc.w	-12,-1
	dc.w	-12,9
	dc.w	97,9
	dc.w	97,-1
	dc.w	98,9
	dc.w	98,-1
	dc.w	-11,-1
Str0Info:
	dc.l	DEZPUF		;^Arbeitspuffer
	dc.l	UNDOPUF 	;^UndoPuffer
	dc.w	0		;Anfangs-Cursor-Position
	dc.w	12		;Puffergröße+1
	dc.w	11		;Pos. Cursor Zeichen
	dc.w	11		;Zahl Zeichen im Puffer
	dc.w	11		;Zeichen sichtbar
	dc.w	0,0		;Lage des Rahmens
	dc.l	0		;^Layer des Gadgets
	dc.l	0		;Long Int hier
	dc.l	0		;^eigene Keymap


;***** STRINGGADGET FüR HEXADEZIMALE EINGABE *****

Gadget1:
	dc.l	Gadget2 	;noch eins
	dc.w	173,11		;x,y
	dc.w	72,8		;breit,hoch
	dc.w	0		;flags
	dc.w	RELVERIFY!GADGIMMEDIATE ;Aktivierung
	dc.w	STRGADGET	;Typ
	dc.l	Border1 	;^Border-Strukt.
	dc.l	0
	dc.l	0		;^Text-Strukt.
	dc.l	0
	dc.l	Str1Info
	dc.w	1		;ID
	dc.l	0
Border1:
	dc.w	0,0		;x,y
	dc.b	1,0		;Pens (BackPen ohne Wirkung)
	dc.b	RP_JAM1
	dc.b	9		;Paare
	dc.l	Koord1		;^Liste
	dc.l	0		;kein Border mehr
Koord1:
	dc.w	-11,-2		;Koord.-Liste
	dc.w	-11,8
	dc.w	-12,-2
	dc.w	-12,8
	dc.w	73,8
	dc.w	73,-2
	dc.w	74,8
	dc.w	74,-2
	dc.w	-11,-2

Str1Info:
	dc.l	HEXPUF		;^Arbeitspuffer
	dc.l	UNDOPUF 	;^UndoPuffer
	dc.w	0		;Anfangs-Cursor-Position
	dc.w	9		;Puffergröße+1
	dc.w	8		;Pos. Cursor Zeichen
	dc.w	8		;Zahl Zeichen im Puffer
	dc.w	8		;Zeichen sichtbar
	dc.w	0,0		;Lage des Rahmens
	dc.l	0		;^Layer des Gadgets
	dc.l	0		;Long Int hier
	dc.l	0		;^eigene Keymap



;***** STRINGGADGET FüR BINäRE EINGABE *****

Gadget2:
	dc.l	Gadget3 	;noch eins
	dc.w	12,21		;x,y
	dc.w	264,11		;breit,hoch
	dc.w	0		;flags
	dc.w	RELVERIFY!GADGIMMEDIATE ;Aktivierung
	dc.w	STRGADGET	;Typ
	dc.l	Border2 	;^Border-Strukt.
	dc.l	0
	dc.l	0		;^Text-Strukt.
	dc.l	0
	dc.l	Str2Info
	dc.w	2		;ID
	dc.l	0
Border2:
	dc.w	0,0		;x,y
	dc.b	1,0		;Pens (BackPen ohne Wirkung)
	dc.b	RP_JAM1
	dc.b	9		;Paare
	dc.l	Koord2		;^Liste
	dc.l	0		;kein Border mehr
Koord2:
	dc.w	-11,-2		;Koord.-Liste
	dc.w	-11,8
	dc.w	-12,-2
	dc.w	-12,8
	dc.w	265,8
	dc.w	265,-2
	dc.w	266,8
	dc.w	266,-2
	dc.w	-11,-2
Str2Info:
	dc.l	BINPUF		;^Arbeitspuffer
	dc.l	UNDOPUF 	;^UndoPuffer
	dc.w	0		;Anfangs-Cursor-Position
	dc.w	33		;Puffergröße+1
	dc.w	32		;Pos. Cursor Zeichen
	dc.w	32		;Zahl Zeichen im Puffer
	dc.w	32		;Zeichen sichtbar
	dc.w	0,0		;Lage des Rahmens
	dc.l	0		;^Layer des Gadgets
	dc.l	0		;Long Int hier
	dc.l	0		;^eigene Keymap




;***** STRINGGADGET FüR EINGABE EINES ASCII-ZEICHENS *****************

Gadget3:
	dc.l	Gadget4 	;noch eins
	dc.w	260,11		;x,y
	dc.w	16,8		;breit,hoch
	dc.w	0		;flags
	dc.w	RELVERIFY!GADGIMMEDIATE ;Aktivierung
	dc.w	STRGADGET	;Typ
	dc.l	Border3 	;^Border-Strukt.
	dc.l	0
	dc.l	0		;^Text-Strukt.
	dc.l	0
	dc.l	Str3Info
	dc.w	3		;ID
	dc.l	0
Border3:
	dc.w	0,-2		 ;x,y
	dc.b	1,0		;Pens (BackPen ohne Wirkung)
	dc.b	RP_JAM1
	dc.b	9		;Paare
	dc.l	Koord3		;^Liste
	dc.l	0		;kein Border mehr
Koord3:
	dc.w	-13,0	       ;Koord.-Liste
	dc.w	-13,10
	dc.w	-14,0
	dc.w	-14,10
	dc.w	17,10
	dc.w	17,0
	dc.w	18,10
	dc.w	18,0
	dc.w	-13,0

Str3Info:
	dc.l	ASCPUF	     ;^Arbeitspuffer
	dc.l	UNDOPUF 	;^UndoPuffer
	dc.w	0		;Anfangs-Cursor-Position
	dc.w	2		;Puffergröße+1
	dc.w	1		;Pos. Cursor Zeichen
	dc.w	1		;Zahl Zeichen im Puffer
	dc.w	1		;Zeichen sichtbar
	dc.w	0,0		;Lage des Rahmens
	dc.l	0		;^Layer des Gadgets
	dc.l	0		;Long Int hier
	dc.l	0		;^eigene Keymap





;***** GADGET ZUM EIN/AUSSCHALTEN DES VORZEICHENS ********************

Gadget4:
	dc.l	Gadget5 	;noch eins
	dc.w	41,10		;x,y
	dc.w	11,9		;breit,hoch
	dc.w	GADGHCOMP	;flags
	dc.w	RelVerify	;Aktivierung
	dc.w	BOOLGADGET	;Typ
	dc.l	Border4 	;^Border-Strukt.
	dc.l	0
	dc.l	Gadtext4	;^Text-Strukt.
	dc.l	0,0
	dc.w	4		;ID
	dc.l	0
Border4:
	dc.w	-2,0		;x,y
	dc.b	1,0		;Pens (BackPen ohne Wirkung)
	dc.b	RP_JAM1
	dc.b	4		;Paare
	dc.l	Koord4		;^Liste
	dc.l	0		;kein Border mehr
Koord4:
	dc.w	0,0		;Koord.-Liste
	dc.w	0,8
	dc.w	1,8
	dc.w	1,0
GadText4:
	dc.b	1,0		;Pens
	dc.b	RP_JAM2,0
	dc.w	2,1		;x,y
	dc.l	0		;Sys-Font
	dc.l	VZOffTxt
	dc.l	0


;***** GADGET ZUM EINSTELLEN DES FORMATS (B,W,L) *********************

Gadget5:
	dc.l	Gadget6 	;noch eins
	dc.w	28,10		;x,y
	dc.w	11,9		;breit,hoch
	dc.w	GADGHCOMP	;flags
	dc.w	RelVerify	;Aktivierung
	dc.w	BOOLGADGET	;Typ
	dc.l	Border5 	;^Border-Strukt.
	dc.l	0
	dc.l	Gadtext5	;^Text-Strukt.
	dc.l	0,0
	dc.w	5		;ID
	dc.l	0
Border5:
	dc.w	-2,0		;x,y
	dc.b	1,0		;Pens (BackPen ohne Wirkung)
	dc.b	RP_JAM1
	dc.b	4		;Paare
	dc.l	Koord5		;^Liste
	dc.l	0		;kein Border mehr
Koord5:
	dc.w	0,0		;Koord.-Liste
	dc.w	0,8
	dc.w	1,8
	dc.w	1,0
GadText5:
	dc.b	1,0		;Pens
	dc.b	RP_JAM2,0
	dc.w	2,1		;x,y
	dc.l	0		;Sys-Font
	dc.l	LongTxt
	dc.l	0



;***** GADGET FüR SHIFT RECHTS ***************************************

Gadget6:
	dc.l	Gadget7 	;noch eins
	dc.w	15,10		;x,y
	dc.w	11,9		;breit,hoch
	dc.w	GADGHCOMP	;flags
	dc.w	RELVERIFY	;Aktivierung
	dc.w	BOOLGADGET	;Typ
	dc.l	Border6 	;^Border-Strukt.
	dc.l	0
	dc.l	Gadtext6	;^Text-Strukt.
	dc.l	0,0
	dc.w	6		;ID
	dc.l	0
Border6:
	dc.w	-2,0		;x,y
	dc.b	1,0		;Pens (BackPen ohne Wirkung)
	dc.b	RP_JAM1
	dc.b	4		;Paare
	dc.l	Koord6		;^Liste
	dc.l	0		;kein Border mehr
Koord6:
	dc.w	0,0		;Koord.-Liste
	dc.w	0,8
	dc.w	1,8
	dc.w	1,0
GadText6:
	dc.b	1,0		;Pens
	dc.b	RP_JAM2,0
	dc.w	2,1		;x,y
	dc.l	0		;Sys-Font
	dc.l	SHRTxt
	dc.l	0


;***** GADGET FüR SHIFT LINKS ****************************************

Gadget7:
	dc.l	0		;noch eins
	dc.w	2,10		;x,y
	dc.w	11,9		;breit,hoch
	dc.w	GADGHCOMP	;flags
	dc.w	RELVERIFY	;Aktivierung
	dc.w	BOOLGADGET	;Typ
	dc.l	0		;^Border-Strukt.
	dc.l	0
	dc.l	Gadtext7	;^Text-Strukt.
	dc.l	0,0
	dc.w	7		;ID
	dc.l	0
GadText7:
	dc.b	1,0		;Pens
	dc.b	RP_JAM2,0
	dc.w	2,1		;x,y
	dc.l	0		;Sys-Font
	dc.l	SHLTxt
	dc.l	0




;***** MENUE - STRUKTUREN ********************************************

My_Menu:
	dc.l 0			;Nächstes Menu
	dc.w 20,0		;x,y Position
	dc.w 110,10		;Breite, Höhe
	dc.w 1			;Wählbar
	dc.l M1_Title		;Menuetitle
	dc.l Item1		;Einträge
	dc.w 0,0,0,0		;Für Intuition

Item1:
	dc.l 0			;Nächstes Item
	dc.w 0,3		;x,y Position
	dc.w 110,10		;Breite, Höhe
I1_Check:
	dc.w %101011011 	;Flag
	dc.l 0			;Ausschluß
	dc.l Item1_ITxt 	;Textstruktur
	dc.l 0			;Kein Image
	dc.b 0			;Keine Tastenkombination
	cnop 2
	dc.l 0			;Subitem
	dc.l 0

Item1_ITxt:
	dc.b	2,1		;Pens
	dc.b	RP_JAM2,0
	dc.w	20,1		;x,y
	dc.l	0		;Sys-Font
	dc.l	Item1_Txt
	dc.l	0


