You are on page 1of 7

My Build of Bit Boffer Audio Cassette Interface

By D.R. Sentz
January, 2015
In 1976-77 I constructed an audio cassette interface for my
homebrew computer. I used the Bit Boffer design by Don
Lancaster, as published in the March 1976 issue of BYTE magazine,
plus the read/write time delay circuits and remote ON/OFF
control circuit described in that same issue of BYTE, in the
article The COMPLEAT Tape Cassette Interface by Jack Hemenway.
My Tx clock circuit is slightly different from the Hemenway
article, per the Bit Boffer requirement for 19200 Hz. Bit
Boffer provides the divide-down to 4800 Hz for the ACIA.
My tape recorder did not have an Aux input, so I added a
20kohm gain control to reduce the Bit Boffers output voltage to
just a few millivolts, for the dynamic microphone input.

1976-77 COMPLEAT Tape Cassette Interface with Bit Boffer

I redrew Figure 1 of the Hemenway article to reflect the


architecture of my build;

Compare to Figure 1 of Jack Hemenway Article, March 1976 BYTE


My build did not work at first. During the troubleshoot I
discovered the following errors in Figure 5 and Figure 6 of the
Bit Boffer article;

The output pin of IC6 was labeled 5, should have been 6.


IC4c and IC4d wiring was incorrect. My markup shows the
correction that made the circuit work.
IC3 in Figure 5 of the article is supposed to be a 4001
chip, as shown in Figure 8, not a 4011.

See photograph below of my markups.

From Page 35 of March 1976 Issue of Byte Magazine


I never did write to BYTE magazine to report the artwork errors.
BYTE reported the IC4 wiring correction in the August 1976 issue,
on page 76, but not the other typos.
I wrote I/O software drivers derived from the examples in the
Hemenway article. I bought a Panasonic RQ-212DAS cassette unit
just for this application.
I saved several programs and utilities to audio tape using this
interface. My file directory is on the next page. The largest
program I saved was the paper tape version of the Resident
Assembler MP-E, from Southwest Technical Products Corporation,
which occupies memory range $0088 to $15B6. I used an ASR33 at
my workplace to load the MP-E paper tape to memory, and then I
wrote the memory range to audio tape using my Bit Boffer.

My Files on Audio Cassette Tape, Thanks to Bit Boffer


January 14, 2015- My Bit Boffer still works. However, I was
always puzzled why I had to specify at least one more byte, to
be written to tape, than the memory range that I intended to
save. Otherwise the read function could not correctly read the
last byte of that range. I recently figured it out and corrected
my tape reader and writer utilities.
The Hemenway article has an error in the example software. The
error always prevents the last byte of the specified memory
range from being written out to the tape. In the test program
named WRITE in Listing 8, the command to turn off the tape
recorder motor is transmitted immediately after the last memory
byte to be written is latched from the ACIA data register to the
ACIA output shift register (i.e., after the Transmit-Data-

Register-Empty signal transitions from Full to Empty). At


300 baud rate it takes another 36.7 milliseconds for the serial
transmission to be completed, but the motor was turned off at
the beginning of that serial transmission. Since my tape write
programs were based on the Hemenway article, they had the same
error.
My solution is to send the last byte to the ACIA a 2nd time, and
then wait for the Data Register Empty signal to transition from
Full to Empty again, before turning off the motor. The
signal goes Empty when the first serial transmission of the
last byte completes. Then the motor can be turned off. The
second serial transmission of the last byte will not get
recorded, because the motor was turned off just after that byte
was latched to the serial output register.
My tape writing utilities now work the way I always thought they
should. The program listing for my minimum version is shown
below. It resides in available memory in the MIKBUG RAM so it
can write out to tape the entire 8K user memory space, $0000
to $1FFF, of my computer.
In the Hemenway article he described an interface test procedure
using Listing 8 that would not reveal the software error,
because he did not say to erase or otherwise alter the entire
target memory space after the writing operation and before the
reading operation.
PUNCHER2 exits with a register dump. The X register displays the
last memory location that was written to the tape. The value
should match the contents of locations $A004-$A005.
Here is my minimum tape reader utility. It resides in the
MIKBUG RAM, so I can load from tape up to the 8K memory space of
my computer without overwriting the tape reader utility.
Program LOADER exits with a register dump only if there was a
read error. Otherwise it exits to MIKBUG without a register dump.
I included the MIKBUG-format object code printouts below so you
can copy/paste the object code to your console terminal after
typing the MIKBUG "L" command.

00010
00020
00030
00040
00050
00060
00070
00080
00090
00100
00110
00120
00130
8010
00140
8011
00150 A002
00160 A002 0002
00170 A004 0002
00190
00200
00210
00220
00230
00240
00250
00260
00270
00280
00290
00300
00310
00320
00330
00340
00350
00360
00370
00380
00390
00400
00410
00420
00430
00440
00450
00440

A048
A048
A04A
A04D
A04F
A051
A054
A057
A059
A05B
A05D
A060
A062
A065
A067
A068
A06A
A06D
A06F
A071
A072
A075
A077
A079
A07A
A07C
A07F

A04A
FE A002
8D 2B
C6 1D
F7 8010
F6 8010
C5 08
26 F9
A6 00
B7 8011
8D 10
BC A004
27 03
08
20 F1
B7 8011
8D 03
8D 09
3F
F6 8010
C5 02
27 F9
39
C6 5F
F7 8010
39

NAM
OPT

PUNCHER2
O,S,NOG OBJECT TAPE AND SYMBOLS

*
* CASSETTE PUNCHER PROGRAM BY DONALD R. SENTZ
* 1977 ORIGINAL, UPDATED JANUARY 2015
* THIS PROGRAM IS USED TO WRITE MEMORY
* TO THE AUDIO CASSETTE UNIT WHICH
* IS INTERFACED TO THE ACIA CHIP ON THE
* MEK6800 BOARD. ENTER START ADDRESS IN
* A002-03, AND END ADDRESS IN A004-05.
* THIS PROGRAM WAS PREPARED USING THE
* RESIDENT EDITOR/ASSEMBLER MP-E.
ACIACT EQU
$8010
ACIA CONTROL REGISTER
ACIADT EQU
$8011
ACIA DATA REGISTER
ORG
$A002
BEGAD RMB
2
START ADDRESS
ENDAD RMB
2
END
ADDRESS

LOOP1
LOOP2

ENDCH

WAIT

RESET

ORG
FDB
LDX
BSR
LDA
STA
LDA
BIT
BNE
LDA
STA
BSR
CPX
BEQ
INX
BRA
STA
BSR
BSR
SWI
LDA
BIT
BEQ
RTS
LDA
STA
RTS
END

B
B
B
B
A
A

$A048
$A04A
BEGAD
RESET
#$1D
ACIACT
ACIACT
#8
LOOP1
0,X
ACIADT
WAIT
ENDAD
ENDCH

GO INITIALIZE ACIA
START MOTOR, DEFINE FORMAT
8 BITS, ODD PARITY, 1 STOP

GET BYTE FROM MEMORY


PUT IT TO I'FACE

LOOP2
ACIADT
WAIT
RESET

ARE WE DONE?
WAIT UNTIL ALL BITS ON TAPE
POINT TO NEXT MEM LOC.
AND KEEP PUTTING
THIS WRITE IS NECESSARY SO
THAT THE PRECEDING WRITE
OP. COMPLETES(JAN/2015)

B
B

ACIACT
#2
WAIT

XMT DATA REG. EMPTY?


IF NOT, WAIT

B
B

#$5F
ACIACT

S00B000050554E4348455232AD
S11EA048A04AFEA0028D2BC61DF78010F68010C50826F9A600B780118D10BC94
S11EA063A00427030820F1B780118D038D093FF68010C50227F939C65FF78008
S105A07E103993
S9

00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
8010
00015
8011
00016
E0E3
00017 A002
00018 A002 0002
00019 A004 0002
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049

A014
A014
A016
A019
A048
A048
A04A
A04D
A04F
A051
A054
A057
A059
A05B
A05E
A060
A062
A064
A066
A068
A069
A06C
A06E
A071
A073
A075
A078
A079

NAM
OPT

OBJECT TAPE AND SYMBOLS


*
* CASSETTE LOADER PROGRAM BY DONALD R. SENTZ
* ORIGINAL 1976, REVISED JAN., 2015
* THIS PROGRAM IS USED TO LOAD MEMORY FROM THE
* AUDIO CASSETTE UNIT INTERFACED THROUGH THE
* ACIA ON THE MEK6800 EVALUATION BOARD.
* ENTER START AND END ADDRESSES IN A002-A005
* BEFORE STARTING THIS PROGRAM AND READY TAPE.
* THIS UPDATED LOADER WAS PREPARED USING
* MACWRITE AND THE RESIDENT ASSEMBLER MP-E.
*
ACIACT EQU
$8010
ACIA CONTROL REGISTER
ACIADT EQU
$8011
ACIA DATA REGISTER
CNTRL EQU
$E0E3
MIKBUG RETURN POINT
ORG
$A002
BEGAD RMB
2
START ADDRESS
ENDAD RMB
2
END
ADDRESS

C6 5F
RESET
F7 8010
39
A04A
FE A002
8D C5
C6 1D
F7 8010
F6 8010
C5 04
26 F9
F6 8010
C5 01
27 F9
C5 70
27 03
8D AC
3F
B6 8011
A7 00
BC A004
26 05
8D 9F
7E E0E3
08
20 E0

LOADER
O,S,NOG

LOOP1
LOOP2

CONT

CONT2

ORG
LDA
STA
RTS
ORG
FDB
LDX
BSR
LDA
STA
LDA
BIT
BNE
LDA
BIT
BEQ
BIT
BEQ
BSR
SWI
LDA
STA
CPX
BNE
BSR
JMP
INX
BRA
END

B
B

B
B
B
B
B
B
B

A
A

$A014
#$5F
ACIACT
$A048
$A04A
BEGAD
RESET
#$1D
ACIACT
ACIACT
#4
LOOP1
ACIACT
#1
LOOP2
#$70
CONT
RESET
ACIADT
0,X
ENDAD
CONT2
RESET
CNTRL
LOOP2

PUT RESET CONTROL WORD


TO ACIA CONTROL REGISTER

GO INITIALIZE ACIA
START MOTOR, DEFINE FORMAT
8 BITS, ODD PARITY, 1 STOP
DATA CARRIER DETECT?
IF NOT, KEEP CHECKING
RCV DATA REG. FULL?
IF NOT, KEEP CHECKING.
ANY ERROR FLAGS SET?
IF NOT, GO READ DATA.
STOP MOTOR
EXIT IF ANY READ ERROR
READ DATA BYTE
PUT IT TO LOC(X)
WAS IT THE LAST BYTE?
IF NOT, CONTINUE
ELSE STOP MOTOR
AND NORMAL EXIT
POINT TO NEXT LOC
AND CONTINUE READING TAPE

TOTAL ERRORS 00000


S00B00004C4F414445522020FD
S109A014C65FF78010395D
S11EA048A04AFEA0028DC5C61DF78010F68010C50426F9F68010C50127F9C514
S11BA0637027038DAC3FB68011A700BCA00426058D9F7EE0E30820E0E1
S9

THE END