;18 JAN 77. BRH. CREATED.
;
;***********************************************************
;***********************************************************
;****                                                   ****
;****             TARBELL BOOTSTRAP LOADER              ****
;****                                                   ****
;****        (C) COPYRIGHT 1977, IMSAI MFG CORP         ****
;****              SAN LEANDRO, CALIFORNIA              ****
;****                                                   ****
;***********************************************************
;***********************************************************
;
; THIS PROGRAM HAS SEVERAL SPECIAL CONSTRAINTS:
;
;   1. IT MUST BE CAPABLE OF RUNNING IN PROM.
;
;   2. IT MUST USE NO RAM OTHER THAN THAT INTO WHICH THE
;      BOOTED PROGRAM IS LOADED; IN PARTICULAR, IT MUST NOT
;      USE A STACK.
;
;   3. IT MUST RUN IN 512 BYTES, STARTING AT FA00.
;
;   4. IT MUST NOT INCLUDE BYTES 'FA' AND 'FB' AS ANYTHING
;      BUT HI ADDRESS BYTES, SO IT MAY BE RELOCATED. THIS
;      MEANS THAT THE INSTRUCTIONS 'JM' AND 'EI' MUST NOT
;      BE USED, AND THAT 'FA' AND 'FB' MUST NOT OCCUR IN
;      THE 2ND BYTE OF AN INSTRUCTION.
;
CRI     EQU     0       ;CASSETTE PORT
CRL     EQU     3       ;CONTROL PORT
CRY     EQU     4       ;CASSETTE READY BIT
;
        ORG     0FA00H
START:  XRA     A       ;TURN ON LIGHTS...
        OUT     0FFH
        MVI     A,60H   ;SET MIO TO READ BY BIT...
        OUT     CRL
SYNC0:  IN      CRL
        ANI     CRY
        JZ      SYNC0
        IN      CRI     ;READ THEM
        CPI     0E6H    ;ARE THEY A SYNC
        JNZ     SYNC0   ;WAIT TILL A SYNC IS FOUND
        MVI     A,20H   ;SET TO READ BY BYTE...
        OUT     CRL
        MVI     B,31    ;# OF OTHER SYNC'S AT START OF FILE
SYNC1:  IN      CRL     ;WAIT TILL A BYTE IS READY...
        ANI     CRY
        JZ      SYNC1
        IN      CRI     ;READ THE BYTE
        CPI     0E6H    ;IS IT A SYNC?
        JNZ     START   ;START OVER IF NOT
        DCR     B       ;COUNT SYNC'S
        JNZ     SYNC1   ;LOOP UNTIL STRIP DONE
TYPE:   IN      CRL     ;READ RECORD TYPE...
        ANI     CRY
        JZ      TYPE
        IN      CRI
        DCR     A       ;IS IT 1 (ABSOLUTE BINARY OBJECT)?
        JNZ     START   ;START OVER IF NOT
COUNT:  IN      CRL     ;READ RECORD COUNT...
        ANI     CRY
        JZ      COUNT
        IN      CRI
        CPI     11      ;IS IT 11 (5-BYTE NAME + 3 2-BYTE ADDR'S)
        JNZ     START   ;START OVER IF NOT
        MVI     B,5     ;INIT COUNTER OF BYTES IN NAME
        LXI     D,0     ;INIT CHECKSUM
NAME:   IN      CRL     ;READ A BYTE...
        ANI     CRY
        JZ      NAME
        IN      CRI
        ADD     E       ;ADD TO CHECKSUM
        MOV     E,A
        MVI     A,0
        ADC     D
        MOV     D,A
        DCR     B       ;COUNT LETTERS
        JNZ     NAME    ;READ 5 OF THEM
ADDS0:  IN      CRL     ;READ LO BYTE OF START ADDRESS...
        ANI     CRY
        JZ      ADDS0
        IN      CRI
        MOV     L,A     ;SAVE IN L
        ADD     E       ;ADD TO CHECKSUM...
        MOV     E,A
        MVI     A,0
        ADC     D
        MOV     D,A
ADDS1:  IN      CRL     ;READ HI BYTE OF START ADDRESS...
        ANI     CRY
        JZ      ADDS1
        IN      CRI
        MOV     H,A     ;SAVE IN H
        ADD     E       ;ADD TO CHECKSUM...
        MOV     E,A
        MVI     A,0
        ADC     D
        MOV     D,A
        SPHL            ;SAVE START ADDRESS IN SP
ADDE0:  IN      CRL     ;READ LO BYTE OF END ADDRESS...
        ANI     CRY
        JZ      ADDE0
        IN      CRI
        MOV     L,A     ;SAVE IN L
        ADD     E       ;ADD TO CHECKSUM...
        MOV     E,A
        MVI     A,0
        ADC     D
        MOV     D,A
ADDE1:  IN      CRL     ;READ HI BYTE OF END ADDRESS...
        ANI     CRY
        JZ      ADDE1
        IN      CRI
        MOV     H,A     ;SAVE IN H
        ADD     E       ;ADD TO CHECKSUM...
        MOV     E,A
        MVI     A,0
        ADC     D
        MOV     D,A
        MVI     B,2     ;READ LAST 2 BYTES AND ADD TO CHECKSUM...
ADDX:   IN      CRL
        ANI     CRY
        JZ      ADDX
        IN      CRI
        ADD     E
        MOV     E,A
        MVI     A,0
        ADC     D
        MOV     D,A
        DCR     B
        JNZ     ADDX
        XCHG            ;PUT CHECKSUM IN HL, END ADDRESS IN DE
CHECB:  IN      CRL     ;READ HI CHECKSUM BYTE INTO B...
        ANI     CRY
        JZ      CHECB
        IN      CRI
        MOV     B,A
CHECC:  IN      CRL     ;READ LO CHECKSUM BYTE INTO C...
        ANI     CRY
        JZ      CHECC
        IN      CRI
        MOV     C,A
        DAD     B       ;ADD TO ACCUMULATED CHECKSUM
        MOV     A,H     ;IS RESULT 0?...
        ORA     L
        JNZ     START   ;ABORT IF NOT
        DAD     SP      ;GET START ADDRESS INTO HL
        MOV     A,E     ;SUBTRACT START FROM END ADDRESS AND
        SUB     L       ;  PUT RESULT IN HL...
        MOV     L,A
        MOV     A,D
        SBB     H
        MOV     H,A
        DAD     H       ;DOUBLE IT
        MOV     C,H     ;PUT RECORD COUNT IN C...
        INR     C
        LXI     H,0     ;PUT START ADDRESS IN HL...
        DAD     SP
RECOR:  MOV     A,H     ;PUT HIGH ADDRESS BYTE IN LIGHTS...
        CMA
        OUT     0FFH
RTYPE:  IN      CRL     ;READ RECORD TYPE..
        ANI     CRY
        JZ      RTYPE
        IN      CRI
        CPI     81H     ;IS IT AN ABSOLUTE BINARY OBJECT
        JNZ     START   ;ABORT IF SO
RCOUN:  IN      CRL     ;READ BYTE COUNT...
        ANI     CRY
        JZ      RCOUN
        IN      CRI
        MOV     B,A     ;PUT IN B
        LXI     D,0     ;INIT CHECKSUM
RDATA:  IN      CRL
        ANI     CRY
        JZ      RDATA
        IN      CRI
        MOV     M,A     ;STASH IT...
        INX     H
        ADD     E       ;ADD TO CHECKSUM...
        MOV     E,A
        MVI     A,0
        ADC     D
        MOV     D,A
        DCR     B       ;COUNT BYTES
        JNZ     RDATA   ;LOOP TILL ALL DATA IN
RCHEK:  IN      CRL     ;READ HI CHECKSUM BYTE...
        ANI     CRY
        JZ      RCHEK
        IN      CRI
        MOV     B,A     ;SAVE IT IN B
RCHEL:  IN      CRL     ;READ LO CHECKSUM BYTE...
        ANI     CRY
        JZ      RCHEL
        IN      CRI
        ADD     E       ;ADD TO LO BYTE OF ACCUMULATED CHECKSUM
        JNZ     START   ;ABORT IF ERROR
        MOV     A,B     ;GET HI CHECKSUM BYTE BACK INTO A
        ADC     D       ;ADD TO HI BYTE OF ACCUMULATED CHECKSUM
        JNZ     START   ;ABORT IF ERROR
        DCR     C       ;COUNT RECORDS
        JNZ     RECOR   ;LOOP TILL ALL READ
        XRA     A       ;TURN LIGHTS ON (LIKE AFTER A RESET)...
        OUT     0FFH
        LXI     H,0     ;GET START ADDRESS INTO HL...
        DAD     SP
        PCHL            ;OKAY BUB, HEAD OUT
;
        END
