*Amiga BTOA.ASM 941013
*Randy Lilly N3ET
*For non-commercial use only
*Encodes Binary to ASCII for Ham Radio Packet transmission.
*Use ATOB (ASCII to Binary) to decode .AB files.

*This source is complete - no LIB or INCLUDES needed.
*Suggest STACK 8000

*To assemble and link;
* ASMB BTOA.ASM -O BTOA.O
* ALINK BTOA.O TO BTOA

 NOPAGE

_LVOClose       EQU -$24
_LVOExit        EQU -$90
_LVOInput       EQU -$36
_LVOOpen        EQU -$1E
_LVOOpenLibrary EQU -$198
_LVOOutput      EQU -$3C
_LVORead        EQU -$2A
_LVOWrite       EQU -$30
_AbsExecBase equ 4

MAXLIN EQU 76
RSIZE EQU 512
WSIZE EQU 512

DATAS EQU 0
CCNT EQU -1 B
BCNT EQU -2 B
WCNT EQU -4 W
CEOR EQU -8  LB
CSUM EQU -12 L
CROT EQU -16 L
RPNT EQU -20 L
RCNT EQU -22 W
WORD EQU -26 L
RFILE EQU -30 L
WFILE EQU -34 L
INHAN EQU -38 L
OUTHN EQU -42 L
DATAE EQU OUTHN

ABNAM EQU DATAE-80
FNAME EQU ABNAM-80
WBUFF EQU FNAME-WSIZE
RBUFF EQU WBUFF-RSIZE

START
 LINK   A4,#RBUFF
 LEA    DATAE(A4),A0
 MOVEQ  #DATAS-DATAE,D3
1$
 CLR.B  (A0)+
 DBRA   D3,1$

 MOVE.L _AbsExecBase,A6
 LEA    DOSNAM(PC),A1
 CLR.L  D0
 JSR    _LVOOpenLibrary(A6)
 MOVE.L D0,A6
 JSR    _LVOInput(A6)
 MOVE.L D0,INHAN(A4)
 BEQ    ABORT
 JSR    _LVOOutput(A6)
 MOVE.L D0,OUTHN(A4)
 BEQ    ABORT

 LEA    INFILE(PC),A0
 BSR    GNAM_CON
 MOVE.L A0,D1
 MOVE.L #1005,D2
 JSR    _LVOOpen(A6)
 MOVE.L D0,RFILE(A4)
 BEQ    NREAD

ANAME;
 LEA    FNAME(A4),A0
18$
 LEA    ABNAM(A4),A1
 MOVEQ  #76,D3
20$
 CMP.B  #':',(A0)+
 BEQ.S  18$
 SUBQ.L #1,A0
 CMP.B  #'/',(A0)+
 BEQ.S  18$
 SUBQ.L #1,A0
 MOVE.B (A0)+,(A1)+
 DBEQ   D3,20$
 LEA    MABNAM(PC),A0
 BSR    PLIN_CON
 LEA    ABNAM(A4),A0
 BSR    PLIN_CON
 BSR    YESNO           ;(Y/N)
 BNE.S  WNAME
 LEA    MABNAM(PC),A0
 BSR    PLIN_CON
 LEA    ABNAM(A4),A0
 BSR    GLIN_CON
 LEA    ABNAM(A4),A0
 TST.W  D0
 BEQ    ENDIT
 CLR.B  0(A0,D0.W)

WNAME;
 LEA    FNAME(A4),A0
 MOVEQ  #76,D3
40$
 TST.B  (A0)+
 DBEQ   D3,40$
 MOVE.B #'.',-1(A0)
 MOVE.B #'A',(A0)+
 MOVE.B #'B',(A0)+
 MOVE.B #0,(A0)
 LEA    OUTFIL(PC),A0
 BSR    PLIN_CON
 LEA    FNAME(A4),A0
 BSR    PLIN_CON
 BSR    YESNO           ;(Y/N)
 BEQ.S  60$
 LEA    FNAME(A4),A0
 BRA.S  65$
60$
 LEA    OUTFIL(PC),A0
 BSR    GNAM_CON
65$
 MOVE.L A0,D1
 MOVE.L #1006,D2
 JSR    _LVOOpen(A6)
 MOVE.L D0,WFILE(A4)
 BEQ    NWRITE

CONVERT;
 LEA    HEADER(PC),A0 ;xbtoa Begin
 BSR    PLIN_FIL
 LEA    ABNAM(A4),A0
 BSR    PLIN_FIL
 MOVEQ  #$A,D7
 BSR    PCHR_FIL

 MOVEQ  #0,D6
70$
 BSR    GCHR_FIL   ;Get a Character from READ file
 BMI.S  80$
 BSR    ENCODE     ;encode
 ADDQ.L #1,D6
 BRA    70$

80$
 TST.B  BCNT(A4)
 BEQ.S  90$
 MOVEQ  #0,D7
 BSR    ENCODE     ;encode 0
 BRA    80$

90$
 BSR    WFLUSH
* "\nxbtoa End N %ld %lx E %lx S %lx R %lx\n",n,n,Ceor,Csum,Crot
 LEA    RBUFF(A4),A0
 MOVE.L D6,D0   ;Bytes in hex
 BSR.S  HEXDEC
 MOVE.L D6,D0   ;Bytes in decimal
 BSR.S  HEXFIL
 MOVE.B #' ',(A0)+
 MOVE.B #'E',(A0)+
 MOVE.L CEOR(A4),D0
 BSR.S  HEXFIL
 MOVE.B #' ',(A0)+
 MOVE.B #'S',(A0)+
 MOVE.L CSUM(A4),D0
 BSR.S  HEXFIL
 MOVE.B #' ',(A0)+
 MOVE.B #'R',(A0)+
 MOVE.L CROT(A4),D0
 BSR.S  HEXFIL
 MOVE.B #$A,(A0)+
 MOVE.B #0,(A0)+
 LEA    TRAIL(PC),A0
 BSR    PLIN_FIL
 LEA    RBUFF(A4),A0
 BSR    PLIN_FIL
 BRA.S  ENDIT


HEXDEC ;Form 8 ASCII (DECIMAL) digits, leading 0's suppressed
 DIVU   #10000,D0
 MOVE.W D0,-(SP)
 CLR.W  D0
 SWAP   D0
 CLR.L  D1
 MOVEQ  #3,D3
1$
 DIVU   #10,D0
 SWAP   D0
 OR.B   D0,D1
 ROR.L  #4,D1
 CLR.W  D0
 SWAP   D0
 DBRA   D3,1$

 MOVE.W (SP)+,D0 ;For 10k
 MOVEQ  #3,D3
2$
 DIVU   #10,D0   ;REM,DEC
 SWAP   D0
 OR.B   D0,D1
 ROR.L  #4,D1    ;Rotate remainder
 CLR.W  D0
 SWAP   D0
 DBRA   D3,2$
 MOVE.L D1,D0

HEXFIL  ;Form 8 ASCII (HEX) digits, leading 0's suppressed
 MOVE.B #' ',(A0)+
 TST.L  D0
 BNE.S  1$
 MOVE.B #'0',(A0)+
 RTS

1$
 MOVEQ  #0,D2 ;For leading 0's
 MOVEQ  #7,D3
2$
 ROL.L  #4,D0
 MOVE.B D0,D1
 AND.B  #$F,D1
 SUB.B  D1,D2
 BEQ.S  4$
 ADD.B  #$30,D1
 CMP.B  #$39,D1
 BLE.S  3$
 ADDQ.B #7,D1
3$
 MOVE.B D1,(A0)+
4$
 DBRA   D3,2$
 RTS


NWRITE
 LEA    NOWRIT(PC),A0
 BRA.S  ENDIT1

NREAD
 LEA    NOREAD(PC),A0
ENDIT1
 BSR    PLIN_CON

ENDIT
 MOVE.L RFILE(A4),D1
 BEQ.S  1$
 JSR    _LVOClose(A6)
1$
 BSR    WFLUSH
 MOVE.L WFILE(A4),D1
 BEQ.S  ABORT
 JSR    _LVOClose(A6)
ABORT
 JMP    _LVOExit(A6)


ENCODE
 EOR.L  D7,CEOR(A4) ;Ceor ^= c;

 MOVE.L D7,D0
 ADD.L  CSUM(A4),D0 ;Csum +=c;
 ADDQ.L #1,D0       ;Csum +=1;
 MOVE.L D0,CSUM(A4)

 MOVE.L CROT(A4),D0 ;if ((Crot & 0x80000000L)) {
 LSL.L  #1,D0       ;Crot <<=1;
 BCC.S  1$
 ADDQ.L #1,D0       ;Crot +=1;
1$
 ADD.L  D7,D0       ;Crot +=c;
 MOVE.L D0,CROT(A4)

 MOVE.L WORD(A4),D1
 LSL.L  #8,D1       ;word <<=8;
 OR.B   D7,D1       ;word |=c;
 MOVE.L D1,WORD(A4)

 CMP.B  #3,BCNT(A4) ;if (bcount==3)
 BNE.S  2$

 BSR.S  WORDOUT     ;wordout(word);

 CLR.B  BCNT(A4)    ;bcount=0;
 RTS

2$
 ADDQ.B #1,BCNT(A4) ;bcount +=1;
 RTS


WORDOUT
 MOVE.L D1,D7
 BEQ.S  ZERO

 LEA    TAB85(PC),A5
 MOVEQ  #3,D4
1$
 MOVEQ  #0,D0
 MOVEQ  #6,D3
2$
 LSL.B  #1,D0
 MOVE.L (A5)+,D1
 CMP.L  D1,D7
 BCS.S  3$
 SUB.L  D1,D7
 ADDQ.B #1,D0
3$
 DBRA   D3,2$
 MOVEM.L A5/D7,-(SP)
 MOVE.B D0,D7
 BSR.S   4$
 MOVEM.L (SP)+,D7/A5
 DBRA   D4,1$
4$
 ADD.B  #'!',D7
 BRA.S  BINOUT    ;Remainder byte


ZERO
 MOVEQ  #'z',D7
***
BINOUT ;charout
***
 BSR.S  PCHR_FIL        ;putc(c,outf);
 ADDQ.B #1,CCNT(A4)     ;ccount += 1;
 CMP.B  #MAXLIN,CCNT(A4) ;if (ccount==MAXLIN) {
 BNE.S  1$
 MOVEQ  #$A,D7          ;putc('\n',outf);
 BSR.S  PCHR_FIL
 CLR.B  CCNT(A4)        ;ccount = 0;
1$
 RTS

***
PCHR_FIL ;D7 to W file
***
 LEA    WBUFF(A4),A0
 MOVE.W WCNT(A4),D0
 MOVE.B D7,0(A0,D0.W)
 ADDQ.W #1,D0
 MOVE.W D0,WCNT(A4)
 CMP.W  #WSIZE,D0
 BNE.S  RTS1

***
WFLUSH ;write buffer to disk
***
 MOVE.L WFILE(A4),D1
 BEQ.S  RTS1
 LEA    WBUFF(A4),A0
 MOVE.L A0,D2
 CLR.L  D3
 MOVE.W WCNT(A4),D3
 BEQ.S  RTS1
 JSR    _LVOWrite(A6)
 CLR.W  WCNT(A4)
 TST.L  D0
 BMI    ENDIT         ;Error
RTS1    RTS


***
RFILL ;Fill transmit buffer
***
 MOVE.L RFILE(A4),D1
 LEA    RBUFF(A4),A0
 MOVE.L A0,RPNT(A4)
 MOVE.L A0,D2
 MOVEQ  #0,D3
 MOVE.W #RSIZE,D3
 JSR    _LVORead(A6)
 MOVE.W D0,RCNT(A4)
 BEQ.S  WRITE1   ;EOF
 BMI    ENDIT    ;Error
***
GCHR_FIL
***
 TST.W  RCNT(A4)
 BEQ.S  RFILL
 MOVE.L RPNT(A4),A0
 MOVEQ  #0,D7
 MOVE.B (A0)+,D7
 MOVE.L A0,RPNT(A4)
WRITE1
 SUBQ.W #1,RCNT(A4)
 RTS


***
GLIN_CON ;Get line of txt from console
***
 MOVE.L INHAN(A4),D1
 MOVE.L A0,D2
 MOVEQ  #79,D3
 JSR    _LVORead(A6)
 SUBQ.L #1,D0
 RTS

PLIN_CON
 MOVE.L OUTHN(A4),D1
 BRA.S  PLIN

PLIN_FIL
 MOVE.L WFILE(A4),D1
PLIN
 MOVE.L A0,D2
 MOVEQ  #-1,D3
1$
 TST.B  (A0)+
 DBEQ   D3,1$
 NOT.L  D3
 JMP    _LVOWrite(A6)


GNAM_CON
 BSR    PLIN_CON
 LEA    FNAME(A4),A0
 BSR    GLIN_CON
 LEA    FNAME(A4),A0
 CLR.B  0(A0,D0.W)
 RTS

YESNO
 LEA    CONT(PC),A0    ;Go (Y/N)
 BSR    PLIN_CON
 LEA    WBUFF(A4),A0
 BSR    GLIN_CON
 MOVE.B WBUFF(A4),D0
 AND.B  #$5F,D0
 CMP.B  #'N',D0
 RTS


INFILE DC.B 'BTOA 941013 - Binary to ASCII converter',$A,$A
       DC.B ' READ file: ',0
OUTFIL DC.B 'WRITE file: ',0
MABNAM DC.B ' ATOB name: ',0
NOREAD DC.B 'No READ',$A,0
NOWRIT DC.B 'No WRITE',$A,0
HEADER DC.B 'xbtoa Begin ',0
TRAIL  DC.B $A,'xbtoa End N',0
CONT   DC.B ' (Y/N) ',0

*Powers of 85 for 32 bit division.
P1 EQU 85
P2 EQU P1*85
P3 EQU P2*85
P4 EQU P3*85

 CNOP 0,2
TAB85
 DC.L 64*(P4),32*(P4),16*(P4),8*(P4),4*(P4),2*(P4),P4
 DC.L 64*(P3),32*(P3),16*(P3),8*(P3),4*(P3),2*(P3),P3
 DC.L 64*(P2),32*(P2),16*(P2),8*(P2),4*(P2),2*(P2),P2
 DC.L 64*(P1),32*(P1),16*(P1),8*(P1),4*(P1),2*(P1),P1
DOSNAM DC.B  'dos.library',0
 END

