home *** CD-ROM | disk | FTP | other *** search
- ; BRKP-1.INC - Kaypro Z80-SIO insert for BYERSX - 85/12/06
- ;
- ; name this file RSXIO.INC for automatic inclusion in RSXMAST. If
- ; your assembler cannot handle inclusion you will have to manually
- ; concatenate the various files, starting with RSXMAST.MAC.
- ;
- ; CAUTION - version for 1983 version Kaypros only. See the
- ; "dskstp" and "dskrun" procedures and the kp83 & kp84
- ; equates. Various versions use different ports/bits.
- ;
- ; Has an anomalous connection to "DODELAY" in the main system,
- ; which must delay (de) millisecs, preserving bc and hl. The RSX
- ; call cannot be used, because these routines may be called via
- ; the RSX mechanism, and would then over-write the switched stack.
- ;
- ; This version adapts any Kaypro computer to BYERSX. It may be used
- ; with any auto-answer modem such as the Hayes Smartmodem 300 or
- ; 1200, the Cermetek Infomate 212A, etc.
- ;
- ; With the USR Password (1200 baud), set all switches to OFF.
- ;
- ; Note: This is an insert, not an overlay.
- ;
- ; ------------------------------------------------------------------
- ;
- ; 85/11/06 Created for BYERSX. The similarity to BYE inserts
- ; is not accidental. - C.B. Falconer
- ;
- ; ------------------------------------------------------------------
- ;
- ; Set both the following to NO for a universal version.
- kp83 equ yes
- kp84 equ no; No more than one set YES
- ;
- havetim equ yes; No for no timer, yes for custom code
- ; If yes, check code for your system
- ;
- if kp83
- bitport equ 01ch
- video equ 03000h; Bank 1, location of screen memory
- endif
- if kp84
- bitport equ 014h
- endif
- mtrbit equ 040h; disk motor on/off. Inverted for 84
- ;
- ; Set base port for ZSIO & 8116 chips
- basep equ 04H; Port for SIO
- basec equ 00H; Port for 8116 baudrate generator
- ;
- ; The following define the port addresses to use.
- datport equ basep; Data port
- stport equ basep+2; Status/Control port
- bport equ basec; Baud rate port
- ;
- ; The following are baud rates for BPORT.
- bd110 equ 02h; 110 baud
- bd300 equ 05h; 300 baud
- bd450 equ 0ffh; not available
- bd600 equ 06h; 600 baud
- bd710 equ 0ffh; not available
- bd1200 equ 07h; 1200 baud
- bd2400 equ 0ah; 2400 baud
- bd4800 equ 0ch; 4800 baud
- bd9600 equ 0eh; 9600 baud
- bd19200 equ 0fh; 19200 baud
- ;
- ;
- ; ----------- (partial) ZILOG SIO chip definition -------------
- ;
- ; write-register bits
- ;
- ; For WR0: (lo 3 bits are next register address)
- noop equ 0;
- ; mask 038h
- rsints equ 10h; reset external/status interrupts
- chreset equ 18h; channel reset
- erreset equ 30h; error reset
- ;
- ; For WR1:
- ; mask 018h
- rxintdis equ 0; rx int disable
- ;
- ; For WR2: value is interrupt vector. Channel B only
- ;
- ; FOR WR3:
- ; mask 0c0h. Receive bits per char
- rx5bit equ 0
- rx6bit equ 80h
- rx7bit equ 40h
- rx8bit equ 0c0h
- rxmask equ 0c0h
- ; individual bits
- rxenbl equ 1; rx enable
- ;
- ; For WR4
- ; mask 0c0h. Internal clock divider
- clkx1 equ 0
- clkx16 equ 40h
- clkx32 equ 80h
- clkx64 equ 0c0h
- ; mask 0ch
- syncenbl equ 0; sync modes enable, else async
- stops1 equ 4; 1 stop bit
- stops15 equ 8; 1.5 stop bits
- stops2 equ 0ch; 2 stop bits
- stopmsk equ 0ch
- ; mask 3. Parity. Values 0, 1, 3 useful only
- pareven equ 2
- parodd equ 0
- parenbl equ 1
- paroff equ 0
- parmask equ 3
- ;
- ; For WR5:
- dtr equ 80h; data terminal ready output
- ; mask 060h. Transmit bits/char
- tx5bit equ 0; 5 bits (or less)
- tx6bit equ 40h
- tx7bit equ 20h
- tx8bit equ 60h
- txmask equ 060h
- ; Individual bits
- sndbrk equ 10h; send break
- txenbl equ 8; tx enable
- rts equ 2; request to send output
- ;
- ; -------------------------------------
- ; Read register bits
- ;
- ; For RR0
- drdy equ 1; receive data ready
- ordy equ 4; output buffer empty
- dcd equ 8; state of dcd/ input pin
- cts equ 20h; state of cts/ input pin
- brkrcvd equ 80h; break detected, async. abort for sync
- ;
- ; For RR1
- allsent equ 1; All xmit buffers empty.
- parityx equ 10h; Receive parity error. Latched till erreset
- rcvovrn equ 20h; Rcv overrun. Latched till erreset
- framerr equ 40h; Framing (asyn) CRC (sync) error. not latched
- ;
- ; For RR2
- ; holds interrupt vector (from WR2), possibly modified if
- ; "status affects vector" set. (WR1 statvec bit)
- ;
- ; ------------------------------------------------------------------
- ;
- ; Do a complete reset of the ZSIO.
- ; Hang up in case carrier present. Then assert DTR.
- ; return 0ffh for success, 0 for failure (with flags)
- ; a,f
- mdinit: call mdgo; reinit port, synchronize
- call mdstop; drop dtr, line, hangup
- push d
- lxi d,2000
- call dodelay; Can't use RSX call, stack re-entrancy
- pop d
- ; " "
- ; enable the modem. Set stop bits, parity, word length
- ; Zsio/Kaypro II/4/20/2x initialization
- ; a,f
- mdgo: push h
- push b
- lxi h,tbl1; init the SIO chip
- mov b,m; count of items
- inx h
- mov c,m; port id
- inx h
- db 0edh,0b3h; outir/otir ** Z80 code ** <<
- pop b
- pop h
- ori 0ffh; signal success
- ret
- ;
- ; This table sets the default configuration.
- ; It is modified by the SETBAUD command (wd lgh, stops, parity)
- tbl1: db tbl1lgh,stport
- db noop; force ctl reg access
- db chreset; throw out of mode
- db 1,rxintdis; disable all interrupts
- wr3: db 3,rx8bit + rxenbl; reg 3, enable receive
- wr4: db 4,clkx16+stops1; reg 4, set ascii params
- wr5: db 5,dtr+tx8bit+txenbl+rts; reg 5, enable send,dtr,rts
- tbl1lgh equ $-tbl1-2
- ;
- ; Deinitialize the Modem and hang up the phone by dropping DTR and
- ; leaving it inactive. This disables any interrupt systems.
- ; a,f (allowed)
- mdquit:
- ; " "
- ; Drop DTR to the modem to force hangup.
- ; a,f (allowed)
- mdstop: mvi a,5
- out stport
- lda wr5+1; get present configuration
- ani (NOT dtr) AND (NOT rts)
- out stport
- ret
- ;
- ; The following routine checks to make sure we still have carrier.
- ; If there is no carrier, it will return with the Zero flag set.
- ; a,f
- mdcarck:
- mvi a,rsints; Reset status
- out stport
- in stport; Get status
- ani dcd; Check for data carrier
- rz
- ori 0ffh
- ret
- ;
- ; The following is a routine that will input one character from the
- ; modem port. If there is nothing there, it will return garbage...
- ; so use the MDINST routine first. Do not strip parity for BYERSX
- ; a,f
- mdinp: in datport; Get character
- ret
- ;
- ; The following routine determines if there is a character waiting
- ; to be received. If no character is waiting the Zero flag will be
- ; set, else 0FFH will be returned in register 'A'.
- ; a,f
- mdinst: in stport; Get status
- ani drdy; Got a character?
- rz; Return if none
- ori 0ffh; Otherwise, set the proper flag
- ret
- ;
- ; The following is a routine that will output one character
- ; in register 'A' to the modem.
- ; ** Use MDOUTST first to see if buffer is empty **
- ; f (allowed)
- mdoutp: out datport; Send it
- ret
- ;
- ; The following is a routine to determine if the transmit buffer is
- ; empty. If empty, it will return with the Zero flag clear. If the
- ; transmitter is busy, it will return with the Zero flag set.
- ; a,f
- mdoutst:
- in stport
- ani ordy; Mask it
- rz
- ori 0ffh; Set all bits
- ret
- ;
- ; Send a break (a) millisec long. Return nz and 0ffh.
- ; Don't drop DTR. We want to keep the connection up.
- ; If not capable, return 0 and z flag
- ; a,f
- sendbk: push d
- push psw
- mvi a,5
- out stport
- lda wr5+1; get present configuration
- ori sndbrk
- out stport
- pop d; orig (a) to d
- mov e,d
- mvi d,0
- call dodelay
- pop d; restore entry
- jmp mdgo; end break and signal success
- ;
- ; Generalized baud setting per (a).
- ; Input 0 for no action
- ; 0 and zero flag if good, else 0ffh and nz flag.
- ; a,f
- setbaud:
- push psw
- call setparity; uses hi order bits
- pop psw
- ani 0fh; baud field
- rz; 0, ignore
- cpi 11
- jnc badbd; invalid request
- push h
- lxi h,bdtbl-1; for 1 based value
- add l
- mov l,a
- adc h
- sub l
- mov h,a
- mov a,m
- pop h
- inr a
- jz badbd; baud rate not available
- dcr a
- out bport; Send the byte
- xra a; Say rate is OK
- ret
- badbd: ori 0ffh; with error signal
- ret
- ;
- ; Table of bit patterns for baud rates. Not visible externally
- bdtbl: db bd110, bd300, bd450, bd600, bd710
- db bd1200, bd2400, bd4800, bd9600, bd19200
- ;
- ; set parity on bit weights 20,10h of (a).
- ; values: 10h = no parity, 20h=odd, 30h = even parity
- ; set stop bits on bit weights 80h,40h
- ; values: 40h = 1 stop, 80h = 1.5 stops, 0c0h = 2 stops
- ; zero fields for no change.
- ; a,f
- setparity:
- push b
- push d
- push h
- mov e,a; save configuration
- ani 030h
- jz sp2; no parity changes
- mvi d,paroff
- lxi b,256*tx8bit + rx8bit; 8 bits for no parity
- cpi 20h
- jc sp1; parity is turned off
- mvi d,pareven + parenbl
- lxi b,256*tx7bit + rx7bit; 7 bits for parity
- cpi 30h
- jz sp1; even parity
- mvi d,parodd + parenbl
- sp1: lxi h,wr3+1; b holds new txbits, c new rxbits,
- mov a,m; d new parity bits
- ani NOT rxmask
- ora c
- mov m,a; set receive wd length
- lxi h,wr5+1
- mov a,m
- ani NOT txmask
- ora b
- mov m,a; set transmit wd length
- lxi h,wr4+1
- mov a,m
- ani NOT parmask
- ora d
- mov m,a; set parity
- sp2: mov a,e
- ani 0c0h
- jz sp4; no stop bit changes
- mvi b,stops1
- cpi 010h
- jz sp3; 1 stop bit
- mvi b,stops15
- cpi 020h
- jz sp3; 1.5 stop bits
- mvi b,stops2; else 2 stop bits
- sp3: lxi h,wr4+1; b holds new stop configuration
- mov a,m
- ani NOT stopmsk
- ora b
- mov m,a; set stop bits
- sp4: pop h
- pop d
- pop b
- jmp mdgo; make the physical changes
- ;
- ; For non-intelligent modems. Go off hook and connect.
- ; a,f
- mdansw: xra a; This insert can't do this
- ret
- ;
- ; For non intelligent modems. Is the phone ringing
- ; 0 and z flag if not, 0ffh and nz flag if ringing
- ; a,f
- mdring: xra a; not ringing to this insert
- ret
- ;
- ; For disk control, the following indicates that the application
- ; will not require disk access in the immediate future. If possible
- ; drive motors should be stopped. No harm if unable to perform
- ; **** CHANGE THIS FOR non 1983 version Kaypros ****
- ; a,f
- dskstp: if kp83 OR kp84
- in bitport
- if kp83
- ori mtrbit; Kills 'em dead
- else; 1984 version
- ani NOT mtrbit
- endif
- out bitport
- endif; kp83 or kp84
- ret
- ;
- ; For disk control, the following indicates that the application
- ; will require disk access in the immediate future. If possible
- ; drive motors should be started. No harm if unable to perform.
- ; **** CHANGE THIS FOR non 1983 version Kaypros ****
- ; a,f
- dskrun: if kp83 OR kp84
- in bitport
- ani mtrbit
- if kp83
- rz; already running
- else; 1984 version
- rnz; already running
- endif; 1984 ver.
- in bitport; startem
- if kp83
- ani NOT mtrbit
- else; 1984 ver
- ori mtrbit
- endif; 1984 ver
- out bitport
- push d
- lxi d,400; millisecs = 0.4 sec.
- call dodelay; allow to come up to speed
- pop d; Standard Kaypro is 500ms, but this
- endif; kp83 or kp84
- ret; is used as an anticipator.
- ;
- ; ----------------------- Timer interface --------------------------
- ;
- ; ---- CUSTOMIZE TO YOUR INSTALLATION ---
- ;
- if havetim; System peculiar
- year equ 03bh
- month equ year+1
- day equ month+1
- hour equ day+1
- minute equ hour+1
- endif; where I keep them
- ;
- ; This is used only where the host system has no real-time clock.
- ; This allows simulation of that clock, with lousy accuracy.
- ; Adds 1 minute to the internally stored time value
- ; a,f,h,l (allowed)
- add1min:
- if havetim; the faked Kaypro system
- lxi h,minute
- add1m1: mov a,m
- inr a
- mov m,a
- sui 60; this rolls hours at 60 !!!
- rnz
- mov m,a
- dcx h
- jmp add1m1
- else; the simplest system, none
- ret
- endif
- ;
- ; These two routines are called with either
- ; de = 0ffffh for a query (return current value in hl) )
- ; de = other to set the appropriate value, and return in (hl)
- ; The returned value should be 0ffffh if no timer system installed.
- ; A zero value for date should also indicate no timer system (this
- ; is the default value when the RSX is not running).
- ;
- ; The date is kept in the following format (note 0ffffh is invalid)
- ; MSbit yyyyyyy mmmm ddddd LSbit
- ; with y field (0..127) the offset from 1980 (dates to 2107)
- ; m field (1..12) the numerical month (Jan to Dec)
- ; d field (1..31) the day of month
- ; (Identical to MSDOS format)
- ; a,f,h,l
- sgdate: lxi h,0ffffh; default not implemented
- if havetim
- mov a,d
- ana e
- inr a
- jz gmdate; enquiry
- ; " "
- ; Set MSDOS format date (from de), return in hl
- ; yyyyyyy m mmm ddddd
- ; a,f,h,l
- smdate: mov a,d
- rar
- ani 07fh
- adi 80
- sta year
- mov a,e
- ani 01fh
- sta day
- mov a,d
- rar; bit to cy
- mov a,e
- ral
- ral
- ral
- ral
- ani 0fh
- sta month
- ; " "
- ; convert to MSDOS date format in hl.
- ; a,f,h,l
- gmdate: lda year; My hardware leaves 0 or 0ffh
- inr a; on power on, until set.
- rz; not set
- dcr a
- rz; not set
- sui 80; MSDOS year 0 is 1980
- ani 07fh; max 127
- mov l,a
- lda month
- ani 0fh
- call put4b
- lda day
- ani 31; max value
- jmp put5b
- else
- ret
- endif
- ;
- ; The time is kept in the following format (note 0ffffh is invalid)
- ; MSbit hhhhh mmmmmm sssss LS bit
- ; with h field (0..23) hour of day (0 is midnight)
- ; m field (0..59) minute of hour
- ; s field (0..29) seconds DIV 2 (resolution 2 seconds)
- ; (Identical to MSDOS format)
- ; a,f,h,l
- sgtime: lxi h,0ffffh; Not implemented
- if havetim
- mov a,d
- ana e
- inr a
- jz gmtime; -1, get timer
- ; " "
- ; Store MSDOS format time from de, return in hl
- ; hhhhh mmm mmm sssss
- ; a,f
- smtime: mov a,d
- rrc
- rrc
- rrc
- ani 01fh
- sta hour
- mov a,d
- ral
- ral
- ral
- ani 038h
- mov h,a
- mov a,e
- rlc
- rlc
- rlc
- ani 07h
- ora h
- sta minute
- ; " "
- ; convert to MSDOS format time in hl.
- ; a,f,h,l
- gmtime: lda minute; Any ff indicates not set
- inr a; in my hardware
- rz; not set
- lda hour
- inr a
- rz; not set
- dcr a
- ani 01fh
- mov l,a
- lda minute
- ani 03fh
- dad h; make put5 into put6
- call put5b
- xra a; seconds value 0
- ; " "
- ; inject (a) premasked as rh 5 bits of hl, shifting hl left
- ; a,f,h,l
- put5b: dad h
- ; " "
- ; inject (a) premasked as rh 4 bits of hl, shifting hl left
- ; a,f,h,l
- put4b: dad h
- dad h
- dad h
- dad h
- ora l
- mov l,a
- endif
- ret
- ;
- ; ------------ I/O Dependant Function Key actions -------------
- ;
- ; Function key 0, used to print screen
- ; a,f,h,l
- f0k: if kp83
- ;
- ; IF NOT lstbusy THEN
- ; FOR line := 0 TO 23 DO BEGIN
- ; i := 79;
- ; WHILE i > 0 AND line[i] = ' ' DO i := i - 1;
- ; FOR j := 0 TO i DO write(lst, line[i]);
- ; writeln(lst); END;
- ;
- ; Print screen to lister
- ; a,f,h,l
- push d
- push b
- call @lstat; Kaypro only flag is trustworthy
- jz f0k7; ignore if off line/busy
- lxi h,video-128
- mvi b,24; lines to scan
- ; " "
- ; b is lines still to scan, hl is start of prev. line
- f0k1: lxi d,128; memory per line
- dad d
- push h; save line start
- lxi d,79; e := 79, rh column
- dad d; point to line end
- ; " "
- ; Scan off trailing blanks
- f0k2: call getch
- dcx h
- mov a,c
- ani 07fh; remove any flash attribute
- cpi ' '
- jnz f0k3; non blank found, e is char count
- dcr e
- jp f0k2
- inr e; put a single blank for empty line
- ; " "
- ; e is chars for this line, TOS is line start
- f0k3: pop h
- push h; restore line start
- ; " "
- ; output next character
- f0k4: call getch; output next character
- mov a,c
- ani 07fh; remove any flash attribute
- mov c,a
- cpi 07fh
- jz f0k5; rub to space
- cpi ' '
- jnc f0k6; printing char
- f0k5: mvi c,' '; convert funnys to blanks
- f0k6: call lputch; absorb funny graphics
- inx h
- dcr e
- jp f0k4
- mvi c,cr
- call lputch
- mvi c,lf
- call lputch
- pop h
- dcr b
- jnz f0k1
- f0k7: pop b
- pop d
- xra a
- ret
- ;
- lputch: push h; char to lister, save regs
- push d
- push b
- call @lout; get rid of the rub here
- pop b
- pop d
- pop h
- ret
- ;
- ; Access video location (hl)^
- ; This must execute above the bank1 storage area
- ; a,f,c
- getch: in bitport
- ori 080h
- di
- out bitport
- mov c,m
- ani 07fh
- out bitport
- ei
- ret
- endif; otherwise f0k falls thru to "ret" below
- ;
- ; The following are called when the ATTN char is followed by one
- ; of the digits '0' thru '9'. It is suggested that the digit '0'
- ; be reserved for performing screen dumps. A simple "ret"
- ; eliminates any key from the function repetoire.
- ; a,f,h,l (allowed)
- f1k:
- f2k:
- f3k:
- f4k:
- f5k:
- f6k:
- f7k:
- f8k:
- f9k: ret; eliminate all these
- ;
- .savelc:
- ;
- ; Following special mechanism for SLRMAC assembler. For others omit
- ; and patch the initialization area
- org imsg; defined in rsxinit module.
- db ' installing on Kaypro 2/4'
- if kp83
- db ' (83'
- endif
- if kp84
- db '/10 (84'
- endif
- db ' version)$'
- org .savelc; restore lcn ctr.
- ;
- ; end of insert
- ; ------------------------------------------------------------------
- ;
- ≡╔