;
*******************************************************
;
; This is the DELTA PRODUCTS  2K boot prom for use with 
; standard floppy systems.
;                               PROM185 11/20/82
*******************************************************
;
FALSE           EQU     0
TRUE            EQU     NOT     FALSE
;
VERSION         EQU     0185H           ; CODE RETURNED WHEN CONSTAT CALLED (L,H)
SIO             EQU     FALSE           ; TRUE FOR REV C CPU'S (TYPE 1.95)
I8251           EQU     TRUE            ; TRUE FOR REV B CPU'S (TYPE 1.85)
DBUG            EQU     FALSE           ; TRUE TO RUN IN RAM FOR TESTING
STK             EQU     8000H           ; ONLY FOR DEBUGING
;
; Console and List I/O port equates
;
STAT            EQU     3
DATA            EQU     2
LSTSTAT         EQU     1
LSTDAT          EQU     0

        IF      SIO
RxMASK          EQU     0000$0001B
TxMASK          EQU     0000$0100B
LISTMASK        EQU     0010$1100B
        ENDIF

        IF      I8251
RxMASK          EQU     0000$0010B
TxMASK          EQU     0000$0001B
LISTMASK        EQU     1000$0101B
        ENDIF
;
WAITX           EQU 0FCH
SECT            EQU 0FAH
DCOM            EQU 0F8H
DDATA           EQU 0FBH
DSTAT           EQU 0F8H
DENS            EQU 0FDH
;
;**************************************************************
        MACLIB  Z80
;
        IF DBUG
        ORG 08000H
        ELSE
        ORG 0F800H
        ENDIF
;
        PROM    EQU     $

        JMP     MONINZ          ;INITIALIZE ROUTINE
        JMP     MONTR           ;MONITOR W/O INIZ
        JMP     CONSTAT         ;CONSOLE STATUS
        JMP     CONIN           ;CONSOLE INPUT (LOCAL PORT 'B')
        JMP     CONOUT          ;CONSOLE OUTPUT (LOCAL PORT 'B')
        JMP     LIST            ;LOCAL PORT 'A'
        JMP     OUTHX           ;BINARY TO HEX OUTPUT (CHAR IN 'B' REG)
        JMP     ADOUT           ;ADDRESS TO HEX OUT   (IN H,L)
        JMP     GETVERS         ;GET VERS IN HL
;
MONTR:
        LXI     D,BACK1
        JMP     GETSTACK
STARTX:
        EXX             ;Z-80 EXX TO GET STACK ADRESS
        SPHL            ;IT'S IN HL
        EXX             ;PUT IT ALL BACK FOR NEXT TIME
BACK1:  CALL CRLF
        MVI A,'*'
        CALL OUTA
        CALL INECO
        LXI D,3
        LXI H,CMDS
        MOV B,A
        MVI C,0FFH
CLOOP   MOV A,M
        CMP B
        JZ FOUND
        CMP C
        JZ ERROR
        DAD D
        JMP CLOOP
ERROR   MVI A,'?'
        CALL OUTA
        JMP STARTX
CMDS    DB 'L'
        DW LOAD
        DB 'G'
        DW GO
        DB 'D'
        DW DUMP
        DB 'M'
        DW MOVE
        DB 'V'
        DW VIEW
        DB 'F'
        DW ZERO
        DB 'X'  
        DW MEM
        DB 'H'
        DW HSRCH
        DB 'F'-40H
        DW BOOT                         ; dp - dsk
        DB 'C'-40H
        DW BOOT
;
        DB 0FFH
FOUND   CALL SPACE
        INX H
        MOV E,M
        INX H
        MOV D,M
        XCHG
        PCHL
HSRCH:
        CALL    IN2AD
        PUSH    IX
        PUSH    H
        INX     D
        PUSH    D
        MVI     D,00H
INLP:
        PUSH    D
        CALL    INHX
        POP     D
        DB 0DDH,71H,00H ;MOV 0(X),C
        ORA     A
        JNZ     FIND1
        DB 0DDH,2BH     ;DCX IX
        INR     D
        CALL    SPACE
        JMP     INLP
FIND1:
        POP     B
        CALL    CRLF
FIND:
        POP     H
        DB 0DDH,0E1H    ;POP IX
        MOV     E,D
        DB 0DDH,7EH,00H ;MOV A,0(X)
        DB 0EDH,0B1H    ;CPIR
        JPO     STARTX
        DB 0DDH,0E5H    ;PUSH IX
        PUSH    H
FND:
        DCR     E
        JZ      RPT
        DB 0DDH,7EH,0FFH        ;MOV A,-1(X)
        CMP     M
        JNZ     FIND
        INX     H
        DB 0DDH,2BH     ;DCX IX
        JMP     FND
RPT:
        POP     H
        PUSH    H
        DCX     H
        PUSH    B
        CALL    ADOUT
        CALL    CRLF
        POP     B
        JMP     FIND
;
OHOH:   PUSH PSW
        CALL CONSTAT1
        JNZ STARTX
        POP PSW
        RET
;
LOAD    CALL INADR
LOAD1   CALL CRLF
        CALL ADOUT
LOAD2   MVI A,'-'
        CALL OUTA
        MOV B,M
        CALL OUTHX
        CALL SPACE
        MVI A,'<'
        CALL OUTA
        CALL SPACE
        CALL INHX
        CPI 0DH
        JZ NNTRY
        MOV M,C
NNTRY   INX H
        JMP LOAD1
DUMP    CALL IN2AD
DUMP1   CALL CRLF
        CALL ADOUT
        MVI B,8
DUMP2   PUSH B
        MOV B,M
        CALL OUTHX
        CALL SPACE
        MOV A,D
        ORA E
        JZ STARTX
        DCX D
        INX H
        POP B
        DCR B
        JNZ DUMP2
        CALL OHOH
        JMP DUMP1
ZERO    CALL SPACE
        LXI H,STARTX
        PUSH H
HRZ1    CALL INADR
        PUSH H
        CALL INADR
        PUSH H
        CALL INHX
        MOV B,C
        POP D
        POP H
HRZ2    MOV M,B
        INX H
        MOV A,L
        CMP E
        JNZ HRZ2
        CALL OHOH
        MOV A,H
        CMP D
        JNZ HRZ2
        RET
MOVE    CALL SPACE
        LXI H,STARTX
        PUSH H
HRM1    CALL INADR
        PUSH H
        CALL INADR
        PUSH H
        CALL INADR
        POP B
        POP D
        XCHG
HRM2    MOV A,M
        STAX B
        INX H
        INX B
        DCX D
        MVI A,0
        CMP E
        JNZ HRM2
        CALL OHOH
        CMP D
        JNZ HRM2
        RET
INECO   CALL INA
        CALL OUTA
        RET
CRLF:   MVI A,0DH
        CALL PRINT
        MVI A,0AH
        JMP PRINT
;
TST1:
        MOV D,A
        CPI 48
        JM ER1
        CPI 71
        JP ER1
        CPI 58
        JP LTR
        ANI 0FH
TST2:   MOV C,A
        MOV A,D
        STC
        RET
LTR:
        CPI 65
        JM ER1
        ANI 0FH
        ADI 9
        JMP TST2
ER1:
        ORA A
        RET
;
INADR:
        LXI H,0000H
        CALL INH
        RNC
        MOV L,C
        MOV B,C
        CALL INH
        JNC REXIT
        CALL RLT
        CALL INH
        JNC REXIT
        MOV H,B
        MOV B,L
        CALL RLT
        CALL INH
        JNC REXIT
        MOV H,B
        CALL RLT
REXIT:  CALL SPACE
        CALL SPACE
        CALL SPACE
        CALL SPACE
        RET
;
RLT:
        MOV A,L
        ANI 0FH
        RLC
        RLC
        RLC
        RLC
        ADD C
        MOV L,A
        RET
;
INH:
        CALL INA
        CPI 0DH
        RZ
        CPI '.'
        JZ STARTX
        CALL TST1
        JNC INH
        CALL OUTA
        STC
        RET
;
INHX:
        PUSH H
        LXI H,0000H
        CALL INH
        JNC EXT1
        MOV L,C
        CALL INH
        JNC EXT
        CALL RLT
        MOV C,L
EXT     MVI A,00H
EXT1    POP H
        RET
;
SPACE   MVI A,' '
PRINT   CALL OUTA
        RET
OUTHX   MOV A,B
        RRC
        RRC
        RRC
        RRC
        CALL NIB
        MOV A,B
        CALL NIB
        RET
NIB     ANI 0FH
        CPI 10
        JNC P10
        ADI '0'
        CALL OUTA
        RET
P10     ADI 'A'-10
        CALL OUTA
        RET
ADOUT   MOV B,H
        CALL OUTHX
        MOV B,L
        CALL OUTHX
        JMP REXIT
GO      CALL INADR
        CALL CRLF
        PCHL
IN2AD:  CALL INADR
        PUSH H
        CALL INADR
        POP D
        CPI 0DH
        JZ LIE
        MOV A,L
        SUB E
        MOV L,A
        MOV A,H
        SBB D
        JC ERROR
        MOV H,A
        XCHG
        RET
LIE     LXI H,00B7H
        XCHG
        RET
;
VIEW    LXI H,STARTX
        PUSH H
HRV1    CALL INADR
        MVI A,1
        CALL OUTA
        XRA A
HERE9
        LXI     D,0
        CALL CRLF
        CALL CRLF
        CALL ADOUT
        CALL REXIT
LOOPX:  MVI B,64
LOOPX1: MOV A,M
        ANI 7FH
        CPI 20H
        JP ASCI
        MVI A,' '
ASCI:
        CALL OUTA
        INX D
        INX H
        PUSH    H
        LXI     H,1536
        DSBC    DE
        POP     H
        JZ WAIT
        DCR B
        JNZ LOOPX1
        CALL CRLF
        CALL ADOUT
        CALL REXIT
        JMP LOOPX
WAIT    CALL INA
        CPI ' '
        JZ      STARTX
        CPI 0DH
        JZ HERE9
        JMP WAIT
;
INA:
        CALL CONIN
        RET
OUTA:
        PUSH    B
        MOV C,A
        CALL CONOUT
        POP     B
        RET
;
RETRY:  
        POP     PSW     ;
        DCR     A       ; 
        PUSH    PSW     ;
        JZ      RDONE   ;TIMEOUT, GO REPORT ERROR
        MVI     B,5     ;
RETRY1:
        MVI     A,01000011B     ;STEP IN, NO UPDATE, NO HDLOAD, NO VARIFY, 15 MS
        OUT     DCOM    ;
RETRY2:
        IN      DSTAT   ;
        RRC             ;
        JRC     RETRY2  ;
        DCR     B       ;
        JRNZ    RETRY1  ;
        JR      BOOT1   ;
BOOT:
        MVI     A,5     ;RETRYS
        PUSH    PSW     ;
BOOT1:
        MVI A,0D0H      ;FORCE INTRUPT
        OUT DCOM        ;
HOME1:
        XTHL            ;
        XTHL            ;
        IN DSTAT        ;
        RRC             ;
        JRC HOME1       ;WAIT FOR NOT BUSY FROM 1795
        MVI A,01        ;DO REGULAR RESTORE
        OUT DCOM        ;
        LXI     H,0     ;LOOP COUNT
HOME2:
        XTHL            ;
        XTHL            ;
        INX     H       ;
        MOV     A,L     ;
        ORA     H       ;
        JZ      RETRY   ;
        IN      DSTAT   ;
        ANI     85H     ;READY, TRK 0, BUSY
        CPI     04H     ;
        JNZ     HOME2   ;
        MVI     A,2     ;
        OUT     DENS    ;SINGLE DENSITY
        DCR     A       ;= 1
        OUT     SECT    ;
        LXI     H,0     ;ADDRESS
        MVI     A,8CH   ;
        OUT     DCOM    ;
RLOOP:
        IN      WAITX   ;
        ORA     A       ;
        JP      RDONE   ;
        IN      DDATA   ;
        MOV     M,A     ;
        INX     H       ;
        JR      RLOOP   ;
RDONE:
        LXI     H,MONINZ;
        PUSH    H       ;
        LXI     H,NOSYSMSG
        IN      DSTAT   ;
        ORA     A       ;
        JRNZ    RDONE1  ;
        LDA     0       ;
        CPI     31H     ; 
        JRNZ    MSOUT0  ;
        RST     0       ;
RDONE1:
        STA     100H    ;
        LXI     H,UNDEFMSG
        ANI     90H     ;READY, CRC ERROR
        JRZ     MSOUT0  ;UNDEFINED ERROR
        LXI     H,CRCMSG
        ANI     10H     ;CRC
        JRNZ    MSOUT0  ;
        LXI     H,NRDYMSG
;
MSOUT0:
        CALL    MSOUT   ;
        CALL    CRLF    ;
MSO:
        IN      STAT    ;
        ANI     TXMASK  ;
        RNZ             ;
        JR      MSO     ;
;
MSOUT:
        MOV     A,M
        CPI     '$'
        RZ
        MOV     C,A
        CALL    CONOUT
        INX     H
        JMP     MSOUT
;
MEM:
        LXI     H,MEMMSG
        CALL    MSOUT
        CALL    INA
        ANI     7
        OUT     8
        JMP     STARTX
;
CONIN:
        CALL    CONSTAT1
        JRZ     CONIN
        IN      DATA
        ANI     7FH
        RET
CONOUT:
        IN      STAT
        ANI     TxMASK
        JRZ     CONOUT
        MOV     A,C
        OUT     DATA
        RET
;
GETVERS:
CONSTAT:
        LXI     H,VERSION       ; CALL TO CONSTAT RETURNS VERS IN HL
CONSTAT1:
        IN      STAT
        ANI     RxMASK
        MVI     A,0
        RZ
        CMA
RETURN:
        RET
;
LIST:
        IF      SIO
        MVI     A,10H           ; RESET EXT/STATUS INTERRUPTS
        OUT     LSTSTAT
        ENDIF

        IN      LSTSTAT
        ANI     LISTMASK        ; MASK ALL BUT CTS,DCD,TxBUFFER EMPTY
        CPI     LISTMASK        ; CTS,DCD, & TxBUFFER EMPTY MUST BE HIGH
        JNZ     LIST            ; IF NOT, WAIT
        MOV     A,C
        OUT     LSTDAT
        RET
;
MONINZ:
        IN      0AH
        IN      0BH     ;GET BAUD RATE
        OUT     0BH     ;SET BAUD RATE
        LXI     D,BACK2
        JMP     GETSTACK
BACK2:
        LXI     H,INZLST                ; POINT AT INITLIZE LIST
INZLOOP:
        MOV     B,M                     ; GET # OF PRAMETERS
        INX     H
        MOV     C,M                     ; GET PORT
        INX     H
        DCR     B                       ; TEST FOR 0 PRAMETERS
        INR     B
        JZ      PERIZFIN                ; IF 0 THEN FINISHED
        OUTIR                           ; BLOCK OUTPUT
        JMP     INZLOOP
;
PERIZFIN:
        LXI     H,MSG1S
        CALL    MSOUT
        POP     H       ;STACK ADDRESS
        CALL    ADOUT
        JMP     STARTX
;
;THIS ROUTINE FINDS THE END OF CONTIGIOUS
;MEMORY (STARTING AT ZERO OF COURSE)
;AND SETS THE STACK POINTER TO RESIDE THERE.
;
;NOTE:
;       JUMP TO THIS ROUTINE WITH D&E SET TO THE ADDRESS
;       YOU WISH TO RETURN TO
;
GETSTACK:

        IF DBUG
        EXX
        LXI     H,STK
        PUSH    H
        EXX
        LXIX    STK-30H
        XCHG    
        PCHL
        ENDIF   
;
        LXI     H,0     ;SET START ADDRESS
STOOP   MOV     A,M     ;GET A BYTE
        MOV     B,A     ;SAVE IT
        CMA             ;COMPLEMENT IT
        MOV     M,A     ;WRITE CHANGE TO MEMORY
        CMP     M       ;IS IT WHAT YOU WROTE?
        JNZ     STONE   ;IF NOT, MUST BE OUT OF MEMORY
        MOV     M,B     ;RESTORE MEMORY
        INR     L       ;MEMTEST OPTION ADDED 12/79
        JNZ     STOOP
        INR     H       ;POINT TO NEW PLACE IN MEMORY
        JMP     STOOP   ;KEEP ON TRUCKIN
STONE:
        SPHL            ;SET STACK TO TOP OF MEMORY
        PUSH    H       ;SAVE STACK ADDRESS
        EXX             ;WANT TO SAVE STACK ADDRS
        POP     H       ;IN H&L IN ALTERNATE REGS FOR MONITOR
        PUSH    H       ;       
        EXX             ;
        PUSH    D       ;PUT RET ADDRESS ON STACK
        LXI     D,0-32D ;
        DAD     D       ;
        PUSH    H       ;
        POP     IX      ;
        RET             ;
;
;msg
UNDEFMSG:       DB      'Disk error$'
NOSYSMSG:       DB      'No system$'
CRCMSG:         DB      'CRC error$'
NRDYMSG:        DB      'Drive not ready$'
;
MEMMSG:DB 0DH,0AH,'Bank ? $'
MSG1S: DB 0DH,0AH,0AH,'DELTA PRODUCTS',0DH,0AH
MSG2S: DB 'SYSTEM MONITOR',0DH,0AH
;
        DB      'VERS '
        DB      ((VERSION SHR 12) AND 15) +'0'
        DB      ((VERSION SHR  8) AND 15) +'0'
        DB      '.'
        DB      ((VERSION SHR  4) AND 15) +'0'  
        DB      (VERSION AND 15) +'0'
        DB      0AH,0DH,'$'
;
; base io address for the sio on the rev c cpu
;
INZLST:

        IF      SIO
;
; SIO1 LIST
        DB      10                      ; 10 PRAMETERS TO SEND
        DB      LSTSTAT                 ; PORT TO SEND THEM
        DB      18H
        DB      1
        DB      00H
        DB      4
        DB      4CH
        DB      5
        DB      068H
        DB      3
        DB      41H
        DB      00

        DB      10                      ; 10 PRAMETERS TO SEND
        DB      STAT                    ; PORT TO SEND THEM
        DB      18H
        DB      1
        DB      00H
        DB      4
        DB      4CH
        DB      05
        DB      068H
        DB      3
        DB      41H
        DB      00
        ENDIF

        IF      I8251
        DB      4                       ; 4 PRAMETERS TO SEND
        DB      LSTSTAT                 ; PORT TO SEND THEM
        DB      0AAH                    ; SET MODE
        DB      040H                    ; RESET
        DB      0100$1110B              ; 1 STOP BIT, NO PARITY, 8 BITS, 16X
        DB      0011$0111B              ; RTS = 1, ERROR RESET, Rx ENABLED
                                        ; DTR = 1, Tx ENABLED

        DB      4                       ; 4 PRAMETERS TO SEND
        DB      STAT                    ; PORT TO SEND THEM
        DB      0AAH                    ; SET MODE
        DB      040H                    ; RESET
        DB      0100$1110B              ; 1 STOP BIT, NO PARITY, 8 BITS, 16X
        DB      0011$0111B              ; RTS = 1, ERROR RESET, Rx ENABLED
                                        ; DTR = 1, Tx ENABLED
        ENDIF
        DB      0                       ; END OF TABLE MARKER
;
