; B5MH-5.INS - BYE5 insert for Morrow MD5, MD11, MD16, MD34 - 08/26/86
;
;               Z80 SIO and 8253 baudrate generator
;
;                This is an insert, not an overlay
;
; This insert adapts the Morrow computers using hard disk and CP/M+
; with bank memory to BYE5.
;
;
;=   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
;
; 08/26/86  Changed SETINV routine.  Added comment of where to reinstall
;    v5     MDPREP and MDPOSP calls in the main program.
;                                       - George Reding
;
; 07/18/86  Removed bank switching code for compatibility with BYE510
;    v4     or greater.                 - Stuart Rose
;
; 10/10/85  Reorganized and simplified. - Ed Meyer
;    v3
;
; 08/25/85  Fixed BUG in the Morrow BIOS INTER-BANK routine.
;    v2                                 - Paul Bartholomew
;
; 08/17/85  Updated for compatibility with BYE501.
;    v1                                 - George Peace
;
;=   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
;
; To get this to work correctly with a Morrow MD-HD, you must configure
; your cable in accord with the setting of jumpers inside your computer.
; Pins 2 and 3 may or may not need to be crossed. Carrier detect (pin 8)
; from the modem will connect to pin 8 (or pin 4) on the computer, in
; accord with the setting of the jumpers.
;
; ** Consult your MD-## Users Guide, Appendix D, figures D-5 and D-6. **
;
;-----------------------------------------------------------------------
;
;
; Set ONE of the following to YES, the other to NO
;
PMPORT  EQU     NO              ; Yes, using "Printer/Modem" port
AUXPORT EQU     YES             ; Yes, using "Auxilliary" port
;
PORT    EQU     060H            ; Port for local console output
CONST   EQU     PORT+1          ; Local console status
;
;
        IF     PMPORT
BPORT   EQU     062H
BAUDS   EQU     051H
MODEW   EQU     07EH
        ENDIF                  ; PMPORT

        IF     AUXPORT
BPORT   EQU     070H
BAUDS   EQU     050H
MODEW   EQU     03EH
        ENDIF                  ; AUXPORT
;
;
; The following define the port addresses to use.
;
DPORT   EQU     BPORT           ; Data port
MDCTL1  EQU     BPORT+1         ; Status/control port
BRPORT  EQU     053H
;
;
; The following are MDCTL1 status masks
;
MDRCV   EQU     1               ; Data available
MDSND   EQU     4               ; Transmit buffer empty
DCD     EQU     8               ; Data carrier detect
;
;-----------------------------------------------------------------------
;
;
; See if we still have a carrier - if not, return with the zero flag set
;
MDCARCK:MVI     A,10H           ; Reset status
       OUT     MDCTL1
       IN      MDCTL1          ; Get status
       ANI     DCD             ; Check for data carrier
       RET                     ; Return
;.....
;
;
; Disconnect and wait for an incoming call
;
MDINIT: MVI     A,18H           ; Reset channel
       OUT     MDCTL1
       MVI     A,4             ; Setup to write register 4
       OUT     MDCTL1
       MVI     A,44H           ; No parity, 1 stop, 16x
       OUT     MDCTL1
       MVI     A,1             ; Setup to write register 1
       OUT     MDCTL1
       MVI     A,0
       OUT     MDCTL1
       MVI     A,5             ; Setup to write register 5
       OUT     MDCTL1
       MVI     A,0             ; DTR, RTS both off
       OUT     MDCTL1
       PUSH    B               ; Save in case it's being used elsewhere
       MVI     B,20            ; 2 second delay
;
OFFTI:  CALL    DELAY           ; 0.1 second delay
       DCR     B
       JNZ     OFFTI           ; Keep looping until finished
       POP     B               ; Restore bc
       MVI     A,3             ; Setup to write register 3
       OUT     MDCTL1
       MVI     A,0C1H          ; 8 bits, enable receive
       OUT     MDCTL1
       MVI     A,5             ; Setup to write register 5
       OUT     MDCTL1
       MVI     A,0EAH          ; DTR, RTS, TX on, 8 bits
       OUT     MDCTL1

        IF     IMODEM          ; If using intelligent modem
       CALL    IMINIT          ; Go initialize modem now
        ENDIF                  ; IMODEM
;
       RET                     ; Return
;.....
;
;
; Input a character from the modem port
;
MDINP:  IN      DPORT           ; Get character
       RET                     ; Return
;.....
;
;
; Check the status to see if a character is available.  If not, return
; with the zero flag set.  If yes, use 0FFH to clear the flag.
;
MDINST: IN      MDCTL1          ; Get status
       ANI     MDRCV           ; Got a character?
       RZ                      ; Return if none
       ORI     0FFH            ; Otherwise, set the proper flag
       RET                     ; And return
;.....
;
;
; Send a character to the modem
;
MDOUTP: OUT     DPORT           ; Send it
       RET                     ; Return
;.....
;
;
; See if the output is ready for another character
;
MDOUTST:IN      MDCTL1
       ANI     MDSND           ; Mask it
       RET                     ; Return
;.....
;
;
; Reinitialize the modem and hang up the phone by dropping DTR and
; leaving it inactive.
;
MDQUIT:  IF     IMODEM          ; If using an intelligent modem
       CALL    IMQUIT          ; Tell it to shut down
        ENDIF                  ; IMODEM
;
;
; Called by the main program after caller types BYE.
;
MDSTOP: MVI     A,5             ; Setup to write register 5
       OUT     MDCTL1
       MVI     A,0             ; Clear DTR, RTS causing shutdown
       OUT     MDCTL1
       RET
;.....
;
;
; The following routine sets the baudrate.  BYE5 asks for the maximum
; speed you have available.
;
SETINV: ORI     0FFH            ; Make sure zero flag is not set
       RET
;.....
;
;
SET300: LXI     H,BD300
       JMP     SETBAUD
;
SET1200:LXI     H,BD1200
       JMP     SETBAUD
;
SET2400:LXI     H,BD2400
       JMP     SETBAUD
;
SETBAUD:MVI     A,MODEW
       OUT     BRPORT
       MOV     A,L
       OUT     BAUDS
       MOV     A,H
       OUT     BAUDS
       XRA     A               ; Say rate is ok
       RET                     ; Return
;.....
;
;
; The following are baud rates for BPORT -- they will have to be changed
; for your particular CTC.
;
BD300   EQU     833
BD1200  EQU     208
BD2400  EQU     104
BD9600  EQU     26
;.....
;
;
;Find address of INTER-BANK BUG in Morrow's BIOS
;
FINDBUG:LDA     FNDBUG          ; See if we already found the address
       ORA     A
       JZ      FBUG0           ; No, go find it
       LHLD    BUGADR          ; Yes, return with address
       RET
;.....
;
;
FBUG0:  LHLD    1
       INX     H
       MOV     E,M
       INX     H
       MOV     D,M
       XCHG                    ; Hl points to warm boot code
;
;
; The warm boot in common memory is as follows:
;
; loc  opcodes  mneumonics
; ---- -------  --------------------
; xxxx 21 yyyy  LD      HL,BNK-WBOOT ;WARM BOOT code in SYSTEM bank
; xxxx 18 zz    JR      INTER-BANK
;
; We will find the address of INTER-BANK and modify it to fix the BUG.
;
; The INTER-BANK code in COMMON memory is as follows:
;
; loc  opcodes  mneumonics
; ---- -------  --------------------
; xxxx 3A yyyy  LD      A,(SYSMTE-BANK-BITS)
; xxxx CB 47    BIT     0,A     ;Should be BIT 1,A (CB 4F)
;
;
FBUG1:  MOV     A,M
       CPI     18H             ; Look for JR to INTER-BANK
       JZ      FBUG2
       INX     H
       JMP     FBUG1
;
FBUG2:  INX     H
       MOV     A,M             ; Get JR offset
       INX     H
       MOV     E,A
       MVI     D,0
       DAD     D               ; HL now points to INTER-BANK
;
FBUG3:  MOV     A,M
       CPI     0CBH            ; Look for bit opcode
       JZ      FBUG4
       INX     H
       JMP     FBUG3
;
FBUG4:  INX     H
       SHLD    BUGADR
       MVI     A,0FFH
       STA     FNDBUG
       RET
;.....
;
;
FNDBUG: DB      0
BUGADR: DW      0
BUGVAL: DB      0
;
;.....
;
; In the main program, CALL to MDPREP and MDPOSP should be at the
; following locations.  If not present, they may be re-installed.
; CALL MDPREP should be in the PATCH: routine, before CALL TBLADDR.
; CALL MDPOSP should be in the EXCPM: routine, before CALL RSXCLR.
;
;.....
;
; Perform system or hardware dependent PRE-processing.  The following
; code will be executed by the PATCH subroutine before the BIOS jump
; table is overwritten.  This will allow the BIOS intercept routines to
; operate as early as the initial signon message display.
;
MDPREP: CALL    FINDBUG         ; Get address of BIOS bug
       MOV     A,M
       STA     BUGVAL          ; Save old value
       MVI     M,04FH          ; Change the bit 0,A to a bit 1,A
;
; OK, the BIOS BUG is now fixed.
;
       RET
;.....
;
;
; Perform system or hardware dependent POST-processing.  The following
; code will be executed by the EXCPM routine before returning control to
; CP/M Plus when the BYE5 program is terminated.
;
MDPOSP: CALL    FINDBUG         ; Get address of BIOS bug
       LDA     BUGVAL          ; Get old value
       MOV     M,A             ; Un-fix the BIOS bug (make it a bit 0)
       RET
;.....
;
;                              end
;-----------------------------------------------------------------------