home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol144 / setboot.mac < prev    next >
Encoding:
Text File  |  1985-02-10  |  18.5 KB  |  522 lines

  1. ;******************************************************************************
  2. ;                SETBOOT v. 1.0
  3. ;                --------------
  4. ;
  5. ;    This program is used to patch the disk resident autostart command in
  6. ; single and double density Osborne 1 computers.  This program will prompt the
  7. ; user for the disk drive on which the command is to be placed, the command
  8. ; string, and the conditions under which the command should be used.  SETBOOT
  9. ; is as general as I can make it, and is only limited by the capabilities of
  10. ; the Osborne BIOS.
  11. ;
  12. ; Author: Noel J. Bergman
  13. ;
  14. ; (c) Copyright 1983, Noel J. Bergman
  15. ; ALL RIGHTS RESERVED
  16. ;
  17. ; This program may be freely distributed for personal use only.  Any use of
  18. ; of this program for commercial purposes requires prior written approval
  19. ; from the author.  Commercial purposes shall include distribution by any
  20. ; organization affiliated with Lifeboat Associates.  The address to write to
  21. ; for approval is:
  22. ;            Noel J. Bergman
  23. ;            8329 High School Road
  24. ;            Elkins Park, PA 19117
  25. ;------------------------------------------------------------------------------
  26. ;                Modification Log
  27. ;                ------------ ---
  28. ;
  29. ; 04/01/83 - Original version.  Uses DPB to determine whether disk is single
  30. ;         or double density.  Track, sector and sector offset locations are
  31. ;         hardcoded. BIOS versions 1.4x are known to work.
  32. ;******************************************************************************
  33.  
  34. ;*-    Autostart Information Equates
  35.  
  36. SCODE    EQU    5        ; SINGLE DENSITY disk type code
  37. STRK    EQU    2        ; SINGLE DENSITY track location
  38. SSEC    EQU    3        ; SINGLE DENSITY sector location
  39. SOFF    EQU    1Ch        ; SINGLE DENSITY byte offset
  40. SMAX    EQU    7        ; SINGLE DENSITY maximum command length
  41.  
  42. DCODE    EQU    0Ch        ; DOUBLE DENSITY disk type code
  43. DTRK    EQU    1        ; DOUBLE DENSITY track location
  44. DSEC    EQU    5        ; DOUBLE DENSITY sector location
  45. DOFF    EQU    1Ch        ; DOUBLE DENSITY byte offset
  46. DMAX    EQU    7        ; DOUBLE DENSITY maximum command length
  47.  
  48. ;*-    CP/M 2.2 BDOS and BIOS Entry Point Equates
  49.  
  50. BDOS    EQU    0005h        ; BDOS entry point
  51. COS    EQU    09h        ; BDOS Console Output String
  52. CIL    EQU    0Ah        ; BDOS Console Input Line
  53. RSTDRV    EQU    25h        ; BDOS Reset Selected Drive(s)
  54. SELDRV    EQU    0Eh        ; BDOS Select Drive
  55. DSKPRM    EQU    1Fh        ; BDOS Get Disk Parameters
  56.  
  57. BIOSE    EQU    0001h        ; BIOS pointer to jump table
  58. SELDSK    EQU    18h        ; BIOS Select disk (to get XLAT table address)
  59. SETTRK    EQU    1Bh        ; BIOS Set Track
  60. SETSEC    EQU    1Eh        ; BIOS Set Sector
  61. SETDMA    EQU    21h        ; BIOS Set DMA
  62. READ    EQU    24h        ; BIOS Read Sector
  63. WRITE    EQU    27h        ; BIOS Write Sector
  64. SECTRN    EQU    2Dh        ; BIOS Sector Translation
  65.  
  66. ;*-    BIOS related utility macro
  67.  
  68. BIOS    MACRO    FUNCTION    ; Macro to make BIOS service calls.
  69.     LOCAL    Lx        ; Force assembler to generate unique labeling.
  70.     LD      HL,(BIOSE)    ; HL ::= address of BIOS warm boot entry. 
  71.  
  72.     IF    FUNCTION EQ SECTRN
  73.     PUSH    DE        ; DE contains pointer to XLAT table for SECTRN
  74.     ENDIF
  75.  
  76.     LD    DE,FUNCTION    ; DE ::= offset from BIOS warm boot to desired
  77.                 ; entry point.
  78.     ADD    HL,DE        ; HL ::= address of desired BIOS entry point.
  79.  
  80.     IF    FUNCTION EQ SECTRN
  81.     POP    DE        ; Restore pointer to XLAT table
  82.     ENDIF
  83.  
  84.     LD    (Lx+1),HL    ; fill in the address field of the BIOS call.
  85. Lx:    CALL    0000h        ; the relocatable call instruction.
  86.     ENDM
  87.  
  88. ;*-    Miscellaneous Equates
  89.  
  90. CR    EQU    0Dh        ; Carriage Return
  91. LF    EQU    0Ah        ; Line Feed
  92.  
  93. ;******************************************************************************
  94. ;    Print a welcome message.
  95. ;
  96.     .Z80
  97.     ASEG
  98.     ORG    100h
  99.  
  100. START:    LD    (STACK),SP    ; STACK ::= Old SP
  101.     LD    SP,STACK    ; SP ==> STACK
  102.  
  103.     CALL    QUERY1        ; Print startup message
  104.     D┬áá    CR,LF,'SETBOO╘á[1.0NjB¼áLas⌠ ModifieΣ 4/01/83]'
  105.     DB    CR,LF
  106.     DB    CR,LF,'Thi≤ versioε oµ SETBOO╘ wil∞ worδ witΦ botΦ singlσ'
  107.     DB    CR,LF,'anΣ doublσ densit∙ Osbornσ disks«á  Remembe≥á tha⌠'
  108.     DB    CR,LF,'iµá yo⌡ wan⌠ t∩ modif∙ ß doublσ densit∙ disk¼á yo⌡'
  109.     DB    CR,LF,'mus⌠á bσ usinτ ß doublσ densit∙ machine¼á anΣá yo⌡'
  110.     DB    CR,LF,'mus⌠á havσá "bootedó thσ compute≥á witΦá ßá doublσ'
  111.     DB    CR,LF,'densit∙ disδ iε drivσ A«  Makσ surσ tha⌠ eacΦ disδ'
  112.     DB    CR,LF,'t∩á bσ modifieΣ ha≤ ß cop∙ oµ CP/═ witΦ BIO╙ 1.4x«'
  113.     DB    CR,LF,'Thσá prograφ wil∞ promp⌠ yo⌡ fo≥ eacΦá actioεá yo⌡'
  114.     DB    CR,LF,'mus⌠á perforφá anΣ eacΦ questioε yo⌡ mus⌠á answer«'
  115.     DB    CR,LF,'Ever∙ attemp⌠ ha≤ beeε madσ t∩ makσ thi≤ operatioε'
  116.     DB    CR,LF,'painless¼ s∩ remembe≥ thσ ke∙ t∩ computing:'
  117.     DB    CR,LF
  118.     DB    CR,LF,'    NO MATTER WHAT GOES WRONG, DON''T PANIC.'
  119.     DB    CR,LF
  120.     DB    CR,LF
  121.     DB    CR,LF
  122.     DB    CR,LF
  123.     DB    CR,LF
  124.     DB    CR,LF
  125.     DB    CR,LF
  126.     DB    CR,LF,'Hit any key when ready to continue:','$'
  127.  
  128. ;******************************************************************************
  129. ;    This is the beginning of the main program loop.  Here we tell him to
  130. ; put the disk that he wants to setup into drive B, and then we wait for him
  131. ; to do so.
  132. ;    After he has placed the disk into drive B, we must check to see
  133. ; whether we are dealing with single or double demsity by checking the sector
  134. ; size in the DPB.  Once that is known, the location information for that type
  135. ; of disk is setup, and the correct sector is read into the buffer.
  136. ;
  137. DODISK:    CALL    QUERY1        ; Prompt user for disk change.
  138.     DB    CR,LF
  139.     DB    CR,LF,'Pleasσ placσ thσ disδ t∩ bσ modifieΣ iε drivσá Bº 
  140.     D┬á    CR,LF,'anΣ then pres≤ any key.','$'
  141.  
  142. ;*- issue a drive reset so that BDOS will login new disk.
  143.  
  144.     LD    DE,0002h    ; DE ::= drive map (only B is set)
  145.     LD    C,RSTDRV    ; C  ::= BDOS code for reset selected drive(s)
  146.     CALL    BDOS
  147.  
  148. ;*- select the B: drive
  149.  
  150.     LD    E,01h        ; E  ::= drive code for B:
  151.     LD    C,SELDRV    ; C  ::= BDOS code for select drive
  152.     CALL    BDOS
  153.  
  154. ;*- let's take a look at the dpb and see what density disk it defines
  155.  
  156.     LD    C,DSKPRM    ; C  ::= BDOS code for Get Disk Parameters
  157.     CALL    BDOS        ; HL ==> DPB for B:
  158.     DEC    HL        ; HL ==> Osborne code for this disk type
  159.     LD    A,(HL)        ; A  ::= disk type
  160.  
  161.     CP    SCODE        ; Is it a single density disk?
  162.     JP    NZ,DCHK        ; No, see if it is double density
  163.  
  164. ;*- fall through to setup for a single density disk.
  165.  
  166.     LD    HL,STBL        ; HL ==> single density information table
  167.     LD    BC,DTBL-STBL    ; BC ::= number of bytes to copy
  168.     LD    DE,TRACK    ; DE ==> information table for this disk
  169.     LDIR            ; Copy the table
  170.     JP    READIT        ; get the sector with the autostart command
  171.  
  172. ;*- see if it is double density.
  173.  
  174. DCHK:    CP    DCODE        ; Is it a double density disk?
  175.     JP    NZ,BADDSK    ; No, it is neither single nor double
  176.  
  177. ;*- fall through to setup for a double density disk.
  178.  
  179.     LD    HL,DTBL        ; HL ==> double density information table
  180.     LD    BC,TRACK-DTBL    ; BC ::= number of bytes to copy
  181.     LD    DE,TRACK    ; DE ==> information table for this disk
  182.     LDIR            ; Copy the table
  183.     JP    READIT        ; get the sector with the autostart command
  184.  
  185. ;*- tell the jerk that the disk is no good.
  186.  
  187. BADDSK:    CALL    ILPRT
  188.     DB    CR,LF
  189.     DB    CR,LF,'Thi≤ái≤áno⌠á aε Osbornσ Singlσ o≥á Doublσá densit∙'ì
  190.     DB    CR,LF,'disk.  You are welcome to try again,  but you must'
  191.     DB    CR,LF,'use only Osborne format disks.','$'
  192.     JP    DONE
  193.  
  194. ;******************************************************************************
  195. ;    Having figured out what type of disk we are dealing with, and having
  196. ; setup a table of information about it, it is now time to read the sector
  197. ; containing the autoboot information.  If the length of the autoboot command
  198. ; is an E5h, we assume that this disk does not have a copy of CP/M on it.
  199. ;
  200. READIT:    LD    BC,(TRACK)    ; BC  ::= track number
  201.     BIOS    SETTRK        ; Call BIOS to set the track
  202.  
  203.     LD    C,1        ; C  ::= code for drive B:
  204.     BIOS    SELDSK        ; Select disk via BIOS so we can find XLAT
  205.     LD    E,(HL)        ; E  ::= byte offset of XLAT table
  206.     INC    HL        ; HL ==> page address of XLAT table
  207.     LD    D,(HL)        ; DE ==> XLAT table
  208.  
  209.     LD    BC,(SECTOR)    ; C  ::= sector number
  210.  
  211.     LD    A,D        ; A  ::= page address of XLAT table
  212.     OR    E        ; A  = 0 if no XLAT table used
  213.     JP    Z,NXLAT        ; so skip the translation
  214.  
  215.     BIOS    SECTRN        ; Call BIOS to get physical sector number
  216.     LD    B,H
  217.     LD    C,L        ; BC ::= physical sector number
  218.  
  219. NXLAT:    BIOS    SETSEC        ; Call BIOS to set the sector number
  220.     LD    BC,SECBUF    ; BC ==> sector storage area
  221.     BIOS    SETDMA        ; Tell BIOS where to load sector
  222.  
  223.     BIOS    READ        ; Call BIOS to read the sector
  224.     OR    A        ; ((A = 0) ==> good read)
  225.     CALL    NZ,SYSERR    ; no, so abort.
  226.  
  227.     LD    A,(SECBUF+SOFF+1)    ; A ::= byte to be tested
  228.     CP    0E5h        ; Length = format code?
  229.     JP    NZ,FOUND    ; No, there is an autostart command
  230.  
  231.     CALL    ILPRT        ; Tell him that there must be CP/M on the disk
  232.     DB    CR,LF
  233.     DB    CR,LF,'Thσ disδ yo⌡ havσ selecteΣ doe≤ no⌠ havσ ß cop∙ oµ'
  234.     DB    CR,LF,'CP/═ oε it«á  Iµ yo⌡ wisΦ t∩ instal∞ aεá autostar⌠'
  235.     DB    CR,LF,'commanΣá oεá thσ disk¼á yo⌡ mus⌠ firs⌠ follo≈á thσ'
  236.     DB    CR,LF,'direction≤á iε thσ Osbornσ manua∞ fo≥á placinτá aε'
  237.     DB    CR,LF,'operatinτ systeφ oε thσ disk«','$'
  238.  
  239.     JP    DONE        ; and prepare to exit.
  240.  
  241. ;******************************************************************************
  242. ;    At this point SECBUF contains a valid autostart sector.  We check to
  243. ; see if there is an autostart command installed, and if there is we tell him
  244. ; what it is and when it is executed.
  245. FOUND:    LD    A,(SECBUF+SOFF)    ; A  ::= autostart conditions
  246.     CP    0        ; (A =0) ==> ignore autostart
  247.     JP    NZ,SAUTO    ; No, there is an autostart command installed
  248.  
  249.     CALL    ILPRT        ; Show the user that there is no autostart
  250.     DB    CR,LF
  251.     DB    CR,LF,'There is no autostart command on this disk.','$'
  252.  
  253.     JP    CHANGE        ; See if he wants to change things.
  254.  
  255. ;*-    There is an autostart command so show it to him
  256.  
  257. SAUTO:    LD    A,' '        ; Prepare to clear space for name of command
  258.     LD    (ANAME),A    ; Clear first byte
  259.     LD    HL,ANAME    ; Copy from first byte
  260.     LD    DE,ANAME+1    ; to rest of command via propogation of spaces
  261.     LD    BC,ENAME-ANAME-1; Number of spaces to clear
  262.     LDIR
  263.  
  264.     LD    HL,SECBUF+SOFF+2; HL ==> autostart command
  265.     LD    DE,ANAME    ; DE ==> place in message for name of command
  266.     LD    BC,(SECBUF+SOFF+1)    ; BC ::= length of autostart command
  267.     LD    B,0        ; Length is only one byte
  268.     LDIR            ; Put the command into the message
  269.  
  270.     CALL    ILPRT        ; Show user the current autostart command
  271.     DB    CR,LF
  272.     DB    CR,LF,'Thσ curren⌠ autostar⌠ commanΣ is║á "'
  273. ANAME:    DB    '       '    ; Space for name of command
  274. ENAME:    DB    '"«  Thσ'
  275.     DB    CR,LF,'autostart conditions are:'
  276.     DB    CR,LF,'$'
  277.  
  278. ;*-    See it it runs at cold boot time (condtion code <> 2)
  279.  
  280.     LD    A,(SECBUF+SOFF)    ; A  ::= autostart conditions
  281.     CP    2        ; (A <> 2) ==> autostart at cold boot
  282.     JP    Z,SWARM        ; Skip this message  
  283.  
  284.     CALL    ILPRT        ; Show cold boot condition
  285.     DB    CR,LF,'    * Perform command upon cold boot','$'
  286.  
  287. ;*-     See if it runs at warm boot time (condition code <> 1)
  288.  
  289. SWARM:    LD    A,(SECBUF+SOFF)    ; A  ::= autostart conditions
  290.     CP    1        ; (A <> 1) ==> autostart at warm boot
  291.     JP    Z,CHANGE    ; Skip this message
  292.  
  293.     CALL    ILPRT        ; Show warm boot condition
  294.     DB    CR,LF,'    * Perform command upon warm boot','$'
  295.  
  296. ;******************************************************************************
  297. ;    Now we want to find out what changes he wants to make.
  298. CHANGE:    CALL    QUERY1        ; See if he wishes to change the situation
  299.     DB    CR,LF
  300.     D┬á    CR,LF,'D∩ yo⌡ wisΦ t∩ changσ thi≤ setup┐ (Y/N):','$'
  301.  
  302.     LD    A,(CIBUF+2)    ; A  ::= user response
  303.     AND    5Fh        ; capitalize the response
  304.     CP    'Y'
  305.     JP    Z,CHANG2    ; Yes, let's change it. 
  306.     CP    'N'
  307.     JP    Z,DONE        ; No, leave it is it is now.
  308.     JP    CHANGE        ; Accept only yes or no responses
  309.  
  310. ;*-    Maybe he wants to remove the autostart command entirely
  311.  
  312. CHANG2:    CALL    QUERY1        ; See if he wants to remove the autostart
  313.     DB    CR,LF
  314.     DB    CR,LF,'Do you want this disk to autostart? (Y/N):','$'
  315.  
  316.     LD    A,(CIBUF+2)    ; A  ::= user response
  317.     AND    5Fh        ; capitalize the response
  318.     CP    'Y'
  319.     JP    Z,GETA        ; Yes, some get the command
  320.     CP    'N'
  321.     JP    NZ,CHANG2    ; Accept only yes or no responses
  322.     XOR    A        ; clear A
  323.     LD    (SECBUF+SOFF),A    ; Disable autostart
  324.     LD    BC,1        ; Force BIOS to perfrom immdediate write
  325.     BIOS    WRITE        ; Write the sector to disk
  326.     OR    A        ; Check for write errors
  327.     CALL    NZ,SYSERR    ; oh, shit -- print error message
  328.     JP    DONE        ; and prepare to terminate
  329.  
  330. GETA:    CALL    QUERY7        ; Get the new autostart command
  331.     DB    CR,LF
  332.     DB    CR,LF,'Pleasσ ente≥ thσ ne≈ autostar⌠ command« Therσ i≤ ß'
  333.     DB    CR,LF,'limi⌠ oµ no more than seveε (7⌐ characters:','$'
  334.  
  335.     LD    HL,CIBUF+1    ; HL ==> length of new command and command
  336.     LD    BC,(CIBUF+1)    ; BC ::= length of new command
  337.     LD    B,0        ; Length is only one byte
  338.     INC    BC        ; Update Byte Count to include command length
  339.     LD    DE,SECBUF+SOFF+1; DE ==> disk resident autostart command buffer
  340.     LDIR            ; move it
  341.  
  342. GETC:    CALL    QUERY1        ; Get the new autostart conditions
  343.     DB    CR,LF
  344.     DB    CR,LF,'Unde≥ wha⌠ condition≤ i≤ thi≤ autostar⌠ commanΣ t∩'
  345.     DB    CR,LF,'bσ executed┐ Pleasσ makσ you≥ selectioε b∙ chosinτ'
  346.     DB    CR,LF,'the number next to your choice.'
  347.     DB    CR,LF
  348.     DB    CR,LF,'    1. Perform command upon cold boot'
  349.     DB    CR,LF,'    2. Perform command upon warm boot'
  350.     DB    CR,LF,'    3« PerforφácommanΣ upoε eithe≥ warφ boo⌠'
  351.     DB    CR,LF,'       or cold boot.'
  352.     DB    CR,LF
  353.     DB    CR,LF,'Selection? (1,2 or 3):','$'
  354.  
  355.     LD    A,(CIBUF+2)    ; A  ::= user response
  356.     SUB    '1'        ; A  ::= A - ord('1'), valid A in 0..2
  357.     JP    C,GETC        ; (A < '1') ==> bad response
  358.     SUB    3        ; A  ::= A - 3, valid A in -3..-1
  359.     JP    NC,GETC        ; (A > '3') ==> bad response
  360.     ADD    A,4        ; bring A back to 1..3
  361.     LD    (SECBUF+SOFF),A    ; install new condition code
  362.     LD    BC,1        ; Force BIOS to perfrom immdediate write
  363.     BIOS    WRITE        ; Write the sector to disk
  364.     OR    A        ; Check for write errors
  365.     CALL    NZ,SYSERR    ; oh, shit -- print error message
  366.  
  367. DONE:    CALL    QUERY1        ; See if he wants to do any more disks.
  368.     DB    CR,LF
  369.     DB    CR,LF,'Do you want to do any more disks now? (Y/N):','$'
  370.     LD    A,(CIBUF+2)    ; A  ::= user response
  371.     AND    5Fh        ; capitalize the response
  372.     CP    'Y'
  373.     JP    Z,DODISK    ; do another disk
  374.     CP    'N'
  375.     JP    NZ,DONE        ; accept only yes or no response
  376.     JP    EXIT
  377.  
  378. ;******************************************************************************
  379. ;    This routine assumes that the top of the stack is a pointer to a string
  380. ; to be displayed via the BDOS console output string function.  The catch is
  381. ; that the caller wants this routine to return to the address immediately
  382. ; following the message.  This function provides us with an in-line print
  383. ; facility.
  384. ;
  385. ILPRT║    PO╨    H╠        ╗ H╠ ==╛ string
  386.     PUSH    HL        ; TOS ==> string
  387.     LD    A,'$'        ; A  ::= end marker
  388.     LD    BC,2048     ; Allow maximum string length of 2k (safety)
  389.     CPIR            ; Search for '$' end marker
  390.     CALL    NZ,SYSERR    ; SYSTEM ERROR - we didn't find an end marker
  391.     POP    DE        ; DE ==> string
  392.     PUSH    HL        ; TOS ::= caller's return address
  393.     LD    C,COS        ; C  ::= BDOS code for Console Output String
  394.     CALL    BDOS        ; Output the string
  395.     RET            ; Return to caller
  396.  
  397. ;******************************************************************************
  398. ;    These two routines are used to prompt the user for some input, and
  399. ; to read in the user's response.  Both routines use the BDOS Console Input
  400. ; Line (CIL) function to get their input, and so they are compatible with
  401. ; the SUBMIT facility.  They only differ in the number of characters that
  402. ; the BDOS will accept before returning to the program.
  403. ;
  404. QUERY1:    LD    A,1
  405.     LD    (CIBUF),A    ; Set maximum length of console input to 1
  406.     JP    QUERY
  407.  
  408. QUERY7:    LD    A,7
  409.     LD    (CIBUF),A    ; Set maximum length of console input to 7
  410.  
  411. QUERY:    PO╨    H╠        ╗ H╠ ==╛ string
  412.     PUSH    HL        ; TOS ==> string
  413.     LD    A,'$'        ; A  ::= end marker
  414.     LD    BC,2048     ; Allow maximum string length of 2k (safety)
  415.     CPIR            ; Search for '$' end marker
  416.     CALL    NZ,SYSERR    ; SYSTEM ERROR - we didn't find an end marker
  417.     POP    DE        ; DE ==> string
  418.     PUSH    HL        ; TOS ::= caller's return address
  419.     LD    C,COS        ; C  ::= BDOS code for Console Output String
  420.     CALL    BDOS        ; Output the string
  421.     LD    C,CIL        ; C  ::= BDOS code for Console Input Line
  422.     LD    DE,CIBUF    ; DE ==> console input buffer
  423.     CALL    BDOS        ; Get user input 
  424.  
  425.     RET
  426.  
  427. ;******************************************************************************
  428. ;    These two routines, SYSERR and EXIT, get control when it is time to
  429. ; return to CP/M.  SYSERR is the error exit routine and EXIT is the normal
  430. ; exit routine.  The difference is that SYSERR prints an error message before
  431. ; terminating.
  432. ;
  433. SYSERR:    POP    HL        ; HL ==> instruction following CALL SYSERR
  434.     LD    DE,-3        ; CALL instruction is 3 bytes long
  435.     ADD    HL,DE        ; HL ==> CALL SYSERR instruction
  436.     LD    DE,ERRADR    ; DE ==> place to put printable hex number
  437.     LD    C,H        ; C  ::= page address of call instruction
  438.     CALL    PUTHEX        ; Put 2 hex digits at (DE) and (DE+1)
  439.     LD    C,L        ; C  ::= page offset of call instruction
  440.     CALL    PUTHEX        ; Put 2 hex digits at (DE) and (DE+1)
  441.  
  442.     CALL    ILPRT        ; Print error message
  443.     DB    CR,LF
  444.     DB    CR,LF,'%ERROR - SYSERR called from '
  445. ERRADR:    DB    '0000'
  446.     DB    'h.   Please record'
  447.     DB    CR,LF,'this information  and give  it to  the appropriate'
  448.     DB    CR,LF,'person(s).  If you cannot get help from some other'
  449.     DB    CR,LF,'source, you may obtain it by writing (NOT calling)'
  450.     DB    CR,LF,'to the address below:'
  451.     DB    CR,LF
  452.     DB    CR,LF,'    Noel J. Bergman'
  453.     DB    CR,LF,'    8329 High School Road'
  454.     DB    CR,LF,'    Elkins Park, PA 19117'
  455.     DB    CR,LF
  456.     DB    CR,LF,'Be sure to include  the SETBOOT version number and'
  457.     DB    CR,LF,'last date modified,  the address SYSERR was called'
  458.     DB    CR,LF,'from,  the BIOS and ROM revision  numbers of  your'
  459.     DB    CR,LF,'Osborne, the density of the disks you were working'
  460.     DB    CR,LF,'with in both  drives,  and a  transcription of the'
  461.     DB    CR,LF,'entire dialog between you and SETBOOT. Please note'
  462.     DB    CR,LF,'that this error does not necessarily mean that you'
  463.     DB    CR,LF,'have a problem with your computer.   If you do not'
  464.     DB    CR,LF,'have other  problems with  your Osborne,  you need'
  465.     DB    CR,LF,'not be overly concered about this error.','$'
  466.  
  467.     JP    EXIT
  468.  
  469. ;*- these are two utility routines for Binary to Hex conversion
  470.  
  471. PUTHEX:    LD    A,C        ; A  ::= byte to be converted
  472.     RRA
  473.     RRA
  474.     RRA
  475.     RRA
  476.     CALL    PUT1        ; do high order character
  477.     LD    A,C        ; and low order character
  478.  
  479. PUT1:    AND    0Fh        ; drop top nibble
  480.     ADD    A,90h
  481.     DAA
  482.     ADC    A,40h
  483.     DAA
  484.     LD    (DE),A        ; put printable digit in string
  485.     INC    DE        ; point to next position
  486.     RET
  487.  
  488. ;*- Restore CP/M's stack and return to CP/M
  489.  
  490. EXIT:    LD    SP,(STACK)    ; Restore CP/M's stack
  491.     RET            ; and return from whence we came
  492.  
  493. ;******************************************************************************
  494. ;            Data Storage Areas
  495. ;
  496. ; The general format of the sector we are dealing with is:
  497. ;
  498. ;    0_____1B_1C_1D_1E_____24_25________80_
  499. ;    |    | A| B|       C    |         |
  500. ;    --------------------------------------
  501. ;
  502. ;    A == Autostart conditions
  503. ;    B == Length of autostart command
  504. ;    C == Autostart command
  505.  
  506. SECBUF:    DS    128        ; Storage for the sector
  507. CIBUF:    DS    9        ; Console Input BUFfer
  508.     DS    128        ; Local stack space
  509. STACK:    DS    2        ; + space for CP/M's stack pointer
  510.  
  511. ;*-    Location Information 
  512.  
  513. STBL:    DW    STRK,SSEC,SOFF    ; SINGLE DENSITY information table
  514. DTBL:    DW    DTRK,DSEC,DOFF    ; DOUBLE DENSITY information table
  515.  
  516. TRACK:    DS    2        ; storage for track number to be used
  517. SECTOR:    DS    2        ; storage for sector number to be used
  518. OFFSET:    DS    2        ; storage for offset to be used
  519.     END
  520.