;
; Bin2Ass.s :  konvertiert files in folgendes Format :
;              " dc.w $aaaa,$bbbb,...,$zzzz ;..A..S.D.."
;
**************************************************************
*                                                            *
*  THIS IS  PUBLIC DOMAIN  !!!!  Do with it what you like !!!!
*                                                            *
**************************************************************
;
;              Autor : Sascha Groening
;                      Blaustr.:    13
;                      8360 Deggendorf
;                      WEST-Germany
;
;
;
;              fuer A68k   Public Domain Assembler
;                   BLINK  Public Domain Linker
;
;              Aufruf :  AssData [> outfile] infile
;
;              Assemblieren :  A68K AssData.s
;                              BLINK AssData.o
;
;
;



SysBase   equ 4
OldOpenLibrary equ -408
FindTask equ -294
AllocMem equ -198
FreeMem equ -210
CloseLibrary equ -414

Open equ -30
Close equ -36
Read equ -42
Write equ -48
Output equ -60
Lock equ -84
UnLock equ -90
Examine equ -102

MODE_READWRITE equ 1004
MODE_OLDFILE   equ 1005
MODE_NEWFILE   equ 1006
MODE_READONLY  equ MODE_OLDFILE

MEMF_PUBLIC  equ $1
MEMF_CHIP    equ $2
MEMF_FAST    equ $4
MEMF_CLEAR   equ $10000
MEMF_LARGEST equ $20000

SHARED_LOCK equ -2

fib_DiskKey      equ $00
fib_DirEntryType equ $04
fib_FileName     equ $08
fib_Protection   equ $74
fib_EntryType    equ $78
fib_Size         equ $7c
fib_NumBlocks    equ $80
fib_DateStamp    equ $84
fib_Comment      equ $90
fib_SIZEOF       equ $104

tc_sigrecvd      equ 26 ;Eintrag in der Task-Struktur der Process-Struktur
                        ;der die Signal Bits enthaelt (CTRL-C ... CTRL-F)

SIGBREAKB_CTRLC  equ 12 ;Bit 12 gesetzt wenn CTRL-C gedrueckt
SIGBREAKB_CTRLD  equ 13
SIGBREAKB_CTRLE  equ 14
SIGBREAKB_CTRLF  equ 15


CALLEXEC macro
         movea.l SysBase,a6
         jsr    \1(a6)
         endm

CALLDOS  macro
         movea.l DOSBase,a6
         jsr    \1(a6)
         endm


;
;  *****  MainProg *****
;

_main
    move.l a7,stapel
    move.l a0,comadr
    move.l d0,comlaenge
    clr.b  -1(a0,d0)        ;Null terminated string

    lea.l  dosname,a1
    CALLEXEC OldOpenLibrary ;Open dos.library
    move.l  d0,DOSBase
    beq     fini            ;Was ? Nicht da ?!?! Nix wie raus !!!

    CALLDOS Output          ;OutputHandle holen
    move.l  d0,OutHandle

    suba.l  a1,a1           ;find own task
    CALLEXEC FindTask
    addi.l #tc_sigrecvd,d0
    move.l d0,tasksigbits   ;adr unserer Signal-Bits


    move.l comlaenge,d0     ;Filename nicht eingegeben ?
    subq.l #1,d0
    beq.s  helpmessage

;
; Prglaenge holen
;
    bsr    getlength   ;wie lang ist das zu ladende File ?
;
; Prglaenge ausgeben
;

;    move.l flaenge,d2
;    lea.l  hbuf,a0
;    move.b  #10,8(a0)  ;LineFeed anfuegen
;    bsr     hexasc     ;in Hex-Zahl wandeln
;
;    move.l  OutHandle,d1
;    move.l  #hbuf,d2
;    moveq.l  #9,d3
;    CALLDOS Write
;
;**** Speicher belegen ***
;
    move.l flaenge,d0
    move.l #MEMF_CLEAR!MEMF_PUBLIC,d1 ;allokierten Speicher mit $00 fuellen
    CALLEXEC AllocMem
    move.l d0,DATA            ;nicht genug freier Speicher ?
    beq    nomem
;
; File lesen
;
    bsr readfile
;
; File ausgeben
;
    bsr Display
;
; CleanUp
;

CloseAll
memfree
    movea.l stapel,a7
    movea.l DATA,a1
    move.l flaenge,d0
    CALLEXEC  FreeMem

unlock
    movea.l stapel,a7
    move.l lock,d1
    CALLDOS UnLock

closedos
    movea.l stapel,a7
    movea.l  DOSBase,a1
    CALLEXEC CloseLibrary        ;CloseLibrary
    clr.l   d0
fini    rts


****************************************
; SubProgs

helpmessage
    move.l  OutHandle,d1
    move.l  #Fehler1,d2
    moveq.l  #len1,d3
    CALLDOS Write
    bra     closedos

nomem
    move.l  OutHandle,d1
    move.l  #Fehler3,d2
    moveq.l  #len3,d3
    CALLDOS Write     ;LVOWrite
    bra     unlock
;
; Konvertiere d2.l in ASCII-String ab (a0)
;

hexasc
    moveq.l #3,d0                       ;4 Nibble (=1 Word) wandeln
    adda.l  #8,a0                       ;Pos der letzten Stelle im Buffer+1
loop5
    moveq.l #15,d1                      ;
    and.l   d2,d1                       ;1 Nibble isolieren
    asr.l   #4,d2                       ;naechstes Nibble an 1.Pos
    addi.b  #48,d1                      ;isol. Nibble+48=Zahl in ASCII
    cmpi.b  #57,d1                      ;war Zahl >9 ?
    bls.s   cont4
    addq.l  #7,d1                       ;wenn ja noch 7 dazu ==> A-F
cont4
    move.b  d1,-(a0)                    ;in Buffer eintragen
    dbra    d0,loop5                    ;naechstes Nibble wandeln
    rts

;
; gibt Speicherinhalt in dc.w $ Form aus
;


Display
    move.l flaenge,d5      ;laenge des Files
    movea.l DATA,a3        ;FileBuffer

loop2
    lea.l line,a4
    lea.l dcw,a0           ;' dc.w ' in Buffer eintragen

    move.l (a0)+,(a4)+
    move.w (a0)+,(a4)+


    moveq.l #4,d4
loop3
    lea.l dol,a0           ;'$' in Buffer eintragen
    move.b (a0)+,(a4)+

    clr.l  d2
    move.w (a3)+,d2        ;naechstes Word holen
    lea.l  hbuf,a0         ;Ziel der Konvertierung
    move.b #32,4(a0)       ;Space anfuegen
    bsr.s  hexasc          ;in Hex-Zahl wandeln

    lea.l hbuf+4,a0
    move.b (a0)+,(a4)+
    move.b (a0)+,(a4)+
    move.b (a0)+,(a4)+
    move.b (a0)+,(a4)+

    tst.l  d4              ;wenn letztes Word ==> kein Komma darstellen
    beq.s  cont1

    lea.l kom,a0           ;',' in Buffer eintragen
    move.b (a0)+,(a4)+

cont1
    dbra   d4,loop3        ;naechstes Word in ASCII wandeln

    lea.l sem,a0           ;'  ;' in Buffer eintragen
    move.b (a0)+,(a4)+
    move.b (a0)+,(a4)+
    move.b (a0)+,(a4)+


;
; ASCII Ausgabe
;

    suba.l #10,a3          ;Zeiger im Buffer wieder um 5 Words zurueck

    moveq.l #9,d4          ;10 Buchstaben darstellen
loop4
    move.b (a3),d0         ;nicht darstellbare Zeichen
    cmpi.b #' ',d0         ;mit Space ueberschreiben
    blt    cont2
    cmpi.b #'z',d0
    blt  cont3
cont2
    move.b #' ',(a3)
cont3
    adda.l #1,a3           ;Pointer = Pointer + 1
    dbra   d4,loop4

    suba.l #10,a3

    move.l (a3)+,(a4)+
    move.l (a3)+,(a4)+
    move.w (a3)+,(a4)+

                           ;10 Byte aus dem Buffer kopieren
                           ;=> ASCII Zeichen als Kommentar
    lea.l  Ret,a0
    move.b (a0)+,(a4)+

    move.l OutHandle,d1
    move.l #line,d2
    moveq.l #50,d3
    CALLDOS Write          ;Zeile ausgeben

    move.l tasksigbits,a0
    move.l (a0),d0
    btst.w #SIGBREAKB_CTRLC,d0   ;CTRL-C gedrueckt ?
    bne.s  break           ;wenn zustaendiges Bit in
                           ;TaskControlStrktr gesetzt ==> *** Break ***

    subi.l #10,d5
    tst.l  d5
    bne    loop2                ;naechste Zeile darstellen

    rts

;
; User-Break detected
;

break
    move.l  OutHandle,d1
    move.l  #Fehler2,d2
    moveq.l #len2,d3
    CALLDOS Write
    bra     CloseAll

;
; comadr enthaelt pointer auf null-terminated string
; der den Filenamen enthaelt
; ==> flaenge enthaelt Laenge des zu ladenden Files
;     als Vielfaches von 10 (aus programmtechnischen Gruenden)
;

getlength
    move.l comadr,d1
    move.l SHARED_LOCK,d2
    CALLDOS Lock
    move.l d0,lock
    beq    helpmessage

                              ;allocate Speicher fuer Fileinfoblock Struktur
    move.l #fib_SIZEOF,d0     ;groesse des Speichers
    move.l #MEMF_CLEAR!MEMF_CHIP,d1 ;allokierten Speicher mit $00 fuellen
    CALLEXEC AllocMem
    move.l d0,FileInfoBlock   ;nicht genug freier Speicher ?
    beq    nomem              ;sicher ist sicher
                              ;fuer zukuenftige abgespeckte Amiga-Versionen
                              ;mit weniger als 128 KByte

    move.l lock,d1
    move.l FileInfoBlock,d2
    CALLDOS Examine

    move.l FileInfoBlock,a0
    move.l fib_Size(a0),d0    ;Filelaenge holen
    divu.w #10,d0             ;daraus Viefaches von 10 machen
    andi.l #$FFFF,d0  ;Rest der Division loeschen
    mulu.w #10,d0
    addi.l #10,d0     ;ob nun ein Rest aufgetreten ist oder nicht

    move.l d0,flaenge

    movea.l FileInfoBlock,a1
    move.l #fib_SIZEOF,d0
    CALLEXEC  FreeMem

    rts

readfile
    move.l comadr,d1
    move.l #MODE_OLDFILE,d2
    CALLDOS Open
    move.l d0,d4  ;braucht nicht getestet werden ob <> 0
                  ;wurde in getlength schon erledigt

    move.l d0,d1
    move.l DATA,d2
    move.l flaenge,d3
    CALLDOS Read

    move.l d4,d1
    CALLDOS Close

    rts

***************************************


 DATA constants


dosname     dc.b 'dos.library',0
            cnop 0,4
Fehler1     dc.b 'Bin2Ass   by Sascha Groening',10
            dc.b 'This is Public Domain ! Do with it what you like !!!',10
            dc.b 'Usage "Bin2Ass [>outfile] infile/A" ',10
len1        equ  *-Fehler1
            cnop 0,4
Fehler2     dc.b '*** BREAK ***',10
len2        equ  *-Fehler2
            cnop 0,4
Fehler3     dc.b 'not enough Memory  !',10
len3        equ  *-Fehler3
            cnop 0,4
dcw         dc.b ' dc.w '
            cnop 0,4
kom         dc.b ','
            cnop 0,4
dol         dc.b '$'
            cnop 0,4
Ret         dc.b 10
            cnop 0,4
sem         dc.b '  ;'
            cnop 0,4


 BSS storage

            cnop  0,4
DOSBase       ds.l 1
DATA          ds.l 1
FileInfoBlock ds.l 1
OutHandle     ds.l 1
tasksigbits   ds.l 1
flaenge       ds.l 1
comadr        ds.l 1
comlaenge     ds.l 1
stapel        ds.l 1
lock          ds.l 1
hbuf          ds.l 3
line          ds.b 81
            cnop 0,4

            END

