Classic Computer Magazine Archive COMPUTE! ISSUE 30 / NOVEMBER 1982 / PAGE 199

Copy Atari Boot Tapes To Disk

C. Scott Davis
Broomfield, CO

If you're an Atari owner who purchased a disk drive after you bought your initial system, probably one of the first things you did was transfer your program library from cassette to diskette. I know I did. Everything was going along fine until I got to a boot tape. They're the ones you load by powering-up the system while depressing the START key. The game "SHOOT" appearing in the September 1981 issue of COMPUTE! is an example.

Not being satisfied with leaving several programs on cassette, I had to find a way to put them on disk. After a little research I developed a program that did the job. Considerable credit goes to Bob Nalbone, who had already developed his own program to read and display data from cassette tapes.

To use the program, simply boot up your system with the BASIC cartridge in place, the disk drive turned on with a DOS disk inserted, and a blank formatted disk handy. Run the program from this article. When finished, you should have a boot disk containing the program from your boot tape. A boot disk is loaded by powering up your disk drive, inserting the disk, and then powering up your computer while depressing the START key.

Here's an explanation of the program:

Lines 180 - 210 read the first four bytes of information from the tape. The number of records and starting address for loading are contained in bytes two, three, and four.

Lines 220 -370 display system parameters as well as information just obtained from the boot tape. This could be useful if the tape can't be copied because of lack of memory space.

Line 380 calculates the starting address for a work area to be used in transferring data from tape to disk. 500 bytes above the area used by BASIC was selected.

Line 390 calculates the address of the last location required for the work space.

Lines 400 - 480 check to make sure your system has sufficient space to make the transfer. Note that a boot tape may contain as many as 256 records (128 bytes each) requiring a total of 32K of free space. Most tapes should be much smaller.

Lines 490 - 570 place the code for a short machine language routine into reserved memory starting at location 1536 decimal. This routine will read the tape and store the data in the work area previously defined. Machine language is required because BASIC isn't fast enough for more than the first record on the tape. Table 1 shows the assembly language version of this code.

Line 620 opens the cassette for input. The parameter 128 specifies data with short inter-record gaps.

Line 630 calls the routine to read the tape. The work area starting address and the tape length in bytes are passed via the USR function.

Lines 650 - 670 check for an error in the tape reading attempt.

Lines 720 - 740 set up parameters for writing data onto disk. The locations and values used were derived from the Atari Technical Users Notes.

Lines 750 - 800 provide a routine to write a single sector of data to disk. See Table 2.

Lines 810 - 870 provide a loop to manipulate several parameters and call the machine routine. The variable START contains the starting address of the next 128 bytes of data to be written.

Line 820 POKEs the low byte of the STARTing address into memory.

Line 830 POKEs the high byte of START into memory.

Line 840 takes care of the disk sector number to be written.

Line 850 calls the USR routine to do the write to disk.

Line 860 increments the starting address for the next write operation.

Table 1.

Decimal Data Assembly Code
104 PLA Pull the number of USR parameters from the stack
162,16 LDX#$10 Place $ 10 into the x register for an offset into IOCB # 1
169,7 LDA #$07 $07 is control code for character read operation
157,66,3 STA$0342,X Place that $07 into ICCOM of IOCB#l
104 PLA Pull the high byte of variable START from the slack
157,69,3 STA$0345,X Place it into ICBAH of IOCB#1
104 PLA Pull the low byte of START from the stack
157,68,3 STA$0344,X Place it into ICBAL of IOCB#I
104 PLA Pull the high byte of variable FLEN From the stack
157,73,3 STA $0349,X Place it into ICBLH of IOCB # I
104 PLA Pull the low byte of FLEN from the slack
157,72,3 STA$0348,X Place it into ICBLL of IOCB# 1
32,86,228 JSR $1,153 Jump to CIOV
16,4 BPL$04 Conditional branch forward by 4 if no error
169,1 LDA $01 Puta$01 in A
133,212 STA$D4 Place the 1 in the USR return location
96 RTS Done

Table 2.

Decimal Data Assembly Code
104 PLA Pull the number of USR parameters from the stack
32,83,228 JSR$E453 Jump to DSKINV to writes sector
96 RTS Done
100 GRAPHICS O
110 DIM A$(1)
120 PRINT
130 PRINT "PLACE BOOT TAPE IN PLAYER"
140 PRINT "REWIND TAPE - ";
150 "DEPRESS PLAY BUTTON"
160 "PRESS RETURN KEY"
170 PRINT
180 OPEN #l,4,O,"C:"
190 GET #1,A:GET #1,NREC
200 GET #1,ADL:GET #1,ADH
210 CLOSE #1
220 PRINT "SYSTEM PARAMETERS:"
230 PRINT
240 BTOP = PEEK(144) + 256*PEEK(145)
250 PRINT "BASIC MEMTOP = ":BTOP
260 OTOP = PEEK(741) + 256*PEEK(742)
270 PRINT "OS MEMTOP = ";OTOP
280 PRINT "FREE RAM = " ;OTOP-BTOP
290 PRINT
300 START = ADL + 256*ADH
310 PRINT "YOUR BOOT TAPE NORMALLY"
320 PRINT "LOADS STARTING AT ";START
330 IF NREC = 0 THEN NREC = 256
340 PRINT "CONTAINS ";NRECs" RECORDS"
350 FLEN = 128*NREC
360 PRINT PRINT " = ;" ;FLEN; " BYTES"
370 PRINT
380 START = BTOP + 500
390 LAST = START + FLEN
400 IF LAST<OTOP THEN 490
410 PRINT "WORK AREA REQUIRED"
420 PRINT
430 PRINT START, " TO " ;LAST
440 PRINT
450 PRINT "INSUFFICIENT FREE RAM"
460 PRINT
470 PRINT "SORRY"
480 STOP
490 FOR A = 1536 TO 1569
500 READ D
510 POKE A,D
520 NEXT A
530 DATA 104, 162, 16, 169, 7, 157, 66, 3
540 DATA 104, 157, 69, 3, 104, 157, 68, 3
550 DATA 104, 157, 73, 3, 104, 157, 72, 3
560 DATA 32, 86, 228, 16, 4, 169, 1, 133, 212
570 DATA 96
580 PRINT "REWIND THE TAPE AGAIN"
590 PRINT "DEPRESS PLAY BUTTON"
600 PRINT "PRESS RETURN"
610 PRINT
620 OPEN #1, 4, 128, "C:"
630 X = USR (1536.START, FLEN)
640 CLOSE #1
650 IF X< >1 THEN 680
660 PRINT "TAPE READ ERROR"
670 STOP
680 PRINT "PUT A FORMATTED DISK IN"
690 PRINT "DRIVE #1 - PRESS RETURN"
700 INPUT A$
710 PRINT
720 POKE 769, 1:REM DUNIT = 1
730 POKE 77O, 87:REM WRITE = 87
740 POKE 779, 0:REM DAUX1 = O 1
750 FOR A = 1536 TO 1540
760 READ D
770 POKE A, D
780 NEXT A
790 DATA 104, 32, 83, 228
800 DATA 96
810 FOR SECTOR = 1 TO NREC
820 POKE 772, START-256*INT(START/256)
830 POKE 773, INT(START/256)
840 POKE 778, SECTOR
850 X = USR (1536)
860 START = START + 128
870 NEXT SECTOR
880 PRINT
890 PRINT "DONE"
900 END