; ; ================================================= ; KMOS-1.ASM - MB-KMD patch file for the OSBORNE I ; ================================================= ; ; ; >>>>>>>IMPORTANT This overlay will require you to set LARGEIO to YES ; in the main MB-KMD program. The size allowance ; needed is 100H bytes. ; ; ============= ; Introduction: ; ============= ; ; This file adapts any version of MB-KMD to run with the OSBORNE I. ; ; To use, first edit any options desired into the mainline source code of ; the transfer program, then assemble with ASM or MAC to produce a HEX file. ; ; Then edit this file as needed (check the CONOUT routine if you want to ; locally see file transfer time and the record count while programs are ; being sent). Then assemble this overlay with ASM or MAC. ; ; Now merge the two .HEX files using MLOAD.COM (available on most RCP/M ; systems using the command: ; ; MLOAD KMD=MB-KMD,KMOS-1 ; ; Then place the resulting .COM file on your system where it is accessible ; from any drive/user area (usually A0:) ; ; ; =============== ; Update History: ; =============== ; ; 08/21/86 - Edited for inclusion in MBKMDOVL.LBR - Bob Kramer ; 08/09/86 - Inspected for MB-KMD compatibility - Michael Conley ; 04/15/83 - Adapted XM74EXT.ASM to XM74OS.ASM to ; install patches for the Osborne I. The MINIT ; routine is executed from the standard patch ; area and moves (a la BYE) the rest of the ; routines up to the memory address defined by ; tag DEST. Note that these patches total more ; than the 128 bytes allotted in XMODEM74.ASM, ; so be sure to set LARGEIO to YES and IOSIZE ; to at least the length of the code (100H is ; safe). Remember to increase the number of ; sectors you SAVE out of DDT. - George Peace ; 04/04/83 - Updated to XMODEM74 - Irv Hoff ; 03/27/83 - Updated to XMODEM73 - Irv Hoff ; 03/17/83 - Updated to XMODEM72 - Irv Hoff ; 03/15/83 - Updated to XMODEM71 - Irv Hoff ; ; 03/07/83 Added instructions on how to adapt this file to XMODEM70.COM. ; Standardized the format. Added automatic MSPEED from "BYE" ; program. Added CONOUT information. Adapted from XM70PMMI. ; - Irv Hoff ; ; ; ============== ; NO: EQU 0 YES: EQU NOT NO ; DEST: EQU 0A000H ; Base address for modem routines. Must be ; at least 1 page lower than DEST in BYE. MODCTLP: EQU 02A00H ; Control/Status port MODDATP: EQU 02A01H ; Data In/Out port ; MODRCVB: EQU 01H ; Bit to test for receive MODRCVR: EQU 01H ; Value when ready MODSNDB: EQU 02H ; Bit to test for send MODSNDR: EQU 02H ; Value when ready MODDCDB: EQU 04H ; Carrier detect bit MODDCDA: EQU 04H ; Value when active MODCTSB: EQU 08H ; Clear to send bit MODCTSA: EQU 08H ; Value when active MODFRME: EQU 10H ; Value for framing error MODOVRE: EQU 20H ; Value for overrun error MODPARE: EQU 40H ; Value for parity error ; LSEED: EQU YES ; Yes, using 'BYE' with speed selection ; No, using 'SPEED' manual selection MSPEED: EQU 3CH ; Location of baud rate factor (Set by ; 'BYE') Set location in 'BYE' to agree ; 3DH and 3EH often used by newer versions ; of 'ZCPR'. XSPEED: EQU 1 ; Speed for file time transfer without ; auto-set. Use one of the following: ; 0=110 1=300 2=450 3=600 4=710 5=1200 BASE: EQU 100H ; Start of CP/M normal program area ; ; ; =========== ; Jump table: ; =========== ; ; The jump table must be in exactly the same sequence as the one in MB-KMD. ; Note the ORG of 103H - This jump table has no jump to 'BEGIN'. ; ORG BASE+3 ; Start after 'JMP BEGIN' ; CONOUT: JMP 00000H ; Must be 0E738H if used, see below PMINIT: JMP MINIT ; Initialization routine (If needed) PUNINIT: JMP UNINIT ; Undo whatever 'MINIT' did (or return) PSENDR: JMP SENDR ; Send character (via POP PSW) PCAROK: JMP CAROK ; Test for carrier PMDIN: JMP MDIN ; Receive data byte PGETCHR: JMP GETCHR ; Get character from modem PRCVRDY: JMP RCVRDY ; Check receive ready PSNDRDY: JMP SNDRDY ; Check send ready PSPEED: JMP SPEED ; Get speed value for file transfer time PEXTRA1: JMP EXTRA1 ; Extra for custom routine PEXTRA2: JMP EXTRA2 ; Extra for custom routine PEXTRA3: JMP EXTRA3 ; Extra for custom routine ; ; ; ================================================================ ; To Display the Record Count on the CRT During Program Transfers: ; ================================================================ ; ; This one addition requires some work on the part of the user. When ; "BYE" is added, CP/M is normally moved lower to accomodate the new ; program above CP/M. Whenever BYE is called to enable the RCPM capability, ; it steals some of the addresses contained in the BIOS jump vector table. ; In order to display on the CRT during program transfers you need to get ; into the BIOS console output routine directly, else what is being ; displayed also tries to go out the modem. This is a big NO-NO at that ; time. (This cannot be done automatically by MB-KMD, since BYE has ; already taken the address we need to find, by the time MB-KMD is auto- ; matically activated by the remote station.) ; ; So, with the disk containing BYE, but prior to activating BYE, do ; this: ; 1) Cold reboot to move CP/M (and BIOS) to the new area needed ; when BYE is activated on the same disk. ; 2) Use DDT and dump the area from 0000H to 0002H. This gives ; the warm reboot address in BIOS. ; 3) Add 9 Bytes to that address to get your console output jump ; vector. ; 4) Pick off the address contained in the jump vector and install ; that in "CONOUT", below. Example of one system in use: ; ; FIRST, COLD REBOOT WITH DISK CONTAINING "BYE" ; ; 0000 C3 03 E0 (location of warm reboot on disk with BYE ; ; PRIOR TO ACTIVATING BYE BUT ON SAME DISK ; ; E003 C3 E9 E0 (BIOS warm reboot jump vector on this disk) ; E006 C3 00 E9 (BIOS get console status routine) ; E009 C3 B7 E1 (BIOS console input routine) ; E00C C3 D4 E1 (BIOS console output routine) ; ; The address we need is thus E1D4. Put that below, in ; our example it would be: CONOUT JMP 0E1D4H ; ; ;CONOUT: JMP 00000H ; If you wish to show the record count ; ; during program transfer, fill in this ; ; address at 'CONOUT' above. ; ; - Irv Hoff ; ; ; ============== ; MINIT: LXI B,PEND-START+1 ; Number of bytes to move LXI H,DEST+PEND-START+1 ; End of moved code LXI D,SOURCE+PEND-START ; End of source code ; MVLP: LDAX D ; Get byte DCX H ; Bump pointers MOV M,A ; New home DCX D DCX B ; Bump byte count MOV A,B ; Check if zero ORA C JNZ MVLP ; If not, do some more RET ; ; ; ============== ; UNINIT: RET ; No 'UN-INITIALIZE' routine ; ; ;=============== ; SOURCE: EQU $ ; Boundary memory amount OFFSET: EQU DEST-SOURCE ; Relocation amount START: EQU $+OFFSET ; ; ; ========================================= ; --> CAROK - check for presence of carrier ; ========================================= ; ; RET with Z = carrier on ; CAROK: EQU $+OFFSET ; ; The following code should be activated and TESTED if the MODEM port is ; used since that port is supposed to be able to report carrier detect. ; ; DI ; Disable interrupts ; OUT 0 ; Switch to shadow in memory ; LDA MODCTLP ; Get status ; OUT 1 ; Switch back to normal memory ; EI ; Enable interrupts ; ANI MODDCDB ; Get carrier detect bit ; CPI MODDCDA ; Test bit ; ; The following code is a fudge to allow the routine to pass the Zero ; flag clear value back to the caller until the carrier lead can be read. ; XRA A ; Clear accumulator to zeros CPI 0 ; Clear the zero flag RET ; ; ; ============== ; EXTRA1: EQU $+OFFSET EXTRA2: EQU $+OFFSET EXTRA3: EQU $+OFFSET RET ; For later use ; ; ; ========================================== ; --> GETCHR - get a character, same as MDIN ; --> MDIN - get a character, same as GETCHR ; ========================================== ; GETCHR: EQU $+OFFSET MDIN: EQU $+OFFSET DI ; Disable interrupts OUT 0 ; Switch to shadow memory LDA MODDATP ; Send a data byte OUT 1 ; Switch back to normal memory EI ; Enable interrupts RET ; ; ; ================================ ; --> RCVRDY - check receive ready ; ================================ ; ; RET with Z = character available. Return with error code in A-reg. ; RCVRDY: EQU $+OFFSET DI ; Disable interrupts OUT 0 ; Switch to shadow memory LDA MODCTLP ; Get modem status OUT 1 ; Switch back to normal memory EI ; Enable interrupts PUSH B ; Save scratch register PUSH PSW ; Check error status ANI MODFRME+MODOVRE+MODPARE MOV B,A ; Save it for a moment POP PSW ANI MODRCVB ; Isolate ready bit CPI MODRCVR ; Test it MOV A,B ; Get the error code character back POP B RET ; ; ; ========================== ; --> SENDR - send character ; ========================== ; SENDR: EQU $+OFFSET POP PSW ; Get the character back DI ; Disable interrupts OUT 0 ; Switch to shadow memory STA MODDATP ; Send a data byte OUT 1 ; Switch back to normal memory EI ; Enable interrupts RET ; ; ; =================================== ; --> SNDRDY - check if ready to send ; =================================== ; SNDRDY: EQU $+OFFSET DI ; Disable interrupts OUT 0 ; Switch to shadow memory LDA MODCTLP ; Get status byte OUT 1 ; Switch back to normal memory EI ; Enable interrupts ANI MODSNDB ; Isolate ready bit CPI MODSNDR ; Ready to send? RET ; ; ; ==================================================== ; --> SPEED - sets the time shown for program transfer ; ==================================================== ; SPEED: EQU $+OFFSET IF LSPEED LDA MSPEED ; Get index for baud rate from 'BYE' ENDIF ; IF NOT LSPEED MVI A,XSPEED ; Get index to baud rate from 'XSPEED' ENDIF ; RET ; ; ; ============== ; PEND: EQU $+OFFSET ; End of relocated code ; ; ============== ; ; END