Post Reply 
HP-71B BASIC Question
03-16-2021, 12:53 AM (This post was last modified: 03-16-2021 01:22 AM by Sylvain Cote.)
Post: #1
HP-71B BASIC Question
I have created a program that have multiple sub-routines and I have a user defined function (UDF) that need to be called from the main body and from the sub-routines.
The manual and my tests told me that is not possible to call a UDF defined in the main body from a sub-routine.
I am currently obliged to define it multiple times, in the main body and in all sub-routines creating code duplication.
Do any of you have a work around ? (while still using UDF)

Code:
! main body
...
100  DEF FNB(S8)=IP(FP(S8/2^6)*2) ! mask 00100000
105  IF FNB(S)=1 THEN ...
...
500 SUB DECODE(S9,B9,E9,C9,L9)
505  DEF FNB(S8)=IP(FP(S8/2^6)*2) ! duplicate code
510  IF FNB(S9)=1 THEN ...
...
540 END SUB

edit: I am searching for something equivalent to the C++ scoping "::" operator that would allow me to call the UDF defined in main space from a sub-routine space
Find all posts by this user
Quote this message in a reply
03-16-2021, 01:42 AM
Post: #2
RE: HP-71B BASIC Question
(03-16-2021 12:53 AM)Sylvain Cote Wrote:  I have created a program that have multiple sub-routines and I have a user defined function (UDF) that need to be called from the main body and from the sub-routines.
The manual and my tests told me that is not possible to call a UDF defined in the main body from a sub-routine.
I am currently obliged to define it multiple times, in the main body and in all sub-routines creating code duplication.
Do any of you have a work around ? (while still using UDF)

You might have to use GOSUB instead of CALL in order to avoid having to define the function multiple times. It doesn't look like there's any way around the separation of environments.

Tom L
Cui bono?
Find all posts by this user
Quote this message in a reply
03-16-2021, 02:38 AM (This post was last modified: 03-16-2021 03:35 AM by Valentin Albillo.)
Post: #3
RE: HP-71B BASIC Question
.
Hi, Sylvain:

(03-16-2021 12:53 AM)Sylvain Cote Wrote:  I have created a program that have multiple sub-routines and I have a user defined function (UDF) that need to be called from the main body and from the sub-routines.

Not a criticism or nitpicking but you need to use the proper terminology: what you are trying to do is to call an UDF from a subprogram (CALL), not from a subroutine (GOSUB)

Calling a main-program UDF from a subprogram is not possible, they use separate environments. Your options are:
  • 1) Convert your subprograms to main-program subroutines and call them using GOSUB, not CALL. Besides, there's no parameter-passing to subroutines, you'll have to use or assing the proper values yourself to the variables used by the subroutines.
          
  • 2) Convert your main-program UDF to a subprogram, like this:

          main program UDF:        10 DEF FNB(S8)=IP(FP(S8/2^6)*2

                to

          subprogram:       100 SUB FUNB(S8,F) @ F=IP(FP(S8/2^6)*2

    and of course change all calls to the UDF to calls to the equivalent subprogram instead. As the calls are statements, they can't be used while evaluating expressions, you'll have to call the subprogram first and then use the returned value in the expressions.
          
  • 3) In your main program, define a string to hold the function definition, then pass that string to every subprogram and evaluate it using VAL, like this:

          main program:

              10 S$="IP(FP(X/2^6)*2"


          subprogram:
            
              500 SUB DECODE(S9,B9,E9,C9,L9,S$)
              510 X=S9 @ IF VAL(S$)=1 THEN ...

Neither option is ideal, each have their disadvantages but at least you won't have to repeat the UDF in the main program and all subprograms that do use it.

Regards.
V.

  
All My Articles & other Materials here:  Valentin Albillo's HP Collection
 
Visit this user's website Find all posts by this user
Quote this message in a reply
03-16-2021, 09:34 AM
Post: #4
RE: HP-71B BASIC Question
(03-16-2021 12:53 AM)Sylvain Cote Wrote:  edit: I am searching for something equivalent to the C++ scoping "::" operator that would allow me to call the UDF defined in main space from a sub-routine space

Something equivalent exists for the CALL keyword, you can write:
CALL MYSUB IN MYFILE
to call the subprogram MYSUB in the file MYFILE.
But not for UDFs. They are local to the current environment (where they are defined) in the Series 70/80 "Technical BASIC".

The UDF implementation is a major difference relative to the HP BASIC in Series 200/300 ("RMB"), where the UDF are similar to subprograms, with their own environment, and can be called from any subprogram. Drawback of this approach is that they can't access the global variables of the environment that uses them, as is possible in the Series 70/80.

J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
03-17-2021, 02:28 PM
Post: #5
RE: HP-71B BASIC Question
Valentin, criticize or nitpick at will, you are welcome. Wink
Valentin, Tom & Jean-François, you made me realize that I was asking too much from the BASIC language.
I have been spoiled from all the languages/paradigms that I have used since the 1980's and I have difficulty going back to a world that does not even have functional decomposition.
I am currently writing a HP-71B BASIC program that does low level HP-IL control and while the code grows I was trying to bring order to chaos.
I will refactor the code to remove all the CALL/SUB and replace them with GOSUB/LABEL.
I will also need to seriously manage variables names/usage because they becomes global.
Thank you!
Sylvain
Find all posts by this user
Quote this message in a reply
03-17-2021, 05:49 PM (This post was last modified: 03-17-2021 05:55 PM by Valentin Albillo.)
Post: #6
RE: HP-71B BASIC Question
.
Hi again, Sylvain:

(03-17-2021 02:28 PM)Sylvain Cote Wrote:  Valentin, criticize or nitpick at will, you are welcome. Wink

No, no, not at alll, I only tried to point out that you were actually using subprograms, not subroutines as you called them.

Quote:Valentin, Tom & Jean-François, you made me realize that I was asking too much from the BASIC language.

That's patronizing in the extreme.

The HP-71B BASIC dialect is not "the BASIC language" but a 40-year old dialect which was very advanced for a handheld device in its time but 40 years later is nothing but a relic. "The BASIC language" nowadays would be something like MS Visual BASIC in its latest team-oriented incarnations, and you can ask very very much from it and it will deliver, in spades. I've participated in very large commercial projects using it and it worked flawlessly, minimizing the development time and being a pleasure to use.

Quote:I have been spoiled from all the languages/paradigms that I have used since the 1980's and I have difficulty going back to a world that does not even have functional decomposition.

May I remind you that all those "functional decompositions" and other such niceties in the end are converted behind the scenes to a bunch of low-level assembly language operations full of goto's and whatnot. Also, the HP-71B BASIC implementation takes much less than 64 Kb, and I wonder about the size of those advanced languages that even have "functional decomposition". Megabytes ? Gigabytes ?

Last but not least, the possibility of sharing variables and other objects among the main program and subprograms already existed in HP's BASIC in the Series 80 and other models using so-called RMB BASIC, by using the COMMON statement to define a list of elements (don't remember right now if that included UDFs) to share among them. The 71B BASIC dialect does not implement that statement but that doesn't imply that "BASIC" in general doesn't.

Quote:I will refactor the code to remove all the CALL/SUB and replace them with GOSUB/LABEL.
I will also need to seriously manage variables names/usage because they becomes global.

Your decision, but it seems to me that this is the hardest way of the three I suggested. If your user-defined functions are single-line (as opposed to multi-line) no matter how long, it would be most convenient to use the S$ approach. Which is more, even if the definition takes 1,000 characters, you can dimension a 1,000-char string and VAL will evaluate it without complaining, which a single-line UDF can't do, being limited to ~90 chars or less.

On the other hand, replacing your subprograms with subroutines will force you to redesign your variable names so there's no conflicts among them and might also incur in unforeseen side effects (OPTION BASE, for instance) as you're merging a number of different local environments into a single one. I think this goes against maintanability and dismisses the many good points inherent in using subprograms in the first place.

Best regards.
V.

  
All My Articles & other Materials here:  Valentin Albillo's HP Collection
 
Visit this user's website Find all posts by this user
Quote this message in a reply
03-17-2021, 07:30 PM (This post was last modified: 03-17-2021 07:31 PM by Sylvain Cote.)
Post: #7
RE: HP-71B BASIC Question
(03-17-2021 05:49 PM)Valentin Albillo Wrote:  
(03-17-2021 02:28 PM)Sylvain Cote Wrote:  Valentin, criticize or nitpick at will, you are welcome. Wink
No, no, not at alll, I only tried to point out that you were actually using subprograms, not subroutines as you called them.
Quote:Valentin, Tom & Jean-François, you made me realize that I was asking too much from the BASIC language.
That's patronizing in the extreme.
ROTFL, I did ask for it! Big Grin

You are right, I should have wrote: "Valentin, Tom & Jean-François, you made me realize that I was asking too much from the HP-71B BASIC language implementation"
Since this thread was about the HP-71B BASIC question, I wrongly assumed that my statement would be taken in that context, sorry about that.

I also agree that other BASIC implementations has more advanced concepts build into them.

Sure, all higher level languages with higher level abstractions are at the end converted to assembly language that are full of goto and gosub.

IMHO the 64KB limit is a moot point because there have been other interpreters created that has support for more advance concept and runs within that space constraint.
The HP-71B machine was part of the BASIC rage that span the 1970's & 1980's and that's ok.

Now I have to decide how I will refactor my program.

Thank you Valentin for your invaluable input, I mean it.

Best regards,

Sylvain
Find all posts by this user
Quote this message in a reply
03-18-2021, 07:56 AM
Post: #8
RE: HP-71B BASIC Question
(03-17-2021 07:30 PM)Sylvain Cote Wrote:  
(03-17-2021 05:49 PM)Valentin Albillo Wrote:  No, no, not at alll, I only tried to point out that you were actually using subprograms, not subroutines as you called them.
That's patronizing in the extreme.
ROTFL, I did ask for it! Big Grin

You are right, I should have wrote: "Valentin, Tom & Jean-François, you made me realize that I was asking too much from the HP-71B BASIC language implementation"
Since this thread was about the HP-71B BASIC question, I wrongly assumed that my statement would be taken in that context, sorry about that.

I understood what you meant.

Tom L
Cui bono?
Find all posts by this user
Quote this message in a reply
03-18-2021, 11:02 AM (This post was last modified: 03-18-2021 11:06 AM by Sylvain Cote.)
Post: #9
RE: HP-71B BASIC Question
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
Find all posts by this user
Quote this message in a reply
03-19-2021, 09:01 AM (This post was last modified: 03-19-2021 09:28 AM by J-F Garnier.)
Post: #10
RE: HP-71B BASIC Question
(03-18-2021 11:02 AM)Sylvain Cote Wrote:  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

Sylvain, may I suggest some improvements?
You may implement or even replace these UDFs using the more efficient binary functions of the HP-IL ROM, for instance:
replace IP(FP(S1/2^6)*2) with BIT(S1,5)
replace FP(S1/2^4)*2^4 with BINAND(S1,15)
There is no bit binary shift operation in the HP-71 BASIC but the integer division can be used, and you can rewrite IP(D1/2^4) as just (D1 DIV 16).

J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
03-19-2021, 07:07 PM
Post: #11
RE: HP-71B BASIC Question
(03-19-2021 09:01 AM)J-F Garnier Wrote:  
(03-18-2021 11:02 AM)Sylvain Cote Wrote:  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

Sylvain, may I suggest some improvements?
You may implement or even replace these UDFs using the more efficient binary functions of the HP-IL ROM, for instance:
replace IP(FP(S1/2^6)*2) with BIT(S1,5)
replace FP(S1/2^4)*2^4 with BINAND(S1,15)
There is no bit binary shift operation in the HP-71 BASIC but the integer division can be used, and you can rewrite IP(D1/2^4) as just (D1 DIV 16).

J-F
Bonjour Jean-François,
The last time I have done serious programming on the HP-71B was in the 1980's.
After spending a lot more hours than intended on that project, it is starting to come back, but man I am seriously rusted on that platform.
Nice optimizations, tank you very much.
Sylvain
Find all posts by this user
Quote this message in a reply
03-20-2021, 12:51 AM
Post: #12
RE: HP-71B BASIC Question
(03-19-2021 07:07 PM)Sylvain Cote Wrote:  The last time I have done serious programming on the HP-71B was in the 1980's.
After spending a lot more hours than intended on that project, it is starting to come back, but man I am seriously rusted on that platform.
Nice optimizations, tank you very much.


A few simple additional ones, many of them avoid unnecessary GOTO's (slow and unsightly):

1) Your original (sans comments):

      440 'ISMSTYPE':
      441 D=DEVAID(A) @ IF FND(D)=1 THEN GOTO 443
      442 DISP "Err: Inv Device Type" @ STOP
      443 RETURN


Somewhat optimized:

      440 'ISMSTYPE':
      441 D=DEVAID(A) @ IF FND(D)=1 THEN RETURN
      442 DISP "Err: Inv Device Type" @ STOP
      443 RETURN



2) Your original (sans comments):

      450 'BUSYWAIT':
      451 S=SPOLL(A) @ IF FNB(S)=1 THEN GOTO 451
      452 RETURN


Somewhat optimized:

      450 'BUSYWAIT':
      451 S=SPOLL(A) @ IF FNB(S) THEN 451
      452 RETURN


If you can use the JPC ROM:

      450 'BUSYWAIT':
      451 REPEAT @ S=SPOLL(A) @ UNTIL NOT FNB(S)
      452 RETURN



3) Your original (sans comments):

      460 'READSTAT':
      461 S=SPOLL(A) @ B=FNB(S) @ E=FNE(S) @ C=FNC(S)
      462 IF E=0 AND B=0 THEN L=0 @ GOTO 465
      463 IF E=0 AND B=1 THEN L=1 @ GOTO 465
      464 IF C=7 OR C=9 OR C=10 THEN L=1 ELSE L=2
      465 RETURN


Somewhat optimized:

      460 'READSTAT':
      461 S=SPOLL(A) @ B=FNB(S) @ E=FNE(S) @ C=FNC(S)
      462 IF NOT E AND NOT B THEN L=0 @ RETURN
      463 IF NOT E AND B THEN L=1 @ RETURN
      464 IF C=7 OR C=9 OR C=10 THEN L=1 ELSE L=2
      465 RETURN



4) Your original (sans comments):

      470 'BUILDMSG'
      471 IF E=0 AND B=0 THEN M$="" @ GOTO 486
      472 IF E=0 AND B=1 THEN M$="Drive Busy" @ GOTO 484
      473 IF C= 7 THEN M$="New Tape" @ GOTO 484
      474 IF C= 9 THEN M$="Rec Number" @ GOTO 484
      475 IF C=10 THEN M$="Rec Checksum" @ GOTO 484
      476 IF C= 4 THEN M$="No Tape" @ GOTO 484
      477 IF C= 8 THEN M$="Time Out" @ GOTO 484
      478 IF C= 3 THEN M$="Tape:EOT+TS" @ GOTO 484
      479 IF C= 1 THEN M$="End of Tape" @ GOTO 484
      480 IF C= 2 THEN M$="Tape Stalled" @ GOTO 484
      481 IF C= 5 OR C=6 THEN M$="Device" @ GOTO 484
      482 IF C=12 THEN M$="Tape Size" @ GOTO 484
      483 M$="Unknown"
      484 IF L=1 THEN M$="Wrn:"&STR$(C)&":"&M$
      485 IF L=2 THEN M$="Err:"&STR$(C)&":"&M$
      486 RETURN


Somewhat optimized and if you can use the JPC ROM:

      470 'BUILDMSG'
      471 IF NOT E AND NOT B THEN M$="" @ RETURN
      472 IF NOT E AND B THEN M$="Drive Busy" @ GOTO 484
      473 SELECT C @ CASE 7 @ M$="New Tape"
      474 CASE 9 @ M$="Rec Number"
      475 CASE 10 @ M$="Rec Checksum"
      476 CASE 4 @ M$="No Tape"
      477 CASE 8 @ M$="Time Out"
      478 CASE 3 @ M$="Tape:EOT+TS"
      479 CASE 1 @ M$="End of Tape"
      480 CASE 2 @ M$="Tape Stalled"
      481 CASE 5,6 @ M$="Device"
      482 CASE 12 @ M$="Tape Size"
      483 CASE ELSE @ M$="Unknown" @ END SELECT
      484 IF L=1 THEN M$="Wrn:"&STR$(C)&":"&M$
      485 IF L=2 THEN M$="Err:"&STR$(C)&":"&M$
      486 RETURN



5) Your original (sans comments):

      490 'REWIND':
      491 GOSUB 'BUSYWAIT' @ GOSUB 'READSTAT'
      492 IF L=2 THEN GOSUB 'BUILDMSG' @ DISP M$ @ STOP
      493 DISP "Rewinding Tape ..."
      494 SEND UNT UNL LISTEN A DDL 7 @ GOSUB 'BUSYWAIT'y
      495 RETURN


Somewhat optimized:

490 'REWIND':
      491 GOSUB 'BUSYWAIT' @ GOSUB 'READSTAT'
      492 IF L=2 THEN GOSUB 'BUILDMSG' @ DISP M$ @ STOP
      493 DISP "Rewinding Tape ..."
      494 SEND UNT UNL LISTEN A DDL 7 @ GOTO 'BUSYWAIT'

         (line 495 is now unnecessary and can be deleted)

Hope that helps, make sure and check that they work Ok.
Have a nice weekend and best regards.
V.

  
All My Articles & other Materials here:  Valentin Albillo's HP Collection
 
Visit this user's website Find all posts by this user
Quote this message in a reply
03-20-2021, 09:23 AM (This post was last modified: 03-20-2021 09:35 AM by J-F Garnier.)
Post: #13
RE: HP-71B BASIC Question
(03-20-2021 12:51 AM)Valentin Albillo Wrote:  A few simple additional ones, many of them avoid unnecessary GOTO's (slow and unsightly):

1) Your original (sans comments):

      440 'ISMSTYPE':
      441 D=DEVAID(A) @ IF FND(D)=1 THEN GOTO 443
      442 DISP "Err: Inv Device Type" @ STOP
      443 RETURN


Somewhat optimized:

      440 'ISMSTYPE':
      441 D=DEVAID(A) @ IF FND(D)=1 THEN RETURN
      442 DISP "Err: Inv Device Type" @ STOP
      443 RETURN

Probably a matter of programming style, but I would rewrite it as:

440 'ISMSTYPE':
441 D=DEVAID(A)
442 IF FND(D)=0 THEN DISP "Err: Inv Device Type" @ STOP
443 RETURN


There are as many programming styles as programmers !

Quote:Somewhat optimized and if you can use the JPC ROM:
[...]

Yes! If you want to write better structured code, the JPC ROM is a must, with it's structured programming constructions modelled from the Series 200/300 HP BASIC.

J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
03-20-2021, 01:03 PM
Post: #14
RE: HP-71B BASIC Question
Thank you Valentin and Jean-François for your comments, greatly appreciated.
I am not the final consumer of this program, so I have the following hardware constraint: HP-71B, HP-IL and ~140KB of main memory, so no JPC for now Sad.
For the development phase, I have purposely made the choice to only have one exit point per sub-routine and to have the code logic reversed in some parts to have more freedom for error handling in case I need it.
The final optimized code will include your suggestions when possible.
Best regards,
Sylvain
Find all posts by this user
Quote this message in a reply
03-22-2021, 10:31 PM
Post: #15
RE: HP-71B BASIC Question
I just published the final program in the General Software Library section (HERE).
Any comments, suggestions, bugs report, etc are welcome.
Sylvain
Find all posts by this user
Quote this message in a reply
03-24-2021, 10:05 AM
Post: #16
RE: HP-71B BASIC Question
(03-22-2021 10:31 PM)Sylvain Cote Wrote:  I just published the final program in the General Software Library section (HERE).
Any comments, suggestions, bugs report, etc are welcome.
Sylvain

Now that we know the final purpose of your program, I'm curious.
What kind of system is using the same cassette type?
Did you check yourself that these cassettes are readable in a 82161 drive?

Some months ago, I have been contacted by a person who wanted to buy a PIL-Box to read cassettes used in a non-HP system.
He too wanted to use a 82161 drive to read them.
I provided the PIL-Box, explicitly saying I can't guarantee it will work, but didn't have feedback then.
It was to read cassettes used in an old Data East DECO system.

BTW, I advised this person to try my ILvLIF utility (together with the PIL-Box and the 82161) to make an image of the cassettes.

J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
03-24-2021, 10:49 AM
Post: #17
RE: HP-71B BASIC Question
(03-24-2021 10:05 AM)J-F Garnier Wrote:  It was to read cassettes used in an old Data East DECO system.

Something like this?



Greetings,
    Massimo

-+×÷ ↔ left is right and right is wrong
Visit this user's website Find all posts by this user
Quote this message in a reply
03-24-2021, 12:40 PM
Post: #18
RE: HP-71B BASIC Question
(03-24-2021 10:05 AM)J-F Garnier Wrote:  BTW, I advised this person to try my ILvLIF utility (together with the PIL-Box and the 82161) to make an image of the cassettes.

J-F

I recommended ILvLIF at the very start of the exploration of these tapes, as dumping the tape to a PC disk file is its very purpose. Since the tapes contained non-HP data, using ILvLIF was deemed unlikely to succeed, and with an old tape, not in great shape (e.g. the pressure pad needed to be replaced) they did not want to possibly wear or damage the tape. I would have tried it anyhow, but in the end, it appears it likely would not have succeeded any better.

But it's not too late to try, I plan to suggest doing so now when we meet on Saturday.

--Bob Prosperi
Find all posts by this user
Quote this message in a reply
03-24-2021, 04:51 PM
Post: #19
RE: HP-71B BASIC Question
(03-24-2021 12:40 PM)rprosperi Wrote:  
(03-24-2021 10:05 AM)J-F Garnier Wrote:  BTW, I advised this person to try my ILvLIF utility (together with the PIL-Box and the 82161) to make an image of the cassettes.

I recommended ILvLIF at the very start of the exploration of these tapes, as dumping the tape to a PC disk file is its very purpose. Since the tapes contained non-HP data, using ILvLIF was deemed unlikely to succeed, and with an old tape, not in great shape (e.g. the pressure pad needed to be replaced) they did not want to possibly wear or damage the tape. I would have tried it anyhow, but in the end, it appears it likely would not have succeeded any better.

The ILvLIF code would have to be tweaked a bit, to bypass the check for a LIF type volume and set the right tape parameters (# of sectors). Should not be too difficult.

Quote:But it's not too late to try, I plan to suggest doing so now when we meet on Saturday.

? Are you/were you involved in these tape recovery? The tapes from Mark mentioned by Sylvain, or the tapes from Mike (the guy who bought me a PIL-Box in Aug.2020)?

J-F
Visit this user's website Find all posts by this user
Quote this message in a reply
03-24-2021, 07:36 PM
Post: #20
RE: HP-71B BASIC Question
(03-24-2021 04:51 PM)J-F Garnier Wrote:  The ILvLIF code would have to be tweaked a bit, to bypass the check for a LIF type volume and set the right tape parameters (# of sectors). Should not be too difficult.

If it's simple and you have the time, please do issue a test version. It can't hurt...

(03-24-2021 04:51 PM)J-F Garnier Wrote:  ? Are you/were you involved in these tape recovery? The tapes from Mark mentioned by Sylvain, or the tapes from Mike (the guy who bought me a PIL-Box in Aug.2020)?

This is a project (attempting to extract non-HP data from some compatible tapes) being done by a crew at HPCC (so with Mark), and is discussed bi-weekly during the virtual HPCC meetings (you see, we can't enough zoom sessions during the week with our jobs and family virtual meetings...). This is where I suggested ILvLIF, and where an initially very simple program to get the raw data began, and ultimately morphed into the more professional solution crafted by Sylvain.

--Bob Prosperi
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 2 Guest(s)