; B5AN-1.ASM - Apple // with PCPI Applicard and MTN CPS Serial Card ; ; 2651 with internal baudrate generator ; ; This insert version is for the Apple ][+ with the Mountain Computer ; CPS Serial Interface Card and PCPI Applicard. Additional routines ; are included to support the TIME routines in BYE5nn. ; ; Thanks to Norman Beeler for previous versions of this insert. ; ;----------------------------------------------------------------------- ; ; 12/23/85 Written for BYE5 - H. Middlebrook ; ;----------------------------------------------------------------------- ; ; BYE5xx Insert Information ; ; The following information regarding BYE5xx inserts is included for ; reference purposes and may be removed and saved in a separate file. ; ; HARDWARE (Serial I/O) -- ; ; BYE5 program calls a number of hardware routines, listed below: ; ; MODEM Specific -- ; ; If IMODEM is set true in BYE5nn, then MDINIT and MDQUIT routines ; should should call IMxxxx routines in BYE5xx core program. ; ; USEFUL BYE ROUTINES -- ; ; DELAY: 100 msec delay routine (uses BC and A registers) ; KDELAY: 1 msec delay routine (uses BC and A registers) ; ; ROUTINES called from BYE core program code -- ; ; ** Routines may use A register but must preserve all others ; (if used). Flags must be set as indicated for status ; routines. ; ; MDCARCK Carrier check. ; Flags: Set Zero if No Carrier is present ; ; MDQUIT Leaving BYE...reset modem. Called when SYSOP types ; Ctrl-C. If IMODEM is TRUE then call IMQUIT and ; fall through to MDSTOP; else just fall through to ; MDSTOP. ; ; MDSTOP Drop DTR permanently. ; Disable DTR...MDINIT and SETnnnn will re-enable DTR. ; ; MDINIT Initialize modem (serial I/O). ; For CPS card, drop then raise DTR, set PSW = 8N1, ; and set baud to current HSnnnn. If IMODEM is TRUE, ; then CALL IMINIT after initializing CPS card. ; ; MDINP Receive character from serial (modem) interface. ; Regs: A = Character received ; ; MDOUTP Send character to serial (modem) interface. ; Regs: A = Character to send to modem ; ; MDOUTST Output status of serial (modem) interface. ; Flags: Set Zero if I/O not ready for character ; ; MDINST Input status of serial (modem) interface. ; Flags: Set Zero if I/O does not have character ; Regs: A = 00H if I/O does not have character ; This routine requires that both A = 00H and zero ; set if a character is not available. Your routine ; should clear zero and return with A = 0FFH if ; character is available. ; ; MDCRDL Carrier check with 2 second delay. Returns with ; carrier status ON or BEFORE about a 2 second delay. ; This routine may be required for modems which are ; slow in returning carrier status after ATA command. ; Replace the following code in BYE502: ; ; Was -- FINISH: CALL MDCARCK ; ; Now -- FINISH: CALL MDCRDL ; ; SETnnnn Set serial I/O to specified baud rate. Only one ; routine is called depending on HSnnnn EQUATE in ; BYE core. Should init CPS card to PSW=8N1 and ; Baud = nnnn. ; ; ;----------------------------------------------------------------------- ; ; CPS Serial Interface Routines ; SLOT EQU 2 ; CPS card slot number ; ; ; CPS Serial Port and Register Equates ; DATREG EQU 0C0FAH + SLOT * 100H ;Serial Data Register STAREG EQU 0C0FBH + SLOT * 100H ;Serial Status Register SCRCTL EQU 0C0FEH + SLOT * 100H ;CPS Serial Ctl Register CLKREG EQU 0C0F9H + SLOT * 100H ;CPS Clock Data Register ; RDBYTEAPPL EQU 0FFE0H ;Read byte from Apple WRBYTEAPPL EQU 0FFE3H ;Write byte to Apple RDWORD EQU 0FFE6H ;Read 2 bytes (DE = Bytes) WRWORD EQU 0FFE9H ;Write 2 bytes (DE = Bytes) ; PEEK1BYTE EQU 6 ;Command to Peek 1 byte to Apple POKE1BYTE EQU 7 ;Command to Poke 1 byte to Apple ; ; ; The following routines communicate with hardware in Apple Slots ; directly from Applicard. ; ; Read the UART Status Register ; RD$STAREG: PUSH D LXI D,STAREG CALL PEEK POP D RET ;..... ; ; ; Write to the UART Status Register ; WR$STAREG: PUSH D LXI D,STAREG CALL POKE POP D RET ;..... ; ; ; Write to the UART Command Port ; WR$SCRCTL: PUSH D LXI D,SCRCTL CALL POKE POP D RET ;..... ; ; ; Read the UART Data Register ; RD$DATREG: PUSH D LXI D,DATREG CALL PEEK POP D RET ;..... ; ; ; Write to the UART Data Register ; WR$DATREG: PUSH D LXI D,DATREG CALL POKE POP D RET ;..... ; ; ; Read a byte from CPS clock register ; RD$CLKDATA: PUSH D LXI D,CLKREG ; Select clock data CALL PEEK POP D RET ;..... ; ; ; PEEK at 1 byte in Apple address space ; ENTRY DE = Address in 6502 RAM/ROM ; EXIT A = Data from 6502 ; PEEK: PUSH B MVI C,PEEK1BYTE CALL WRBYTEAPPL CALL WRWORD CALL RDBYTEAPPL POP B RET ;..... ; ; ; POKE 1 byte to Apple address space ; ENTRY DE = Address in 6502 RAM/ROM ; EXIT A = data to 6502 ; POKE: PUSH B MOV B,A MVI C,POKE1BYTE CALL WRBYTEAPPL CALL WRWORD MOV C,B CALL WRBYTEAPPL POP B RET ;..... ; ; ;---------------------------------------------------------------------- ; ; This routine intializes Serial Port of CPS card and (optionally) ; initializes ASCII commanded modem. NOTE: PSW and BAUD must be set ; by two sequential writes to DATREG with SCRCTL access open. ; MDINIT: MVI A,80H CALL WR$SCRCTL MVI A,15H ; Drop DTR and reset serial I/O CALL WR$STAREG MVI B,20 ; MDDLOP: CALL DELAY ; 2 second delay DCR B JNZ MDDLOP MVI A,27H ; Now re-enable serial port CALL WR$STAREG MVI A,4EH ; Set PSW = 8N1 (1st DATREG write) CALL WR$DATREG MVI A,03AH ; Default to 2400 baud ; IF HS1200 MVI A,037H ENDIF ; HS1200 ; IF HS300 MVI A,035H ENDIF ; HS300 ; CALL WR$DATREG ; Set baud (2nd DATREG write) XRA A ; Close BAUD/PSW access CALL WR$SCRCTL ; IF IMODEM CALL IMINIT ; Initialize smartmodem ENDIF ; IMODEM ; RET ;..... ; ; ; This routine is called when BYE is to go off the air ; MDQUIT: IF IMODEM CALL IMQUIT ENDIF ; IMODEM ; ; ; This routine will shut everything down permanently. ; MDSTOP: MVI A,80H ; Enable UART command register CALL WR$SCRCTL MVI A,05H ; Disable DTR and RTS (UART Cmd Reg) CALL WR$STAREG XRA A ; Enable CPS status register CALL WR$SCRCTL CALL DELAY ; 100 msec delay RET ;..... ; ; ; The following is a routine to determine if there is a character wait- ; ing to be received. If none are there, the Zero flag will be set, ; otherwise, 255 will be returned in register A. ; MDINST: CALL RD$STAREG ; Read UART command register ANI 02H ; Mask everything but RxRDY, char ready? RZ ; No, then return ORI 0FFH ; Yes, be sure to set flag and A reg RET ;..... ; ; ; The following is a routine to determine if the transmit buffer is ; empty. If it is empty, it will return with the Zero flag clear. If ; the transmitter is busy, then it will return with the Zero flag set. ; ; MDOUTST:CALL RD$STAREG ; Read status register ANI 01H ; Mask everything but TxRDY and... RET ; Return with flags set ;..... ; ; ; The following is a routine that will check to make sure we still have ; carrier. If there is no carrier, it will return with the Zero flag ; set. There are two entry points to this section: the 1st MDCRDL delays ; for 2 seconds or until carrier is detected. The second is the normal ; entry for carrier check. ; MDCRDL: PUSH B MVI B,20 ; Set for 2 sec delay max ; MDCK2: CALL DELAY ; Wait 100 msecs CALL MDCARCK JNZ MDCK1 ; If carrier, then return DCR B JNZ MDCK2 ; If not 2 secs, then continue timing ; MDCK1: POP B ; When done fall thru to carrier check ; ; ; This is normal carrier check routine. ; MDCARCK:CALL RD$STAREG ; Read status register ANI 080H ; Use DSR bit instead of DTR bit RET ;..... ; ; ; The following is a routine that will input one character from the ; CPS UART register. ; MDINP: CALL RD$DATREG ; Get character RET ;..... ; ; ; The following is a routine that will output one character in register ; A to the CPS UART data register. ; MDOUTP: CALL WR$DATREG ; Send character to CPS UART RET ;..... ; ; ; The following routines set the CPS card to a specified baud rate. A ; common setup routine is jumped to after baud setup byte in local ; storage. ; SET300: MVI A,35H ; 300 baud setup byte STA MBSET JMP BPSET ; Jump to psw/baud set routine ; SET1200:MVI A,37H ; 1200 bps byte STA MBSET JMP BPSET ; SET2400:MVI A,3AH ; 2400 bps byte STA MBSET ; BPSET: MVI A,80H ; Open command register CALL WR$SCRCTL ; By storing 80H in SCRCTL MVI A,27H ; Initialize the serial chip CALL WR$STAREG ; By storing 27H in STAREG MVI A,4EH ; Set default format 8N1 CALL WR$DATREG LDA MBSET ; Get baud rate byte from local storage CALL WR$DATREG XRA A CALL WR$SCRCTL ; Close command port by storing 0 RET ;..... ; ; MBSET: DB 0 ; Storage for baud setup byte ;..... ; ; ;----------------------------------------------------------------------- ; ; WARNING: This section uses code in the PORT insert above. Use care ; care if altering it or if you change the code above. ; ; This TIME routine is adapted from TIME14.ASM (Nov 85 - HMM). The ; routine uses a burst read of time from CPS clock chip (OKI 5832). ; The raw data is stored in CLKBUF then assembled and placed into ; RTCBUF in BYE. ; ; Real-Time clock buffer is organized as HH:MM:SS YYYY/MM/DD ; ;RTCBUF:DB 99H,99H,99H ;HH:MM:SS (BCD 24hr) 00:00:00-23:59:59 ; DB 19H,84H,01H,31H ;YYYY/MM/DD (BCD ISO DATE) ; ; ; BYE5 save and restores registers before/after calling TIME. ; IF CLOCK OR RSPEED TIME: MVI A,040H ; Get byte to stop clock CALL WR$SCRCTL ; Send to CPS card LXI D,CLKBUF ; Put CLKBUF address in DE MVI B,0 ; Set clock index to 0 ; TMLOOP: MVI A,050H ; Get byte to read clock ORA B ; Add clock index to read (50H - 5CH) CALL WR$SCRCTL ; Send to CPS card CALL RD$CLKDATA ; Read clock (SEC1 --> YEAR10) ANI 0FH ; Mask garbage in high nibble STAX D ; Save value read in CLKBUF INX D ; Bump CLKBUF address value in DE INR B ; Bump clock index in BC MVI A,0DH ; Fetch table length + 1 CMP B ; Are we beyond end of table... JNZ TMLOOP ; No, then go back again XRA A ; Yes, then zero A reg to turn on clock CALL WR$SCRCTL ; ; ; Now move data from CLKBUF to RTCBUF. ; FIXRTC: LDA CLKBUF+1 ; Seconds ANI 7 MOV B,A LDA CLKBUF+0 CALL SHFTIT STA RTCBUF+2 LDA CLKBUF+3 ; Minutes ANI 7 MOV B,A LDA CLKBUF+2 CALL SHFTIT STA RTCBUF+1 LDA CLKBUF+5 ; Hours ANI 3 MOV B,A LDA CLKBUF+4 CALL SHFTIT STA RTCBUF+0 MVI A,19H ; Century STA RTCBUF+3 LDA CLKBUF+12 ; Year MOV B,A LDA CLKBUF+11 CALL SHFTIT STA RTCBUF+4 LDA CLKBUF+10 ; Month ANI 1 MOV B,A LDA CLKBUF+9 CALL SHFTIT STA RTCBUF+5 LDA CLKBUF+8 ; Day ANI 3 MOV B,A LDA CLKBUF+7 CALL SHFTIT STA RTCBUF+6 LDA RTCBUF ; Put current hour CALL BCDBIN STA CCHOUR ; And minute into CCHOUR LDA RTCBUF+1 CALL BCDBIN ; And CCMIN in Binary STA CCMIN RET ; To BYE ; SHFTIT: PUSH PSW ; Routine to put A & B registers MOV A,B ; Together (low order nibbles) RLC RLC ; Return with result in A. RLC RLC MOV B,A POP PSW ANI 0FH ORA B RET ;..... ; ; ; The CLKBUF is fixed, initialized area used to store time as ; read from CPS clock hardware. Must be DB 0 for proper relocation ; when using BYE. ; CLKBUF: DB 0 ; S1 DB 0 ; S10 DB 0 ; MIN1 DB 0 ; MIN10 DB 0 ; H1 DB 0 ; H10 DB 0 ; Day of Week (not used here in BYE) DB 0 ; D1 DB 0 ; D10 DB 0 ; MON1 DB 0 ; MON10 DB 0 ; Y1 DB 0 ; Y10 ENDIF ; CLOCK OR RSPEED ;..... ; ; end ;-----------------------------------------------------------------------