PGM BOOTIT
        REL
*
* SHOULD BE LOADED AT ABSOLUTE LOCATION #4000
*
* Reads image in form: 11*128 blocks starting record 1 track 0
*                       memory address 0
* then                  41 blocks and 6 tracks starting address #4F80
*                      for the code segment.
*                      13*128 blocks starting at record 1 track 7
* then                 39 blocks and 1 track starting at  #5280
*                      for the data segment.
*
BASE    EQU #78     BASE ADDRESS OF CHANNEL
*
*
TOPP    EQU $
        CLI
        MOV AX,!#FF40       SEGMENT
        MOV DS,AX           TO COPY FROM
        XOR AX,AX           SEGMENT
        MOV ES,AX           TO COPY TO
        MOV CX,!FCH-START   LENGTH
        MOV SI,!START
        MOV DI,!#4000+START
        REP
        MOVB
        JMPS START-TOPP,#400         START IPLING
*
*
START   MOV AX,!#400
        MOV SS,AX
        MOV DS,AX
        MOV ES,AX
        MOV SP,!#120
        CALL RESET
        XOR CX,CX
        MOV BL,!0      UNIT 0
        CALL RECAL     RECALIBRATE DRIVE
        CALL WAITC
        OR AL,AL
        JE GF2
        INT            ERROR
GF2     MOV IONR,!11[B]
        MOV DX,!0                memory address
        MOV CX,DX
        INC CL                   record 1 track 0
        CALL MAKIPL
* next 41 records
        MOV IONR,!41[B]
        MOV DX,!#4F80
        MOV CX,!12               record 12 track 0
        CALL MAKIPL
* now 6 tracks
        MOV IONR,!52[B]          do whole track in one go
        MOV CL,!1                record 1
        MOV CH,CL                track counter
        MOV DX,!128*41+#4F80
*
TRKLP   PUSH CX                  save count
        PUSH DX                  and address
        CALL MAKIPL
        POP DX
        POP CX
        ADD DX,!52*128
        INC CH                   next track
        CMP CH,!6
        JLE TRKLP
* move code just read up by 32k
* MOVES THE BOTTOM 64K UP BY 32K
*
        MOV CX,!#FFFF      64 K BYTES
        MOV SI,!#FFFF  START AT THE TOP
        MOV DI,SI
        MOV AX,!#800
        MOV ES,AX      DESTINATION SEGMENT
        XOR AX,AX
        MOV DS,AX      SOURCE SEGMENT
        STD
        REP
        MOVB
        MOV AL,0
        MOV 0,AL[ES]
        MOV AX,!#400
        MOV DS,AX       RESET DATA SEGMENT
* read in data part
        MOV IONR,!13[B]
        MOV DX,!0                memory address
        MOV CX,!#0701            record 1 track 7
        CALL MAKIPL
* next 39 records
        MOV IONR,!39[B]
        MOV DX,!#5280
        MOV CX,!#070E            record 14 track 7
        CALL MAKIPL
* now 1 track
        MOV IONR,!52[B]          do whole track in one go
        MOV CL,!1                record 1
        MOV CH,!8                track counter
        MOV DX,!128*39+#5280
*
        CALL MAKIPL
* finished
        INT
*
*
IOPB    DB #T00000000   SEQ. FORMAT, EN INTS, WORD LENGTH 8
IODI    DB 0            DISKETTE INSTRUCTION
IONR    DB 52            NO. OF RECORDS
IOTA    DB 0            TRACK ADDRESS
IOSA    DB 0            SECTOR ADDRESS
IOLBA   DB 0            LOWER BUFF. ADD.
IOUBA   DB 0            UPPER BUFF. ADD.
*
* RECALIBRATE
*
RECAL   MOV AL,!RECALIN   BL SHOULD HOLD UNIT NO.
        XOR DX,DX
       MOV CX,!1       TRACK ADDRESS 0, SECTOR ADD. 1
        CALL DISKINS
        RET
*
* GENERAL DISK INSTRUCTION
*   BL   UNIT NO.
*   AL   INSTRUCTION
*   CH   TRACK ADDRESS
*   CL   SECTOR ADDRESS
*   DH   UPPER BUFFER ADDRESS
*   DL   LOWER BUFFER ADDRESS
*
DISKINS MOV IOTA,CH
        MOV IOSA,CL
        OR AL,!#T0000        8 BIT WORDS
        MOV CL,!4
        SHL BL,CL            SHIFT UNIT BITS
        OR AL,BL             OR WITH INST.
        AND AL,!#3F          CLEAR TOP 2 BITS
        MOV IODI,AL
        MOV IOLBA,DL
        MOV IOUBA,DH
        MOV AX,!IOPB+#4000
        OUT BASE+1
        MOV AL,AH
        PUSH AX
        POP AX
        OUT BASE+2           START CHANNEL
        RET
*
* MAKIPL
*
MAKIPL  MOV BL,!0        unit number
        MOV AL,!READIN
        CALL DISKINS
        CALL WAITC
        OR AX,AX
        JE MAKRET
        INT                          ERROR
MAKRET  RET
*
* WAITC, WAIT FOR CHANNEL END , LOOK AT RESULT
*
WAITC   IN BASE+0
        TEST AL,!INTPEND
        JE WAITC              BUSY WAIT
        PUSH AX
        POP AX
        IN BASE+1             0 IF ERROR
       MOV AH,AL
        PUSH AX
        POP AX
       IN BASE+3             RESULT BYTE
        RET
*
* RESET CHANNEL
*
RESET   OUT BASE+7
        RET
*
*
*
RECALIN EQU 3
FORMIN  EQU 2
READIN  EQU 4
WRITEIN EQU 6
INTPEND EQU 4
*
FCH     EQU $
*
        END