; B5LO-1.INS - BYE5 insert for Lobo MAX-80 with CP/M+ - 08/17/85 ; ; Z80 SIO and 8116 baudrate generator ; ; ; NOTE: This is an insert, not an overlay ; ;= = = = = = = = = = = = = = = = = = ; ; 08/17/85 Updated B+LO-1.INS for BYE5 - James Dunn ; ;= = = = = = = = = = = = = = = = = = ; ; ;The following define the address to use. ; SIODA EQU 0F7E4H ; Modem data window SIOCA EQU 0F7E5H ; Modem control window BAUDA EQU 0F7D0H ; Baud rate window ; ; ; The following are baud rates for BAUDA ; B300 EQU 05H ; 300 bps B1200 EQU 07H ; 1200 bps B2400 EQU 0AH ; 2400 bps ; ; ;----------------------------------------------------------------------- ; ; See if there is a carrier. If not, return with the zero flag set. ; MDCARCK:MVI A,10H ; Reset status STA SIOCA LDA SIOCA ; Get status ANI 8 ; Check for data carrier RET ; Return ;..... ; ; ; This routine will turn off the serial card and hang up the phone. ; MDINIT: MVI A,18H ; Reset channel STA SIOCA MVI A,4 ; Setup to write register 4 STA SIOCA MVI A,44H ; 16x, 1 stop bit, no parity STA SIOCA MVI A,1 ; Setup to write register 1 STA SIOCA MVI A,0 ; Value to write to register 1 STA SIOCA MVI A,5 ; Setup to write register 5 STA SIOCA MVI A,0 ; DTR off, RTS off STA SIOCA 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 STA SIOCA MVI A,0C1H ; 8 bits/char, RX enable STA SIOCA MVI A,5 ; Setup to write register 5 STA SIOCA MVI A,0EAH ; DTR on, 8 bits/char, TX enable, RTS on STA SIOCA ; IF IMODEM ; If using a smartmodem CALL IMINIT ; Go initialize smartmodem now ENDIF ; Imodem ; RET ; Return ;..... ; ; ; Input a character ; MDINP: LDA SIODA ; Get character RET ; Return ;..... ; ; ; Check the status to see if a character is available. Return with zero ; flag set if not. If yes, use 0FFH to clear the flag. ; MDINST: LDA SIOCA ; Get status ANI 1 ; Got a character? RZ ; Return if none ORI 0FFH ; Otherwise, set the proper flag RET ; And return ;..... ; ; ; Send a character to the modem. ; MDOUTP: STA SIODA ; Send it RET ; Return ;..... ; ; ; See if the outputa is ready for another character. ; MDOUTST:LDA SIOCA ANI 4 ; Mask it RET ; Return ;..... ; ; ; Reintialize the modem and hang up the phone by dropping DTR and ; leaving it inactive. ; MDQUIT: IF IMODEM ; If using a smartmodem CALL IMQUIT ; Tell it to shut down ENDIF ; Imodem ; ; ; Called by the main program after the caller types BYE ; MDSTOP: MVI A,5 ; Setup to write register 5 STA SIOCA MVI A,0 ; DTR off, RTS off STA SIOCA RET ;..... ; ; ; If you do not support a particular baud rate, put it here before ; SETINV: ; SETINV: ORI 0FFH ; Make sure zero flag is not set RET ; Return ;..... ; ; SET300: MVI A,B300 ; Load rate JMP SETBAUD ; SET1200:MVI A,B1200 ; Load rate JMP SETBAUD ; SET2400:MVI A,B2400 ; Load rate JMP SETBAUD ; SETBAUD:STA BAUDA ; Send first byte of command MVI A,10H ; Reset ext/status interrupts STA SIOCA XRA A ; Say rate is ok RET ; Return ;..... ; ; ;======================================================================= ; Lobo MAX-80 CP/M Plus bank control area ;======================================================================= ; ; jjd - 14 Jul 85 ; Ok, this is my current understanding of how and why BYE5 needs ; control over bank switching. Character I/O goes through the ; BDOS and through the BIOS to the actual, machine dependent, ; character I/O routines. The physical character I/O routines ; under Plus on the MAX-80 are in common, non-banked memory, around ; the F2xxH area. Now, normally, character I/O goes from the ; user application program (like an RBBS or whatever) running in ; the TPA in bank 1, to the part of the BDOS in common memory, to ; the part of the BIOS in common memory. When BYE is in control, ; the character I/O is captured as it is sent to the BIOS routines, ; and sent through the famous local/remote virtual "Y" connector. ; The BYE "Y" connector sits in the RSX. This RSX is not used the ; way DRI intended, where it would filter BDOS calls, but rather, it ; is used to grab and save some memory for its console trapping code. ; Now comes the good news for we MAX-80 people. Lobo decided to ; give us 32k of common memory. I'm not sure if that really produces ; an efficient CP/M Plus machine, but it sure makes RSXing easy as ; compared to the Osborne Exec or the Morrow machine. We can leave ; our BYE "Y" code right in the RSX. George and Paul had to move ; their code onto a "safe" area in the common BDOS. ; ; So, by now you should be wondering why we MAXers should have to worry ; about bank switching at all. Well, here's why. Way back I said ; normally I/O from appl prgm via BDOS via BIOS, right, well, some I/O, ; like CP/M error messages, comes from bank 0, the banked portions of ; the BDOS and BIOS. But, that's not the problem, directly. These I/O ; calls go through the BIOS jump table at F200 and display ok. ; The problem is that when I/O originates from bank 0, and BYE ; gets control at each CONOUT call, it does its normal job of checking ; the current user/drive values at 00004H and comparing them with ; the values plugged in at 003DH and 003FH. Right, you got it, these ; values are, of course, over in bank 1, not in bank 0. Then to ; put the icing on the cake, when a drive or user check fails, ; BYE sets up to A0: does a JP 0000H to get a warm boot ..... ; and we just went south on that one. ; ; So, we realize that even when we do character I/O from any bank, we ; need bank 1 current to check those magic values in the low page of ; bank 1, and to allow a warm boot via JP 0000H. The code runs ok ; in the common memory, and the stack space is not lost. ; This is why I didn't bother with adjusting any stack pointers. ; Another solution which I think should work, would be to grab these ; magic values in the low page of bank 1, MAXUSER, WHEEL and MAXDRIV, ; and put them right into the RSX. ; This would also need the read/write at 0004H to be cancelled, and ; use only the SCB values. I think this approach would work on the ; MAX, and might even work on other machines, if they have enough ; extra room?, not sure. ; ; Possible GOTCHAs :: Ok, when bank switching, we have to switch ; back to the bank from hence we came. When using the bios as ; supplied from Lobo, this value, named CBNK in the Lobo Source, ; and in the DRI CP/M 3 System Guide, is at address 0F2A5H. See ; it at the end of the file XROOT.MAC as supplied from Lobo. ; Also, I call BNKSEL directly at F29FH. Now these will work fine ; unless you modify any of the BIOS source by adding or removing ; bunches of code. These values will change, and you will have to ; snoop around and find the new values. If you can handle BIOS ; modification, you can handle this change. ; ; Also, during testing, I got strange results when I turned on the ; RSPEED equate. I'm not sure why, so I am leaving it off... ; I probably wouldn't use it anyway. ; ;----------------------------------------------------------------------- ; ; 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. ; ; ; Replace the NEWJTBL BIOS routing table with our own ; MDPREP: LXI H,JTBLNEW ; Get replacement table address LXI D,NEWJTBL ; Get address to overwrite LXI B,JTBLEN ; Get number of bytes to overwrite DB 0EDH,0B0H ; Z80 ldir instruction RET ;..... ; ; ; Perform system or hardware dependent POST-processing. ; The following code will be executed by the EXCPM routine before re- ; turning control to CP/M Plus when the BYE5 program is terminated. ; MDPOSP: RET ;..... ; ; WBCOMN: CALL SWIN ; Warm boot JMP MBOOT ;..... ; ; CSCOMN: CALL SWIN ; Console status CALL MSTAT JMP SWOUT ;..... ; ; CICOMN: CALL SWIN ; Console input CALL MINPUT JMP SWOUT ;..... ; ; COCOMN: CALL SWIN ; Console output CALL MOUTPUT JMP SWOUT ;..... ; ; CBNK EQU 0F2A5H ; Address of the current bank byte BNKSEL EQU 0F29FH ; Entry point of BIOS bank select RTBNK DS 1 ; Place to store bank to return to ; SWIN: PUSH A ; Bank switch in routine LDA CBNK ; Get the bank we are switching from STA RTBNK ; Store so we know where to switch back MVI A,1 ; We are going to switch to bank 1 CALL BNKSEL ; Switch to bank 1 POP A ; Restore 'A' and flags RET ;..... ; ; SWOUT: PUSH A ; Save 'A' and flags LDA RTBNK ; Get the bank to return to CALL BNKSEL ; Return to that bank POP A ; Restore 'A' and flags RET ;..... ; ; JTBLNEW:JMP MCBOOT ; Cold boot JMP WBCOMN ; Warm boot JMP CSCOMN ; Modem status test JMP CICOMN ; Modem input routine JMP COCOMN ; Modem output routine ; IF NOT HARDLOG JMP COCOMN ; Modem list device JMP COCOMN ; Modem punch device JMP CICOMN ; Modem reader device ENDIF ; NOT HARDLOG ; JTBLEN EQU $-JTBLNEW ;..... ; ; end ;-----------------------------------------------------------------------