Last edited · 19 revisions  

 


HP-85 BASIC PROGRAM CONTROL BLOCK

 BYTE#  DESCRIPTION              		OFFSET NAME
 -----  ---------------------------------- -----------
   0 NAME[0]
   1 NAME[1]
   2 NAME[2]
   3 NAME[3]
   4 NAME[4]
   5 NAME[5]
   6 program TYPE (see below) P.TYPE
   7-10 program LENGTH (2 bytes) P.LEN
  11-12 COM length or SUB RTN (2 bytes) P.COM or P.SUBR
  13-14 DATA line ptr (2 bytes) P.DATL
  15-16 DATA item ptr (2 bytes) P.DATA
  17-20 Reserved Mem Pointer (2 bytes) P.RMEM
  21 Active FOR/NEXT counter P.FCNT
  22 Active GOSUB counter P.GCNT
  23 not used
  24 not used
  25 Security bits P.SFLG
  26-27 Security code (2 bytes) P.SCOD
   MAIN program starts here
  30-31 4 BCD digits LINE NUMBER (2 bytes) P.GO
  32 LENGTH of first BASIC line
  33 first token of first BASIC line P.FIRS
  
The PROGRAM TYPE (byte 6 of the header above) is:
  BIT DESCRIPTION
  --- ------------------------------------
   0 Program type (0=MAIN, 1=SUBPROGRAM)
   1 Program type (0=BASIC, 1=BINARY PROGRAM)
   2 not used
   3 not used
   4 not used
   5 Allocation (0=NOT allocated, 1=ALLOCATED)
   6 Option base (0=OptionBase 1, 1=OptionBase 0)
   7 COMMON flag (0=NO common, 1=COMMON block)

 

HP-87/86 BASIC PROGRAM CONTROL BLOCK

The following is the appearance of the PCB in a DISK FILE.  When loaded into memory, the HP-87 BASIC program gets turned "upside-down" with the NAME starting at the highest address and the programming proceeding to lower and lower addresses.

 BYTE#  DESCRIPTION              		OFFSET NAME
 -----  ---------------------------------- -----------
   0 NAME[0]
   1 NAME[1]
   2 NAME[2]
   3 NAME[3]
   4 NAME[4]
   5 NAME[5]
   6 program TYPE (see below) P.TYPE
   7-11 program LENGTH (3 bytes) P.LEN
  12-14 COM length or SUB RTN (2 bytes) P.COMG
  15-17 DATA line ptr (2 bytes) P.DTLG
  20-22 DATA item ptr (2 bytes) P.DTAG
  23-25 Reserved Mem Pointer (2 bytes) P.RMEG
  26 Active FOR/NEXT counter P.FCNG
  27 Active GOSUB counter P.GCNG
  30 not used
  31 not used
  32 Security bits P.SFLG
  33-34 Security code (2 bytes) P.SCOG
  35 not used
  36 not used
37 not used
   MAIN program starts here
  40-42 6 BCD digits LINE NUMBER (3 bytes) P.GOG
  43 LENGTH of first BASIC line
  44 first token of first BASIC line P.FIRG
  
The PROGRAM TYPE (byte 6 of the header above) is:
  BIT DESCRIPTION
  --- ------------------------------------
   0 Program type (0=MAIN, 1=SUBPROGRAM)
   1 Program type (0=BASIC, 1=BINARY PROGRAM)
   2 not used
   3 not used
   4 0=HP85 BASIC, 1=HP87 BASIC
   5 Allocation (0=NOT allocated, 1=ALLOCATED)
   6 Option base (0=OptionBase 1, 1=OptionBase 0)
   7 COMMON flag (0=NO common, 1=COMMON block)

 

HP-85 TAPE LAYOUT

The HP-85 tape cartridges contained at most 43 files. File 0 was always the TAPE DIRECTORY, and was always 4 records long.  Files 1-42 were the user-created files. The tape itself had 2 TRACKS, 0 and 1.

There were TWO COPIES of the TAPE DIRECTORY, one in records 0 and 1 of file 0, and a second in records 2 and 3 of file 0.  Record 2 was an exact duplicate of record 0, and record 3 was an exact duplicate of record 1.  Only one record of the directory could be read into memory at a time, so the system had to keep track of whether the first 1/2 or the second 1/2 of the directory was in memory (or neither).

Each DIRECTORY RECORD consisted of 21 12-byte directory entries, which equals 252 bytes.  The final 4 bytes of each record as follows:

  252 directory segment flag (0 or 1).
  253 FILE# of file that wraps from the end of TRACK 0 to the beginning of TRACK 1.
  254-255 (2 bytes) RECORD# of first record of the split file that's on TRACK 1.

 

Each DIRECTORY ENTRY consists of 12 bytes, allocated thusly:

  BYTES	DESCRIPTION
  ----- ---------------------------------------------
  0-5 ASCII FILE NAME, blank filled
  6 EXTENDED File Type
  7 FILE TYPE
  8-9 # RECORDS in the file
  10-11 # BYTES in each record

  

The FILE TYPE is thus:

  BIT	DESCRIPTION
  --- -----------------------------------------------
   0 No directory name listed
   1 Soft write protect
   2 Extended file type (****)
   3 Binary Program (BPGM)
   4 Data file (DATA)
   5 BASIC Program (PRGM)
   6 Empty file (NULL)
   7 Next available file

   

The most significant bit of the EXTENDED FILE TYPE byte will signify extended file type as well as BIT 2 of FILE TYPE, but it shouldn't be used, as a bug in the system doesn't clear that bit if you purge the file.  The lower seven bits allow the differentiation between various extended file types (****).


Each record on the tape is preceded by a 6-byte header (and, I think, the header's 2-byte checksum, so 8 bytes total).  The header bytes (from comments in the tape routines in the HP-85 System ROMs at 020000) is:

    HED 0 bits: ExRTTFFF
      E = 1 if EMPTY FILE
      x = unknown/unused
      R = Reserved (not sure what that means)
      T = Type (0-3, not sure they are, other than 0=EMPTY)
      F = 3 MSbits of FILE NUMBER
    HED 1 = 8 LSbits of FILE NUMBER
    HED 2 = xxxfRRRR
      x = unknown/unused
      f = free (not sure how that relates to EMPTY, or not)
      R = 4 MSbits of RECORD NUMBER
    HED 3 = 8 LSbits of RECORD NUMBER
    HED 4 = unknown/unused
    HED 5 = RECORD LEN-1 (ie, 255=record length of 256 bytes)
 

 

DISK LAYOUT

The HP-85 disks used the LIF (Logical Interchange Format) disk layout.  The first 2 sectors on the disk (cylinder 0, head 0, sector 0-1) contained the VOLUME sectors.  The important things in the VOLUME SECTORS were thus:

BYTES   DESCRIPTION
-----   -----------------------------------------------------------
  0-1   LIF identifier, must be 0x80, 0x00 (0x8000)
  2-7   6-character volume LABEL
 8-11   directory start block (always 0,0,0,2 = 0x00000002)
12-13   LIF identifer for System 3000 machines (always 0x10,0 = 0x1000)
14-15   always 0
16-19   # of sectors in DIRECTORY (usually 0,0,0,something)
20-21   LIF version number (always 0,1 = 0x0001)
22-23   always 0
24-27   number of tracks per surface
28-31   number of surfaces
32-35   number of sectors per track
36-41   date and time that the volume was initialized (YY,MM,DD,HH,mm,SS)
        All date values are in BCD format.  YY is (year-1900). HH is 0-23.

Each DIRECTORY SECTORS held 8 32-byte directory entries.  Each entry contained these values:

  BYTE	DESCRIPTION
  ---- ------------------------------------------------
  0-9 10-character file name (blank filled)
  10 upper byte of file TYPE (see below)
  11 lower byte of file TYPE
  12-15 START of FILE (most signicant byte first)
  16-19 LENGTH of FILE in sectors (most significant byte first)
  20-25 file CREATION DATE
  26 always 0x80
  27 always 0x01 entire file is on this volume
  28* lower byte of # of BYTES in this FILE
  29* upper byte of # of BYTES in this FILE
  30* lower byte of BYTES per LOGICAL RECORD
  31* upper byte of BYTES per LOGICAL RECORD
*) bytes 28-31 are implementation dependent, i.e. non-Series-80 systems may write other information into these bytes.

Note that MOST values in LIF discs' VOLUME and DIRECTORY sectors are stored in "big-endian" format (most significant byte first, least significant byte last).  The Series 80 CPU was "little-endian", it stored the least significant byte first (at the lower address) and the most significant byte last (at the upper address).  That's why the last two entries in the directory entries (bytes/file and bytes/record) were stored in byte-reversed order from the other "official" LIF values.

The FILE TYPE value (WORD) was:

   TYPE  Meaning
------ ------------------------------------------
  0x0000 PURGE'd (deleted) file
  0xFFFF NEXT available (unused directory slot) file
  0x0001 LIF ASCII file
  0xE004 Series 80 **** extended file type (85 ASSM, etc)
  0xE008 Series 80 BPGM binary program
  0xE009 Series 80 BPGM binary program (file security 3)
  0xE00A Series 80 BPGM binary program (file security 2)
  0xE00C Series 80 86/87 GRAF
  0xE010 Series 80 DATA
  0xE011 Series 80 DATA (file security 3)
  0xE012 Series 80 DATA (file security 2)
  0xE014 Series 80 86/87 ASSM
  0xE01C Series 80 ROOT
  0xE020 Series 80 PROG Basic program
  0xE021 Series 80 PROG Basic program (file security 3)
  0xE022 Series 80 PROG Basic program (file security 2)
  0xE024 Series 80 86/87 PSET
  0xE02C Series 80 86/87 BKUP
  0xE034 Series 80 86/87 FORM
  0xE084 Series 80 86/87 MIKSAM

 

Other known HP LIF file types for other systems:

  0x00FF HP 71 LEX, disabled
  0xE040 HP 41 Write All
  0xE050 HP 41 key assigments
  0xE052 HP 75 text and key assigments
  0xE053 HP 75 appointments
  0xE058 HP 75 mass storage database
  0xE060 HP 41 status
  0xE070 HP 41 X-Memory and ROM dump
  0xE080 HP 41 program
  0xE088 HP 75 Basic
  0xE089 HP 75 LEX
  0xE08A HP 75 Visicalc worksheet
  0xE08B HP 75 ROM dump
  0xE0D0 HP 41 data, HP 71 stream data
  0xE0D1 TEXT, secured
  0xE0D5 TEXT, secured
  0xE0F0 HP 71 data
  0xE0F1 HP 71 data, secured
  0xE204 HP 71 binary program
  0xE205 binary program secured
  0xE206 binary program private
  0xE207 binary program secured private
  0xE208 HP 71 language extension
  0xE209 HP 71 language extension, secured
  0xE20A HP 71 language extension, private
  0xE20B HP 71 language extension, secured, private
  0xE20C HP 71 key definition
  0xE20D HP 71 key definition, secured
  0xE214 HP 71 Basic
  0xE215 HP 71 Basic, secured
  0xE216 HP 71 Basic, private
  0xE217 HP 71 Basic, secured, private
  0xE218 HP 71 Forth
  0xE219 HP 71 Forth, secured
  0xE21A HP 71 Forth, private
  0xE21B HP 71 Forth, secured, private
  0xE21C HP 71 ROM
  0xE808 HP 9000 HPL data
  0xE810 HP 9000 HPL program
  0xE814 HP 9000 HPL?
  0xE818 HP 9000 HPL Keys
  0xE820 HP 9000 HPL?
  0xE942 HP 9000 System
  0xE946 HP Unix
  0xE950 HP 9000 Basic Program
  0xE961 HP 9000 BDAT
  0xE971 HP 9000 Binary
  0xEA0A HP 9000 Pascal Data
  0xEA32 HP 9000 Pascal Code
  0xEA3E HP 9000 Pascal Text
 

Layout of disk images in Everett Kaser's Series 80 Emulator

The 'disks' that you select/load/create in my emulator are single MS-DOS/Windows files that ARE simple disk images.  It's just a  question of 'format.'  i.e. what TARGET format you're looking for, as there's an endless stream of possibilities.
 
The disk images that *I* use in my emulator consist of a simple string of 256-byte sectors, as if ripped straight from a Series 80 floppy. The offset into the file is:
 
file_offset = (cylinder*32 + head*16 + sector)*256
 
The file is 270,336 bytes long, which is 33 cylinders, 2 heads, 16 sectors per side (head), 256 bytes per sector. 33*2*16*256 = 270336.
 
So, the order of the sectors in the file are:
 
Offset Cylinder Head Sector Absolute Sector#
====== ======== ==== ====== ================
     0      0     0    0            0
   256      0     0    1            1
   512      0     0    2            2
   ...
  3840      0     0   15           15
  4096      0     1    0           16
  4352      0     1    1           17
  4608      0     1    2           18
   ...      
  7936      0     1   15           31
  8192      1     0    0           32
  8448      1     0    1           33
  8704      1     0    2           34
   ...
 12032      1     0   15           47
 12288      1     1    0           48
   etc.
 
The disk image files are in the disks0, disks1, disks2, etc. folders within the folder in which the emulator is installed.
 
So, taking these raw sectors and converting them to some other file format would be pretty trivial, assuming one knew what the other format needed to look like. These are LIF disk images, including the volume sectors in absolute sectors 0 and 1, with the directory sectors usually starting in sector 2.