home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
mex
/
mxo-s511.asm
< prev
next >
Wrap
Assembly Source File
|
1994-07-13
|
17KB
|
657 lines
TITLE 'MEX overlay for SSM IO5 v1.0'
; MXO-S511.ASM -- SSM IO5 overlay for MEX 86/10/20
VERSION equ 11 ;version number
; NOTE 1: This overlay is designed for use with either MEXPLUS or MEX.
; Edit this file for your preferences, then follow the 'TO USE'
; example shown below.
;
; NOTE 2: The SSM IO-5 board supports two Intel 8251s plus 3 parallel ports.
; Extensive configuration options are supported by the many jumpers on
; this board, but only a few of them relate to software. These are
; supported by the SET command, as follows:
; SET BASE sets base port number of board
; SET PORT selects which serial port (A or B)
; SET DATA select position of data port (0 or 1); the
; status port will be at the other address
; Other SET commands supported:
; SET DIAL select pulse/touch dialing
; TO USE: First edit this file filling in answers for your own equipment,
; then assemble with ASM.COM or equivalent assembler. Finally,
; depending on the version of Mex, create an executable module:
;
; For MEX (v1.1x), use MLOAD (v2.3 or later) to overlay the base
; .COM file:
; A>MLOAD MEX.COM=MEX114.COM,[MXO-SMxx,]MXO-S5xx
; where MXO-SMxx is an optional modem overlay.
;
; For MEXPLUS (v1.2 or greater), use MLOAD to create an overlay
; file (.OVR), boot MEXPLUS, and use its builtin LOAD command to
; install the overlay:
; A>MLOAD MXO-MMxx.OVR=MXO-S5xx.HEX
; A>MEXPLUS
; [MEX] A0>>LOAD MXO-S5XX.OVR
;
; = = = = = = = = = = = = = = = = = =
;
; 86.10.20 - v1.1: fixed bad generation of port - Roger Burrows
; addresses if DEFPORT is 'B'
; 86.10.03 - v1.0: created first version - Roger Burrows
;
; = = = = = = = = = = = = = = = = =
YES equ 0FFH
NO equ 0
BELL equ 07H ;bell
TAB equ 09H ;tab
LF equ 0AH ;linefeed
CR equ 0DH ;carriage return
ESC equ 1BH ;escape
; Change the following information to match your equipment
DEFBASE equ 090H ;Default base address for IO5 board
DEFPORT equ 'A' ;Default serial port
DEFDATA equ 0 ;Default data port
; End of information to change
DEFSTAT equ 1-DEFDATA ;Default status port
DATA equ DEFBASE+(DEFPORT-'A')*2+DEFDATA ;8251 data port
STATUS equ DEFBASE+(DEFPORT-'A')*2+DEFSTAT ;8251 status port
RXRDY equ 02H ; Receiver Ready
MDRCVB equ RXRDY ; Bit to test for Receive
MDRCVR equ RXRDY ; & value when ready
TXEMPTY equ 04H ; Transmitter Empty
MDSNDB equ TXEMPTY ; Bit to test for Send
MDSNDR equ TXEMPTY ; & value when ready
COMMAND equ STATUS ;8251 command port
TXEN equ 01H ; Transmit Enable
DTR equ 02H ; Data Terminal Ready
RXEN equ 04H ; Receive Enable
SBRK equ 08H ; Send Break
ER equ 10H ; Error Reset
RTS equ 20H ; Request To Send
IR equ 40H ; Internal Reset
STDMODE equ 4EH ;Standard Mode Value (see 8251 spec):
; bits: 8 data, 1 stop, no parity
; baud rate factor = 16x
; MEX service processor
MEX equ 0D00h ;address of the service processor
INMDM equ 255 ;get char from port to A, CY=no more in 100 ms
TIMER equ 254 ;delay 100ms * reg B
TMDINP equ 253 ;B=# secs to wait for char, cy=no char
CHEKCC equ 252 ;check for ^C from KBD, Z=present
SNDRDY equ 251 ;test for modem-send ready
RCVRDY equ 250 ;test for modem-receive ready
SNDCHR equ 249 ;send a character to the modem (after sndrdy)
RCVCHR equ 248 ;recv a char from modem (after rcvrdy)
LOOKUP equ 247 ;table search: see CMDTBL comments for info
PARSFN equ 246 ;parse filename from input stream
BDPARS equ 245 ;parse baud-rate from input stream
SBLANK equ 244 ;scan input stream to next non-blank
EVALA equ 243 ;evaluate numeric from input stream
LKAHED equ 242 ;get nxt char w/o removing from input
GNC equ 241 ;get char from input, cy=1 if none
ILP equ 240 ;inline print
DECOUT equ 239 ;decimal output
PRBAUD equ 238 ;print baud rate
CONOUT equ 2 ;simulated BDOS function 2: console char out
PRINT equ 9 ;simulated BDOS function 9: print string
INBUF equ 10 ;input buffer, same structure as BDOS 10
org 100h ;we begin
ds 3 ;for the "JMP START" instruction
PMODEM: db NO ;yes=PMMI modem \ / These 2 locations are not
SMODEM: db NO ;yes=Smartmodem / \ referenced by MEX
TPULSE: db 'T' ;T=touch, P=pulse (referenced by MXO-SMxx)
CLOCK: db 40 ;clock speed x .1, up to 25.5 mhz.
MSPEED: db 5 ;sets display time for sending a file
;0=110 1=300 2=450 3=600 4=710
;5=1200 6=2400 7=4800 8=9600 9=19200
BYTDLY: db 5 ;default time to send character in
;terminal mode file transfer (0-9)
;0=0 delay, 1=10 ms, 5=50 ms, 9=90 ms
CRDLY: db 5 ;end-of-line delay after CRLF in terminal
;mode file transfer for slow BBS systems
;0=0 delay, 1=100 ms, 5=500 ms, 9=900 ms
COLUMS: db 5 ;number of directory columns
SETFL: db YES ;yes=user-defined SET command
SCRTST: db YES ;yes=if home cursor and clear screen
;routine at CLRSCRN
db 0 ;was once ACKNAK, now spare
BAKFLG: db NO ;yes=make .BAK file
CRCDFL: db YES ;yes=default to CRC checking
;no=default to Checksum checking
TOGCRC: db YES ;yes=allow toggling of Checksum to CRC
CVTBS: db NO ;yes=convert backspace to rub
TOGLBK: db YES ;yes=allow toggling of bksp to rub
ADDLF: db NO ;no=no LF after CR to send file in
;terminal mode (added by remote echo)
TOGLF: db YES ;yes=allow toggling of LF after CR
TRNLOG: db YES ;yes=allow transmission of logon
;write logon sequence at location LOGON
SAVCCP: db YES ;yes=do not overwrite CCP
LOCNXT: db NO ;yes=local cmd if EXTCHR precedes
;no=not local cmd if EXTCHR precedes
TOGLOC: db YES ;yes=allow toggling of LOCNXTCHR
LSTTST: db YES ;yes=allow toggling of printer on/off
;in terminal mode. Set to no if using
;the printer port for the modem
XOFTST: db NO ;yes=allow testing of XOFF from remote
;while sending a file in terminal mode
XONWT: db NO ;yes=wait for XON after sending CR while
;transmitting a file in terminal mode
TOGXOF: db YES ;yes=allow toggling of XOFF testing
IGNCTL: db NO ;yes=do not send control characters
;above CTL-M to CRT in terminal mode
;no=send any incoming CTL-char to CRT
EXTRA1: db 0 ;for future expansion
EXTRA2: db 0 ;for future expansion
BRKCHR: db '@'-40h ;^@ = Send a 300 ms. break tone
NOCONN: db 'N'-40h ;^N = Disconnect from phone line
LOGCHR: db 'L'-40h ;^L = Send logon
LSTCHR: db 'P'-40h ;^P = Toggle printer
UNSVCH: db 'R'-40h ;^R = Close input text buffer
TRNCHR: db 'T'-40h ;^T = Transmit file to remote
SAVCHR: db 'Y'-40h ;^Y = Open input text buffer
EXTCHR: db '^'-40h ;^^ = Send next character
ds 2 ;used for PMMI (not referenced by MEX)
INSTAT: ;in modem status port
ST1: in STATUS
ret
; We have 7 free bytes here, so let's use them (for modem stuff)
OUTCMD: ;mex doesn't know about this
ST2: out COMMAND
ret
; Default values for BASE, PORT, DATA
BASEVAL:db DEFBASE ;or this
PORTVAL:db DEFPORT
DATAVAL:db DEFDATA
db 0
OTDATA: ;out modem data port
DA1: out DATA
ret
db 0,0,0,0,0,0,0
INDATA: ;in modem data port
DA2: in DATA
ret
db 0,0,0,0,0,0,0
MASKR: ani MDRCVB ;bit to test for receive ready
ret
TESTR: cpi MDRCVR ;value of receive bit when ready
ret
MASKS: ani MDSNDB ;bit to test for send ready
ret
TESTS: cpi MDSNDR ;value of send bit when ready
ret
DCDTST: jmp DCDVEC ;data carrier detect (MEXPLUS)
RNGDET: jmp RNGVEC ;ring detect (MEXPLUS)
db 0,0,0,0,0 ;reserved
SMDISC: ds 3 ;smartmodem disconnect (MEXPLUS)
DIALV: ds 3 ;dial digit in A
DISCV: jmp PDISC ;disconnect modem (with DTR)
GOODBV: jmp GOODBY ;call just before exit to CP/M
INMODV: jmp INITMD ;called on entry from CP/M
NEWBDV: jmp DUMMY ;set new baud rate
NOPARV: jmp DUMMY ;set modem for no parity
PARITV: jmp DUMMY ;set modem for parity
SETUPV: jmp SETCMD ;process SET cmd
ds 3 ;reserved, not used by MEX
VERSNV: jmp SYSVER ;sign-on message from overlay
BREAKV: jmp PBREAK ;send a break
; Do not change the following six lines
; (jump vectors, not supported in MEX 2.0)
ds 3 ;replace with MEX function 9
ds 3 ;replace with MEX function 10
ds 3 ;replace with MEX function 247
ds 3 ;replace with MEX function 255
ds 3 ;not supported by MEX
ds 3 ;replace with MEX function 254
; Routines to clear screen & clear to end of screen. If using
; these routines, set SCRTST to YES at 010AH (above).
CLREOS: mvi c,PRINT
lxi d,TCLEOS
call MEX
ret
CLS: mvi c,PRINT
lxi d,TCLSCR
call MEX
ret
; End of fixed area ... from here to 1FFH is reserved (MEXPLUS)
org 200H
;.......... start of free-format user routines ..........
; Return data carrier detect status (MEXPLUS)
DCDVEC: mvi a,254 ;not supported - no DCD on 8251s
ret
; Return ring indicator status (MEXPLUS)
RNGVEC: mvi a,254 ;not supported - no RI on 8251s
ret
; Disconnect modem
PDISC: call INDATA ;clear any pending data
mvi A,TXEN+RXEN+ER+RTS ;turn off DTR
call OUTCMD ;clear DTR in command reg
mvi b,3 ;delay 300 milliseconds
mvi c,TIMER
call MEX
mvi a,TXEN+DTR+RXEN+ER+RTS ;set DTR to modem again
call OUTCMD
ret
; Exit to CP/M
GOODBY: call INDATA ;clear any pending data
xra a ;turn off everything (DTR, RTS etc)
call OUTCMD
ret
; Enter from CP/M (also called from FIXIO)
INITMD: mvi b,3 ;send 3 nulls
xra a ; to force to command state
INITLP: call OUTCMD
dcr b
jnz INITLP
mvi a,IR ;reset to mode level
call OUTCMD
mvi a,STDMODE ;set standard mode
call OUTCMD
mvi a,TXEN+DTR+RXEN+ER+RTS ;enable receive, transmit, DTR, RTS
call OUTCMD
ret
; Dummy routine
DUMMY: ret
; Issue signon message
SYSVER: mvi c,ILP
call MEX
db 'Version ',VERSION/10+'0','.',VERSION MOD 10+'0'
db ' for SSM IO5 board',CR,LF,0
mvi c,ILP
call MEX
db 'Base address ',0
lda BASEVAL ;print base port number
call PRTHEX
mvi c,ILP
call MEX
db ', serial port ',0
mvi c,CONOUT
lda PORTVAL ;print serial port (A or B)
mov e,a
call MEX
mvi c,ILP ;show data port as even or odd
call MEX
db ', data port is ',0
lda DATAVAL
lxi d,EVEN ;print even/odd
ora a ;is it even ?
jz SYSVR1 ;yes
lxi d,ODD ;else odd
SYSVR1: mvi c,PRINT
call MEX
mvi c,ILP
call MEX
db ', ',0
lda TPULSE
lxi d,PLSMSG ;print pulse/touch
cpi 'P' ;is it pulse ?
jz SYSVR2 ;yes
lxi d,TCHMSG ;else touch
SYSVR2: mvi c,PRINT
call MEX
mvi c,ILP
call MEX
db ' dialing',0
ret
; Send break to remote
PBREAK: mvi a,TXEN+DTR+RXEN+SBRK+ER+RTS ;set break
call OUTCMD
mvi b,3 ;delay 300 milliseconds
mvi c,TIMER
call MEX
mvi a,TXEN+DTR+RXEN+ER+RTS ;resuming normal service ...
call OUTCMD
ret
; Handle SET command
SETCMD: mvi c,SBLANK ;any arguments?
call MEX
jc STSHOW ;if not, go print out values
mvi c,LOOKUP
lxi d,CMDTBL ;parse command
call MEX
jc SETERR ;can't find it
pchl ;else go there
SETERR: mvi c,PRINT
lxi d,SETEMS ;print error
call MEX
ret
SETEMS: db 'SET command error',CR,LF,CR,LF,'$'
CMDTBL: db '?'+80h ; "set ?"
dw STHELP
db 'BAS','E'+80h ; "set base"
dw STBASE
db 'DAT','A'+80h ; "set data"
dw STDATA
db 'DIA','L'+80h ; "set dial"
dw STDIAL
db 'POR','T'+80h ; "set port"
dw STPORT
db 0
; SET <no-args>: print current statistics
STSHOW: lxi h,SHOTBL ;get table of SHOW subroutines
STSHLP: mov e,m ;get table address
inx h
mov d,m
inx h
mov a,d ;end of table?
ora e
rz ;exit if so
push h ;save table pointer
xchg ;adrs to HL
call GOHL ;do it
mvi c,CHEKCC ;check for console abort
call MEX
pop h ;it's done
jnz STSHLP ;continue if no abort
call CRLF
ret
GOHL: pchl
; table of SHOW subroutines
SHOTBL: dw SHOWBA
dw SHOWPO
dw SHOWDT
dw SHOWDL
dw 0
; SET ? processor
STHELP: mvi c,PRINT
lxi d,HLPMSG
call MEX
ret
; The help message
HLPMSG: db CR,LF,'SET command options:'
db CR,LF,' SET BASE <hex #> ... set new base port (00,10 ... F0)'
db CR,LF,' SET DATA <0|1> ... set data port address (0=even,1=odd)'
db CR,LF,' SET DIAL <P|T> ... set Pulse or Touch dialing'
db CR,LF,' SET PORT <A|B> ... set serial port id'
db CR,LF
CRLFMS: db CR,LF,'$'
; SET BASE command processor
STBASE: mvi c,SBLANK ;skip blanks
call MEX
jc SETERR ;nothing else
lxi h,0 ;use HL to build port #
STBAS1: push h ;save across MEX
mvi c,GNC ;get char from input, cy=1 if none
call MEX
pop h ;restore
jc STBAS2
call HEXCON ;convert to hex nybble in A
jc SETERR ;not hex
dad h ;shift L left by 4 bits
dad h
dad h
dad h
ora l ;or with new nybble
mov l,a ;back to L
mov a,h ;anything in H yet ?
ora a
jnz SETERR ;yes - too big
jmp STBAS1 ;else go round again
STBAS2: mov a,l ;reg L contains base port #
ani 0fh ;check boundary alignment
jnz SETERR ;no good
mov a,l ;ok - save for display
sta BASEVAL
call FIXIO ;fix up in/out with BASEVAL,PORTVAL,DATAVAL
SHOWBA: mvi c,ILP
call MEX
db 'Base address set to ',0
lda BASEVAL
call PRTHEX
call CRLF
ret
; SET DATA processor
STDATA: mvi c,SBLANK ;skip blanks
call MEX
jc SETERR ;nothing else
mvi c,EVALA ;get numeric from input
call MEX
mov a,h
ora a ;> 256 ?
jnz SETERR ;yes, error
mov a,l
cpi 2 ;check it
jnc SETERR ;invalid
sta DATAVAL ;store it
call FIXIO ;fix up in/out with BASEVAL,PORTVAL,DATAVAL
SHOWDT: mvi c,ILP
call MEX
db 'Data port set to ',0
lda DATAVAL ;get data setting
lxi d,EVEN ;assume even
ora a ;is it ?
jz SHOWT2 ;yes
lxi d,ODD ;else odd
SHOWT2: mvi c,PRINT
call MEX
call CRLF
ret
; SET DIAL processor
STDIAL: mvi c,SBLANK ;skip blanks
call MEX
jc SETERR ;nothing else
lxi d,DIALTB ;parse cmd
mvi c,LOOKUP
call MEX
jc SETERR
mov a,l ;get upper case character
sta TPULSE ;store it for MXO-SMxx
SHOWDL: mvi c,ILP ;display status
call MEX
db 'Dialing type set to ',0
lda TPULSE ;get pulse/touch setting
lxi d,PLSMSG ;assume pulse
cpi 'P' ;is it ?
jz SHOWD2 ;yes
lxi d,TCHMSG ;else touch
SHOWD2: mvi c,PRINT
call MEX
call CRLF
ret
; Dial table - saves us worrying about upper/lower case
DIALTB: db 'P'+80H ;pulse dial
db 'P',0
db 'T'+80H ;touch dial
db 'T',0
db 0
; SET PORT processor
STPORT: mvi c,SBLANK ;skip blanks
call MEX
jc SETERR ;nothing else
lxi d,PORTTB ;parse cmd
mvi c,LOOKUP
call MEX
jc SETERR
mov a,l ;get upper case character
sta PORTVAL ;a-ok, save it
call FIXIO ;fix up in/out with BASEVAL,PORTVAL,DATAVAL
SHOWPO: mvi c,ILP ;display status
call MEX
db 'Port set to ',0
mvi c,CONOUT
lda PORTVAL
mov e,a
call MEX ;display it
call CRLF
ret
; Port table - saves us worrying about upper/lower case
PORTTB: db 'A'+80H
db 'A',0
db 'B'+80H
db 'B',0
db 0
;.......... subroutines used by the above routines ..........
; Convert ascii char in A to hex nybble
HEXCON: cpi '0' ;< '0' ?
rc ;error - return with carry set
cpi '9'+1 ;<= '9' ?
jc HEXNUM ;yes - must be 0-9
cpi 'A' ;< 'A' ?
rc ;error
cpi 'F'+1 ;<= 'F' ?
jc HEXALF ;yes - convert to hex nybble
cpi 'a' ;< 'a' ?
rc ;error
cpi 'f'+1 ;<= 'f' ?
jnc HEXERR ;no - error
sui 'a'-'A' ;convert lower case a-f to upper
HEXALF: stc
adi 9 ;convert upper case A-F to 3ah-3fh
HEXNUM: ani 0fh ;clear high-order nybble
ret
HEXERR: stc
ret
; Print contents of A as hex, followed by 'h'
PRTHEX: push psw ;save A
rrc ;right justify one hex digit
rrc
rrc
rrc
call PRTNYB ;print first hex digit
pop psw
call PRTNYB ;print second hex digit
mvi c,CONOUT
mvi e,'h'
call MEX ;print trailing 'h'
ret
; Print hex nybble
PRTNYB: ani 0fh ;print one hex digit
adi 90h ;trust me, this works
daa
aci 40h
daa ;now ascii
mvi c,CONOUT ;print it
mov e,a
call MEX
ret
; Do cr, lf
CRLF: mvi c,PRINT
lxi d,CRLFMS
call MEX
ret
; Update in & out instructions with new BASEVAL, PORTVAL, DATAVAL
FIXIO: lda PORTVAL ;get port id
sui 'A' ; make it 0 or 1
add a ; then 0 or 2 (offset to 1st reg for A or B)
mov b,a ; in reg b
lda BASEVAL ;get base address
ora b
mov b,a ;b = address of even port
lda DATAVAL ;get data port offset
ora b ;a = address of data port
sta DA1+1
sta DA2+1
xri 01h ;now a = address of status port
sta ST1+1
sta ST2+1
jmp INITMD ;go reinitialise ports & return
; Miscellaneous messages
EVEN: db 'even address','$'
ODD: db 'odd address','$'
PLSMSG: db 'pulse','$'
TCHMSG: db 'touch','$'
; Terminal-dependent control sequences
TCLEOS: db 17H,'$' ;clear to end-of-screen
TCLSCR: db 18H,'$' ;clear screen
;.....
;
; Note: This overlay must terminate prior to 0B00H (with Smartmodem overlay)
; 0D00H (without Smartmodem overlay)
;.....
END