RE: Old HP-71 tapes from the 80's uploaded
One way of doing this ...
Using lifutils
- On the computer
- Create a 128KB virtual cassette (LIF volume)
Code:
lifinit -z -m cass tape_01.dat 32
- Name the virtual cassette
Code:
liflabel tape_01.dat TAPE01
- Copy the following HP-71 BASIC program into a text file named "tapedump.txt"
Code:
10 ! TAPEDUMP @Copyrights 2021, Sylvain Cote
11 ! last updated on: 2021-03-20 21h10 EDT
12 ! Program: do a sector by sector tape dump to a file in main memory (~130KB)
13 ! Needs : 71B, 82401A, ~140KB of main RAM
29 ! ----:
30 ! A : DriveAddress (constant)
31 ! B : DriveBusyFlag
32 ! C : DriveErrorCode
33 ! D : DeviceAccessoryID
34 ! E : DriveErrorFlag
35 ! L : DriveErrorLevel
36 ! L0 : InputBufferLength
37 ! L2 : LogDriveError
38 ! R0 : ActiveReadTimes
39 ! R1 : MaxReadTimes (constant)
40 ! S : DriveStatus
41 ! S0 : TapeSectorActive
42 ! S1 : TapeSectorNumbers (constant)
43 ! S2 : TapeSectorSize (constant)
44 ! S3 : TapeSeekFlag : tell the drive to do a tape seek if set to 1
45 ! T1 : TapeTrackNumbers (constant)
50 ! B0$ : InputBuffer
51 ! M$ : DriveErrorLevel
52 ! ----:
100 OPTION BASE 0
105 DIM B0$[256]
110 IMAGE #,256A
115 A=1 @ R1=3 @ T1=2 @ S1=256 @ S2=256
120 S=0 @ B=0 @ E=0 @ C=0 @ L=0 @ M$=""
125 B0$="" @ L0=0 @ D=0 @ L2=0 @ R0=0
130 SFLAG -1 @ PURGE TD @ PURGE TE @ CFLAG -1
135 CREATE TEXT TD @ CREATE TEXT TE
140 ASSIGN #1 TO TD @ ASSIGN #2 TO TE
145 SFLAG -23
150 DELAY 0,0
155 RESET HPIL @ RESTORE IO
160 GOSUB 'AIDCHECK'
165 GOSUB 'REWIND'
170 S3=1
175 FOR T0=0 TO T1-1
180 FOR S0=0 TO S1-1
185 GOSUB 'READSEC'
190 NEXT S0
195 NEXT T0
200 GOSUB 'REWIND'
205 ASSIGN #1 TO * @ ASSIGN #2 TO *
210 CFLAG -23 @ DELAY 1,1/8
215 DISP "DUMP DONE"
220 END
500 ! device accessory id check
505 'AIDCHECK': ! IN: A / UPD: D / OUT: -
510 ! D=DEVAID(A) @ IF D DIV 16#1 THEN DISP "Err: Invalid Device" @ STOP
515 D=DEVAID(A) @ IF D#16 THEN DISP "Err: Invalid Device" @ STOP
520 RETURN
525 ! loop until drive is ready
530 'BUSYWAIT': ! IN: A / UPD: S / OUT: -
535 'BW': S=SPOLL(A) @ IF BIT(S,5)=1 THEN GOTO 'BW'
540 RETURN
545 ! reset drive status variables
550 'RSETSTAT': ! IN: A / UPD: S,B,E,C,L / OUT: -
555 S=0 @ B=0 @ E=0 @ C=0 @ L=0
560 RETURN
565 ! read & decode drive status byte
570 'READSTAT': ! IN: A / UPD: - / OUT: S,B,E,C,L
575 S=SPOLL(A) @ B=BIT(S,5) @ E=BIT(S,4) @ C=BINAND(S,15)
580 IF E=0 AND B=0 THEN L=0 @ RETURN
585 IF E=0 AND B=1 THEN L=1 @ RETURN
590 IF C=9 OR C=10 THEN L=1 ELSE L=2
595 RETURN
600 ! build status message
605 'BUILDMSG': ! IN: B,E,C,L / UPD: - / OUT: M$
610 IF E=0 AND B=0 THEN M$="" @ RETURN
615 IF E=0 AND B=1 THEN M$="Drive Busy" @ GOTO 'BM'
620 IF C=9 THEN M$="Rec Number" @ GOTO 'BM'
625 IF C=10 THEN M$="Rec Checksum" @ GOTO 'BM'
630 IF C=7 THEN M$="New Tape" @ GOTO 'BM'
635 IF C=4 THEN M$="No Tape" @ GOTO 'BM'
640 IF C=8 THEN M$="Time Out" @ GOTO 'BM'
645 IF C=3 THEN M$="Tape:EOT+TS" @ GOTO 'BM'
650 IF C=1 THEN M$="End of Tape" @ GOTO 'BM'
655 IF C=2 THEN M$="Tape Stalled" @ GOTO 'BM'
660 IF C=5 OR C=6 THEN M$="Device" @ GOTO 'BM'
665 IF C=12 THEN M$="Tape Size" @ GOTO 'BM'
670 M$="Unknown"
675 'BM': ! build message
680 IF L=1 THEN M$="Wrn:"&STR$(C)&":"&M$
685 IF L=2 THEN M$="Err:"&STR$(C)&":"&M$
690 RETURN
695 ! verify that drive is ready and not in error
700 'PRECHECK': ! IN: A / UPD: S,B,E,C,L,M$ / OUT: -
705 GOSUB 'BUSYWAIT' @ GOSUB 'READSTAT' @ M$=""
710 IF L=2 THEN GOSUB 'BUILDMSG' @ DISP M$ @ STOP
715 RETURN
720 ! rewind drive tape
725 'REWIND': ! IN: A / UPD: S,B,E,C,L,M$ / OUT: -
730 GOSUB 'PRECHECK'
735 DISP "Rewinding Tape ..."
740 SEND UNT UNL LISTEN A DDL 7
745 GOSUB 'BUSYWAIT'
750 RETURN
755 ! position drive head to the specified track & sector
760 'SEEK': ! IN: A,T0,S0 / UPD: S,B,E,C,L,M$ / OUT: -
765 GOSUB 'PRECHECK'
770 DISP "Seek: T="&STR$(T0)&" S="&STR$(S0)
775 SEND UNT UNL MTA LISTEN A DDL 4 DATA T0 DATA S0
780 GOSUB 'BUSYWAIT'
785 RETURN
790 ! Set Drive in Read Mode - Drive Fill Buffer 0 with Current Sector
795 'READMODE': ! IN: A / UPD: - / OUT: -
800 DISP "Read mode activated"
805 SEND UNT UNL TALK A DDT 2
810 RETURN
815 ! Read Sector
820 'READSEC': ! IN: A,R1,T0,S0,S2,S3,#1,#2 / UPD: R0,S,B,E,C,L,M$,B0$,L0,S3 / OUT: -
825 FOR R0=1 TO R1
830 IF S3=1 THEN GOSUB 'SEEK' @ GOSUB 'READMODE' @ S3=0
835 DISP "Read T:"&STR$(T0)&" S:"&STR$(S0)&" #"&STR$(R0)
840 ENTER :A USING 110;B0$ @ L0=LEN(B0$)
845 GOSUB 'BUSYWAIT' @ GOSUB 'READSTAT'
850 IF L=0 AND L0=S2 THEN PRINT #1;B0$ @ RETURN
855 IF L=0 THEN DISP "Wrn: Inv.Rec.Length" @ PRINT #2;B0$ @ BEEP 440,1 @ RETURN
860 IF L=1 THEN GOSUB 'BUILDMSG' @ DISP M$ @ BEEP 523,1 @ S3=1
865 IF L=2 THEN GOSUB 'BUILDMSG' @ DISP M$ @ STOP
870 NEXT R0
875 PRINT #2;":T="&DTH$(T0)[5]&":S="&DTH$(S0)[4,5]&":E="&DTH$(S)[5]&":"
880 DISP "Wrn: Skipped Bad Rec." @ BEEP 440,1 @ S3=1
885 RETURN
- Add the program file as a LIF text file to the LIF volume
- Unix
Code:
cat tapedump.txt | textlif TAPEDUMP | lifput tape_01.dat
- Windows
Code:
type tapedump.txt | textlif TAPEDUMP | lifput tape_01.dat
- Show virtual cassette content
Code:
Volume : TAPE01 , formatted : 03/05/24 22:00:00
Tracks: 2 Surfaces: 1 Blocks/Track: 256 Total size: 512 Blocks, 131072 Bytes
TAPEDUMP TEXT 4864/4864 03/05/24 22:31:46
1 files (32 max), last block used: 24 of 512
- Load the virtual cassette into a mass storage emulator (pyILPER, ILPER, etc)
- Connect a 71B to the mass storage emulator (71B+PilBox, Emu71, etc.)
- On the HP-71B
- Reset HP-IL loop
- Show tape content
Code:
NAME S TYPE LEN DATE TIME
TAPEDUMP TEXT 4864 05/03/24 22:31
- Copy text file into the 71B
- Show 71B file system content
Code:
NAME S TYPE LEN DATE TIME PORT
workfile BASIC 0 03/05/24 00:11
TAPEDUMP TEXT 4864 05/03/24 23:08
- Transform text file into a BASIC program
Code:
TRANSFORM TAPEDUMP INTO BASIC
- Show 71B file system content
Code:
NAME S TYPE LEN DATE TIME PORT
workfile BASIC 0 03/05/24 00:11
TAPEDUMP BASIC 3708 05/03/24 23:08
- List program to printer
- Compare listing with the original source file
Sylvain Côté
|