I have decided to use the GOSUB/LABEL route, here is a snippet of code to show what it look like ...
Code:
400 DEF FNB(S1)=IP(FP(S1/2^6)*2) ! IsDriveBusy(StatusByte) : returns 0=normal or 1=busy : mask 00100000
405 DEF FNE(S1)=IP(FP(S1/2^5)*2) ! IsDriveInError(StatusByte) : returns 0=normal or 1=error : mask 00010000
410 DEF FNC(S1)=FP(S1/2^4)*2^4 ! GetDriveErrorCode(StatusByte) : returns 0...15=error code : mask 00001111
415 DEF FND(D1)=IP(D1/2^4) ! GetDeviceClass(AccessoryID) : returns 0...15=device class : mask 11110000 4>> 00001111
Code:
440 'ISMSTYPE': ! IN: A / UPD: D / OUT: - ! sub is device at address a mass storage type ?
441 D=DEVAID(A) @ IF FND(D)=1 THEN GOTO 443 ! get accessory id and if device type is a mass storage class then return
442 DISP "Err: Inv Device Type" @ STOP ! display error message then stop the program
443 RETURN ! end sub
Code:
450 'BUSYWAIT': ! IN: A / UPD: S / OUT: - ! sub wait until drive is ready
451 S=SPOLL(A) @ IF FNB(S)=1 THEN GOTO 451 ! loop until drive is no longer busy
452 RETURN ! end sub
Code:
460 'READSTAT': ! IN: A / UPD: - / OUT: S,B,E,C,L ! sub read and decode drive status
461 S=SPOLL(A) @ B=FNB(S) @ E=FNE(S) @ C=FNC(S) ! read drive status and get busy flag, error flag and error code
462 IF E=0 AND B=0 THEN L=0 @ GOTO 465 ! if drive not in error and not busy -> set error level to normal and return
463 IF E=0 AND B=1 THEN L=1 @ GOTO 465 ! if drive not in error but is busy -> set error level to warning and return
464 IF C=7 OR C=9 OR C=10 THEN L=1 ELSE L=2 ! if drive error is recoverable -> set error level to warning otherwise set error level to error
465 RETURN ! end sub
Code:
470 'BUILDMSG': ! IN: B,E,C,L / UPD: - / OUT: M$ ! sub build drive status message
471 IF E=0 AND B=0 THEN M$="" @ GOTO 486 ! drive is normal
472 IF E=0 AND B=1 THEN M$="Drive Busy" @ GOTO 484 ! drive is busy
473 IF C= 7 THEN M$="New Tape" @ GOTO 484 ! new tape has been inserted in the drive and need to be seeked
474 IF C= 9 THEN M$="Rec Number" @ GOTO 484 ! unexpected record number, tape read failed, try to re-read the sector
475 IF C=10 THEN M$="Rec Checksum" @ GOTO 484 ! invalid record checksum, tape read failed, try to re-read the sector
476 IF C= 4 THEN M$="No Tape" @ GOTO 484 ! there is no tape in drive
477 IF C= 8 THEN M$="Time Out" @ GOTO 484 ! no data record has been found on the tape
478 IF C= 3 THEN M$="Tape:EOT+TS" @ GOTO 484 ! unexpected end of tape has been reached AND tape has stalled
479 IF C= 1 THEN M$="End of Tape" @ GOTO 484 ! unexpected end of tape has been reached
480 IF C= 2 THEN M$="Tape Stalled" @ GOTO 484 ! tape has stalled
481 IF C= 5 OR C=6 THEN M$="Device" @ GOTO 484 ! generic device error
482 IF C=12 THEN M$="Tape Size" @ GOTO 484 ! track number greather than 1 has been requested
483 M$="Unknown" ! unknown error (covers code=0, 11, 13, 14 & 15)
484 IF L=1 THEN M$="Wrn:"&STR$(C)&":"&M$ ! warning message
485 IF L=2 THEN M$="Err:"&STR$(C)&":"&M$ ! error message
486 RETURN ! end sub
Code:
490 'REWIND': ! IN: A / UPD: S,B,E,C,L,M$ / OUT: - ! sub rewind tape
491 GOSUB 'BUSYWAIT' @ GOSUB 'READSTAT' ! wait for drive to be ready, then read current status and decode it
492 IF L=2 THEN GOSUB 'BUILDMSG' @ DISP M$ @ STOP ! if error level is error then display error message then stop the program
493 DISP "Rewinding Tape ..." ! tell user the action to be taken
494 SEND UNT UNL LISTEN A DDL 7 @ GOSUB 'BUSYWAIT' ! rewind tape and wait for drive to be ready
495 RETURN ! end sub