                                                           
     NAME     Partition_BootSector

; This still needs to be enhanced to work with
; devices other than the peripheral disk device
; and drives other than drive zero.


     EXTRN    CpAddressOf:FAR, BubbleDriver:FAR

ddRead         EQU  4
loadSeg        EQU  02000H
relocSeg       EQU  03000H
validSignature EQU  0AA55H

PromVariablesType  STRUC
  processQ          DB 9 DUP (?)
  semaQ             DB 9 DUP (?)
  currentPid        DW ?
  loopPid           DW ?
  bootChar          DB ?
PromVariablesType  ENDS

ParamListType  STRUC
  connection        DW ?
  pBufferOff        DW ?
  pBufferSeg        DW ?
  positionLo        DW ?
  positionHi        DW ?
  theLength         DW ?
  mode              DB ?
  drive             DB ?
  intAddr           DB ?
  pOverflow         DD ?
ParamListType  ENDS

PhysInfoPt1Type  STRUC
  bytesPerPage      DW ?
  pagesPerTrack     DW ?
  tracksPerCylinder DW ?
  numCylinders      DW ?
  secondSideCount   DB ?
PhysInfoPt1Type  ENDS

PhysInfoPt2Type  STRUC
  writeCurrentCyl   DW ?
  preCompCylinder   DW ?
  controlField      DB ?
PhysInfoPt2Type  ENDS

LogicalInfoType  STRUC
  bitMapFID         DW ?
  rootDirFID        DW ?
  minDirPages       DW ?
  logPageSize       DW ?
LogicalInfoType  ENDS

PartitionTableType  STRUC
  bootMe            DB ?
  beginHead         DB ?
  beginSec          DB ?
  beginCyl          DB ?
  osID              DB ?
  endHead           DB ?
  endSec            DB ?
  endCyl            DB ?
  beginLo           DW ?
  beginHi           DW ?
  lengthLo          DW ?
  lengthHi          DW ?
PartitionTableType  ENDS

partitionEntryLen   EQU 16
$EJECT

CODE  SEGMENT AT 2000H

    ASSUME CS:CODE, DS:CODE

Boot PROC FAR

    JMP  SHORT BootEntrypoint

    ORG  14

physInfoPt1   PhysInfoPt1Type <0,0,0,0,0>
validInfoFlag DW 0
physInfoPt2   PhysInfoPt2Type <0,0,0>
logDiskInfo   LogicalInfoType <0,0,0,0>
rePgmMode     DB 0

BootEntrypoint:
    PUSH DS
    PUSH BP

MoveBootSector:
    MOV  AX, CS
    MOV  DS, AX
    MOV  AX, relocSeg
    MOV  ES, AX
    XOR  SI, SI
    MOV  DI, SI
    MOV  CX, 100H
    JMP  SHORT MovwBugFix

MovwBugFix:
    REP  MOVSW
    MOV  AX, relocSeg
    PUSH AX
    MOV  AX, OFFSET Boot1
    PUSH AX
    RET
$EJECT

; Continuation of Boot Procedure

Boot1:
    PUSH ES                       ; readjust data
    POP  DS                       ; segment pointer

    CALL CpAddressOf
    MOV  AL, ES:[BX].bootChar
    MOV  BX, OFFSET paramList

    CMP  AL, '0'                  ; if bootchar < 0
    JB   BootErrorExit            ; then return

    CMP  AL, '7'                  ; if bootchar > 7
    JA   BootErrorExit            ; then return

    AND  AL, 00FH
    MOV  DS:[BX].intAddr, AL      ; save int addr

; Now look in the partition table for a bootable
; partition

    MOV  CX, 4                    ; 4 partitions
    MOV  BX, OFFSET entry1

LookForIt:
    CMP  DS:[BX].bootMe, 80H      ; if not bootable
    JNE  LookForNext              ; then look at next

    PUSH BX
    PUSH CX

    CALL LoadAndGo

    POP  CX
    POP  BX

LookForNext:
    ADD  BX, partitionEntryLen
    LOOP LookForIt

; None of the partitions are bootable

BootErrorExit:
    POP  BP
    POP  DS
    RET

Boot ENDP
$EJECT

; A bootable partition has been found.
; BX => the partition offset
; Read in logical page zero.  If not a CCOS
; logical zero page, then jump to 2000:0.  If it is
; a CCOS logical zero page, then read in pgs 1-4
; and jump to 2000:6.

LoadAndGo PROC NEAR
    MOV  CX, 1                    ; read 1 page
    MOV  DX, DS:[BX].beginHi
    MOV  DI, DS:[BX].beginLo      ; logical page 0

    CALL ReadSectors              ; read the page

    OR   AX, AX                   ; if error <> ok
    JNZ  LoadAndGoExit            ; return

    MOV  AX, loadSeg              ; if not a
    MOV  ES, AX                   ; partition page
    MOV  BX, OFFSET signature
    CMP  WORD PTR ES:[BX], validSignature
    JNZ  BootC3OS                 ; then boot C3OS

BootNonC3OS:                      ; else boot others
    CALL DWORD PTR CS:OtherEntrypoint
    JMP  SHORT LoadAndGoExit

BootC3OS:
    MOV  CX, 4                    ; read 4 pages

    MOV  paramList.pBufferOff, 0  ; reset dest off

    INC  DI                       ; start w/ pg 1

    CALL ReadSectors              ; read boot pgs

    OR   AX, AX                   ; if error <> ok
    JNZ  LoadAndGoExit            ; then return

    DEC  DI                       ; pass vol offset
                                  ; in DX:DI
    CALL DWORD PTR CS:C3OSEntrypoint

LoadAndGoExit:
     RET

LoadAndGo ENDP
$EJECT

; This routine reads n pages sequentially starting
; at the location specified by DX:DI.  The number
; of pages to read are stored in CX.
; It is assumed that paramList.pBuffer (seg, off)
; have already been preset with the starting addr
; of the destination for the read.
; AX will indicate the error code upon returning.

ReadSectors  PROC NEAR
    PUSH DI                       ; save offset

ReadSectorsLoop:
    PUSH CX                       ; save count
    PUSH DX
    PUSH DI                       ; save @source

    MOV  paramList.positionLo, DI
    MOV  paramList.positionHi, DX

    MOV  AX, ddRead
    PUSH AX                       ; read request

    PUSH CS
    MOV  AX, OFFSET paramList
    PUSH AX                       ; @ paramList

    PUSH CS
    MOV  AX, OFFSET error
    PUSH AX                       ; @ error

    CALL BubbleDriver

    MOV  AX, DS:error
    OR   AX, AX                   ; if error <> eOK
    JNZ  ReadSectorsExit          ; then return

    POP  DI
    POP  DX                       ; restore @source
    POP  CX                       ; restore count

    INC  DI                       ; inc source addr
    ADD  paramList.pBufferOff, 200H

    LOOP ReadSectorsLoop

ReadSectorsExit:
    POP  DI                       ; restore offset
    RET

ReadSectors  ENDP
$EJECT

c3osEntrypoint  DW 2 DUP (6, 2000H)
otherEntrypoint DW 2 DUP (0, 2000H)
paramList       ParamlistType <0, 0, loadSeg, 0, 0, 200H, 0, 0, 0, 0>
error           DW  0


    ORG  512 - (4 * partitionEntryLen + 4)

tableSig   DB  0AAH, 055H

entry1     PartitionTableType <0,0,0,0,0,0,0,0,0,0,0,0>
entry2     PartitionTableType <0,0,0,0,0,0,0,0,0,0,0,0>
entry3     PartitionTableType <0,0,0,0,0,0,0,0,0,0,0,0>
entry4     PartitionTableType <0,0,0,0,0,0,0,0,0,0,0,0>

signature  DB  055H, 0AAH

    CODE  ENDS

    END
