*Amiga ATOB.ASM 941013
*Randy Lilly  N3ET
*For non-commercial use only
*Decodes ASCII to BINARY (inverse of BTOA).

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

*To assemble and link;
* ASSEM ATOB.ASM -O ATOB.O
* ALINK ATOB.O TO ATOB

 NOPAGE
 PLEN 85

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

NSIZE EQU 80
RSIZE EQU 512
WSIZE EQU 512

* atob: vers 4.0   BIN=(C-!)*85   (((W*2)+1)*16)+W=85

CCNT EQU -1 B
BCNT EQU -2 B
WCNT EQU -4 W
CEOR EQU -8 L
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
OUTHAN EQU -42 L
TEMP  EQU -46
DATAE EQU TEMP

FNAME EQU TEMP-NSIZE
WBUFF EQU FNAME-WSIZE
RBUFF EQU WBUFF-RSIZE


START
 LINK   A4,#RBUFF
 LEA    DATAE(A4),A0
 MOVEQ  #-DATAE,D3
1$
 CLR.B  (A0)+
 DBRA   D3,1$
 MOVEQ  #' ',D4
 MOVE.L _AbsExecBase,A6
 LEA    DOSNAM(PC),A1
 CLR.L  D0              ;any version
 JSR    _LVOOpenLibrary(A6)
 MOVE.L D0,A6
 JSR    _LVOInput(A6)   ;already open
 MOVE.L D0,INHAN(A4)
 JSR    _LVOOutput(A6)  ;already open
 MOVE.L D0,OUTHAN(A4)

 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
 CLR.B  FNAME(A4)

HSERCH
 LEA    HEADER(PC),A3
1$
 BSR    GCHR_FIL
 BMI    NOHEAD
 CMP.B  (A3)+,D7
 BNE.S  HSERCH
 MOVE.B (A3),D7
 BNE.S  1$
 BSR    GCHR_FIL
 BMI    BDHEAD
 CMP.B  D4,D7
 BGT.S  HSERCH
 BNE.S  GNAME
 MOVEQ  #NSIZE-1,D6
 LEA    FNAME(A4),A5
2$
 BSR    GCHR_FIL
 BMI    BDHEAD
 CMP.B  D4,D7
 BLE.S  GNAME
 MOVE.B D7,(A5)+
 CLR.B  (A5)
 DBRA   D6,2$
 BRA    BDHEAD

GNAME
 LEA    OUTFIL(PC),A0
 BSR    PLIN_CON
 LEA    FNAME(A4),A0
 MOVE.B (A0),D0
 BEQ.S  GNEW1
 BSR    PLIN_CON
 LEA    CONT(PC),A0     ;(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
 BNE.S  OPENW
GNEW
 LEA    OUTFIL(PC),A0
GNEW1
 BSR    GNAM_CON
OPENW
 LEA    FNAME(A4),A0
 MOVE.L A0,D1
 MOVE.L #1006,D2
 JSR    _LVOOpen(A6)
 MOVE.L D0,WFILE(A4)
 BEQ    NWRITE
GDATA
 BSR    GCHR_FIL
 BMI    NOTAIL          ;EOF
 CMP.B  #$A,D7
 BEQ    GDATA
 CMP.B  #'x',D7
 BEQ.S  TSERCH
 BSR    DECODE
 BRA    GDATA

TSERCH
 LEA    FNAME(A4),A5
 MOVEQ  #NSIZE-2,D6
 MOVE.B #'x',(A5)+
 LEA    TRAIL+1(PC),A3
1$
 BSR    GCHR_FIL
 BMI    BDTAIL
 MOVE.B D7,(A5)+
 CMP.B  (A3)+,D7
 BNE    BDTAIL
 MOVE.B (A3),D7
 DBEQ   D6,1$
 MOVE.L A5,TEMP(A4)

DOTAIL
1$
 BSR    GCHR_FIL
 BMI.S  3$
 CMP.B  #'Z',D7
 BLE.S  2$
 AND.B  #$5F,D7
2$
 MOVE.B D7,(A5)+
 CMP.B  D4,D7
 DBLT   D6,1$

3$
 CLR.B  (A5)
 MOVEQ  #NSIZE-1,D6
 MOVE.L TEMP(A4),A0
SPCR
 CMP.B  (A0)+,D4
 DBEQ   D6,SPCR
 BNE    BDTAIL

 MOVEQ  #7,D6
 MOVEQ  #0,D0
1$
 MOVE.B (A0)+,D7
 CMP.B  D4,D7
 BEQ.S  3$
 SUB.B  #'0',D7
 BMI    BDCNT
 CMP.B  #9,D7
 BLE.S  2$
 SUBQ.B #7,D7
 BMI    BDCNT
 CMP.B  #$F,D7
 BGT    BDCNT
2$
 LSL.L  #4,D0
 ADD.B  D7,D0
 DBRA   D6,1$
3$
 MOVE.L D0,D6

 LEA    RBUFF(A4),A0
 LEA    TRAIL(PC),A1
MOVIT
 MOVE.B (A1)+,(A0)+
 BNE    MOVIT
 LEA    -2(A0),A0

* xbtoa End N %ld %lx E %lx S %lx R %lx\n",n,n,Ceor,Csum,Crot
* MOVE.L D6,D0          ;Bytes in hex
 BSR.S  HEXDEC
 MOVE.L D6,D0           ;Bytes in decimal
 BSR.S  HEXFIL
 MOVE.B D4,(A0)+
 MOVE.B #'E',(A0)+
 MOVE.L CEOR(A4),D0
 BSR.S  HEXFIL
 MOVE.B D4,(A0)+
 MOVE.B #'S',(A0)+
 MOVE.L CSUM(A4),D0
 BSR.S  HEXFIL
 MOVE.B D4,(A0)+
 MOVE.B #'R',(A0)+
 MOVE.L CROT(A4),D0
 BSR.S  HEXFIL
 CLR.B  (A0)+

 LEA    FNAME(A4),A0
 LEA    RBUFF(A4),A1
TCHK
 CMP.B  (A0)+,(A1)+
 BEQ    TCHK
 TST.B  -(A1)
 BEQ    ENDIT

 LEA    FNAME(A4),A0
 BSR    PLIN_CON
 LEA    RBUFF(A4),A0
 BSR    PLIN_CON
 LEA    BDATA(PC),A0
 BRA    ENDIT1


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
 BSR.S  DIVIDE

 MOVE.W (SP)+,D0 ;For 10k
 BSR.S  DIVIDE
 MOVE.L D1,D0

HEXFIL  ;Form 8 ASCII (HEX) digits, leading 0's suppressed
 MOVE.B D4,(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

DIVIDE
 MOVEQ  #3,D3
1$
 DIVU   #10,D0  ;REM,DEC
 SWAP   D0
 OR.B   D0,D1
 ROR.L  #4,D1   ;Rotate remainder
 CLR.W  D0
 SWAP   D0
 DBRA   D3,1$
 RTS

BDCNT
 LEA    BCONT(PC),A0
 BRA.S  ENDIT1

BDHEAD
 LEA    BHEAD(PC),A0
 BRA.S  ENDIT1

BDTAIL
 LEA    BTAIL(PC),A0
 BRA.S  ENDIT1

NOHEAD
 LEA    NHEAD(PC),A0
 BRA.S  ENDIT1

NOTAIL
 LEA    NTAIL(PC),A0
 BRA.S  ENDIT1

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

NREAD
 LEA    NOREAD(PC),A0
 BRA.S  ENDIT1

BDCHR
 ADD.B  #'!',D7
 LEA    BCHR(PC),A0     ;Input char out of range
 MOVE.B D7,(A0)
 BRA.S  ENDIT1

BDZER
 LEA    ZODD(PC),A0     ;z on odd byte
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)


***
DECODE ;D7
***
 CMP.B  #'z',D7
 BNE.S  1$
 TST.B  BCNT(A4)
 BEQ.S  2$
 BRA    BDZER

1$
 SUB.B  #'!',D7
 BMI    BDCHR
 CMP.B  #85,D7
 BGE    BDCHR
 MOVE.B BCNT(A4),D0
 BEQ.S  3$

 MOVE.L WORD(A4),D0
 MOVE.L D0,D1
 ASL.L  #2,D0
 ADD.L  D1,D0   ;W*5

 MOVE.L D0,D1
 ASL.L  #4,D0   ;W(5*16)
 ADD.L  D1,D0   ;W((5*16)+5)

 ADD.L  D7,D0
 MOVE.L D0,WORD(A4)
 CMP.B  #4,BCNT(A4)
 BLT.S  4$
2$
 MOVE.B WORD(A4),D7
 BSR.S  BYTOUT
 MOVE.B WORD+1(A4),D7
 BSR.S  BYTOUT
 MOVE.B WORD+2(A4),D7
 BSR.S  BYTOUT
 MOVE.B WORD+3(A4),D7
 BSR.S  BYTOUT

 CLR.L  WORD(A4)
 CLR.B  BCNT(A4)
 RTS

3$
 MOVE.L D7,WORD(A4)
4$
 ADDQ.B #1,BCNT(A4)
 RTS

***
BYTOUT
***
 AND.L  #$FF,D7
 EOR.L  D7,CEOR(A4)

 MOVE.L D7,D0
 ADD.L  CSUM(A4),D0
 ADDQ.L #1,D0
 MOVE.L D0,CSUM(A4)

 MOVE.L CROT(A4),D0
 LSL.L  #1,D0
 BCC.S  1$
 ADDQ.L #1,D0
1$
 ADD.L  D7,D0
 MOVE.L D0,CROT(A4)
 BRA.S  PCHR_FIL


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


***
PLIN_CON        ;*A0
***
 MOVE.L OUTHAN(A4),D1
 MOVE.L A0,D2
 MOVEQ  #-1,D3
1$
 TST.B  (A0)+
 DBEQ   D3,1$
 NOT.L  D3
 JMP    _LVOWrite(A6)


***
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 Read 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  REOF            ;EOF
 BMI    ENDIT           ;Error

***
GCHR_FIL ;D7
***
 TST.W  RCNT(A4)
 BEQ.S  RFILL
 MOVE.L RPNT(A4),A0
 MOVEQ  #0,D7
 MOVE.B (A0)+,D7
 MOVE.L A0,RPNT(A4)
REOF
 SUBQ.W #1,RCNT(A4)
 RTS

***
GNAM_CON ;Get File name from console
***
 BSR    PLIN_CON
 LEA    FNAME(A4),A0
 BSR    GLIN_CON
 LEA    FNAME(A4),A0
 CLR.B  0(A0,D0.W)
 RTS

* SECTION DATA
DOSNAM DC.B 'dos.library',0
ZODD  DC.B 'z on odd byte',$A,0
BCHR  DC.B '  Char out of range',$A,0
NHEAD DC.B 'No header',$A,0
NTAIL DC.B 'No trailer',$A,0
BHEAD DC.B 'Bad header',$A,0
BTAIL DC.B 'Bad trailer',$A,0
BCONT DC.B 'Bad count',$A,0
BDATA DC.B $A,'Trailer mismatch',$A,0

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

