	title	'MEX overlay for MEGA SuperComputer SBC'
;
; MXO-MG10.ASM -- MEX Overlay file for the MEGA SuperComputer SBC
;
; Version 1.0: Written 09/04/84 by Ron Fowler
;
; This overlay adapts the MEX modem program to the Mega Computer Co. Single
; Board Computer, using the Zilog SIO or DART.
;
; This overlay is adaptable to any computer using an SIO or DART for
; serial communications, and is especially useful if such adaptations
; are for computer with multiple SIO chips.  It's also helpful if
; the target computer uses a CTC for generating the serial clock.
;
; This overlay is capable of setting baud rate and setting port number
; (via the SET command), and setting baud rate from the phone library.
;
; Note: to take advantage of software baud-rate selection, you must strap
; the MEGA baud-rate block (J10) as follows:
;
;		CTCI0 - 19200\  For non-MEGA computers, this is a 307KB
;		CTCI1 - 19200 > input clock rate (307KB/16=19200)
;		CTCI2 - 19200/                          
;		CTC00 - first SIO clock (RAn, RTAn/RTBn)--\  
;		CTC01 - second SIO clock                --| 
;		CTC02 - third SIO clock			--|  
; 						   |------/			
;						   |   
;				These may be to any of the 6 SIO
;				clock lines, but MAX of three unless
;				you hack in another CTC.  You must
;				change the values in CTCTBL if you
;				don't use CTC port 4 -- SIO on P5
;					  CTC port 5 -- SIO on P6
;					  CTC port 6 -- SIO on P3
;
; The SIO channels are numbered as follows:
;
;	PORT	Connector   SIO Chip
;	----    ---------   --------
;	0	   P5	       U61
;	1	   P6	       U61
;	2	   P3	       U58
;	3	   P4	       U58	(usually, the console)
;	4	   P7	       U64
;	5	   P8	       U64
;
; The reason for this strange numbering scheme is for compatibility with
; MEGA TurboDOS, where ports 4,5 don't exist (U64 is the network control-
; ler port for TurboDOS, and is not used for RS232 serial communications).
;
; Be aware that, if you're running MEGA TurboDOS, this overlay will dis-
; able the interrupts of any port it's SET to ... you can use the TurboDOS
; version of MEX if this is a problem.  You might prefer to use this overlay
; to communicate in terminal mode at the higher baudrates, which is a losing
; situation with the TurboDOS MEX.
; 
; Set the following NPORT value to the relative port # (table above) you
; want MEX to use on start up.
;
NPORT	EQU	1
;
REV	EQU	10	;V 1.0
;
RDA	EQU	1		;mask for recv-data available
TBE	EQU	4		;mask for transmit-bufr empty
;
; MEX service processor stuff
;
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
;
PRINT	EQU	9		;BDOS/MEX print-string function call
;
BELL	EQU	7		;bell
TAB	EQU	9
CR	EQU	13		;carriage return
LF	EQU	10		;linefeed
ESC	EQU	1BH		;escape
YES	EQU	0FFH
NO	EQU	0
;
;
	ORG	100H
;
; Change the clock speed to suit your system
;
	DS	3		;(for  "JMP   START" instruction)

	DB	NO		;yes=PMMI S-100 Modem			103H
	DB	NO		;yes=HAYES Smartmodem, no=non-PMMI	104H
	DB	'T'		;T=touch, P=pulse (Smartmodem-only)	105H
CLOCK:	DB	50		;clock speed in MHz x10, 25.5 MHz max.	106H
				;20=2 MHh, 37=3.68 MHz, 40=4 MHz, etc.
MSPEED:	DB	5		;0=110 1=300 2=450 3=600 4=710 5=1200	107H
				;6=2400 7=4800 8=9600 9=19200 default
BYTDLY:	DB	5		;0=0 delay  1=10ms  5=50 ms - 9=90 ms	108H
				;default time to send character in ter-
				;minal mode file transfer for slow BBS.
CRDLY:	DB	5		;0=0 delay 1=100 ms 5=500 ms - 9=900 ms 109H
				;default time for extra wait after CRLF
				;in terminal mode file transfer
COLUMS:	DB	5		;number of DIR columns shown		10AH
SETFLG:	DB	YES		;yes=user-added Setup routine		10BH
SCRTST:	DB	YES		;Cursor control routine 		10CH
	DB	YES		;yes=resend a record after any non-ACK	10DH
				;no=resend a record after a valid-NAK
BAKFLG:	DB	YES		;yes=change any file same name to .BAK	10EH
CRCDFL:	DB	NO		;yes=default to CRC checking		10FH
TOGCRC:	DB	YES		;yes=allow toggling of CRC to Checksum	110H
CVTBS:	DB	NO		;yes=convert backspace to rub		111H
TOGLBK:	DB	YES		;yes=allow toggling of bksp to rub	112H
ADDLF:	DB	NO		;no=no LF after CR to send file in	113H
				;terminal mode (added by remote echo)
TOGLF:	DB	YES		;yes=allow toggling of LF after CR	114H
	DB	YES		;yes=allow transmission of logon	115H
				;write logon sequence at location LOGON
SAVCCP:	DB	YES		;yes=do not overwrite CCP		116H
	DB	NO		;yes=local command if EXTCHR precedes	117H
				;no=external command if EXTCHR precedes
	DB	YES		;yes=allow toggling of LOCONEXTCHR	118H
LSTTST:	DB	YES		;yes=printer available on printer port	119H
XOFTST:	DB	NO		;yes=checks for XOFF from remote while	11AH
				;sending a file in terminal mode
XONWT:	DB	NO		;yes=wait for XON after CR while	11BH
				;sending a file in terminal mode
TOGXOF:	DB	YES		;yes=allow toggling of XOFF checking	11CH
IGNCTL:	DB	NO		;yes=CTL-chars above ^M not displayed	11DH
EXTRA1:	DB	0		;for future expansion			11EH
EXITCHR	DB	'E'-40H		;^E = Exit to main menu			11FH
BRKCHR:	DB	'@'-40H		;^@ = Send 300 ms. break tone		120H
NOCONN:	DB	'N'-40H		;^N = Disconnect from the phone line	121H
LOGCHR:	DB	'L'-40H		;^L = Send logon			122H
LSTCHR:	DB	'P'-40H		;^P = Toggle printer			123H
UNSAVE:	DB	'R'-40H		;^R = Close input text buffer		124H
TRNCHR:	DB	'T'-40H		;^T = Transmit file to remote		125H
SAVCHR:	DB	'Y'-40H		;^Y = Open input text buffer		126H
EXTCHR:	DB	'^'-40H		;^^ = Send next character		127H
	DS	2		;unused by MEX				128H
;
INCTL1:	JMP	INSP		;go input status port			12AH
	DS	7
;
OTDATA:	JMP	OUTDP		;go output data port			134H
	DS	7
;
INPORT:	JMP	INDP		;go input data port			13EH
	DS	7
;
MASKR:	ANI	RDA	! RET	;bit to test for receive ready		148H
TESTR:	CPI	RDA	! RET	;value of rcv. bit when ready		14BH
MASKS:	ANI	TBE	! RET	;bit to test for send ready		14EH
TESTS:	CPI	TBE	! RET	;value of send bit when ready		151H
	DS	14		;					156H
;
;
	DS	3		;DIALV: not done here (maybe MXO-SM)	162H
DISCV:	JMP	DISCON		;disconnect
GOODBV:	JMP	GOODBY		;					168H
INMODV:	JMP	NITMOD		;go to user written routine		16BH
	RET ! NOP ! NOP		;NEWBDV					16EH
	RET ! NOP ! NOP		;NOPARV					171H
	RET ! NOP ! NOP		;PARITV					174H
SETUPV:	JMP	SETCMD		;					177H
	DS	3		;not used by MEX			17AH
VERSNV:	JMP	SYSVER		;					17DH
BREAKV:	JMP	SBREAK		;					180H
;
; Do not change the following six lines (they provide access to routines
; in MEX that are present to support MDM7 overlays -- they will likely
; be gone by MEX v2.0).
;
ILPRTV:	DS	3		;					183H
INBUFV	DS	3		;					186H
ILCMPV:	DS	3		;					189H
INMDMV:	DS	3		;					18CH
	DS	3		;					18FH
TIMERV	DS	3		;					192H
;
; Routine to clear to end of screen.  If using CLREOS and CLRSCRN, set
; SCRTEST to YES at 010AH (above).
;
CLREOS:	LXI	D,EOSMSG	;					195H
	MVI	C,PRINT
	CALL	MEX
	RET
;
CLS:	LXI	D,CLSMSG	;					19EH
	MVI	C,PRINT
	CALL	MEX
	RET
;									1A7H
;
; end of fixed area
;
SYSVER:	MVI	C,ILP		;in-line print
	CALL	MEX
	DB	'MEGA SuperComputer rev '
	DB	REV/10+'0'
	DB	'.'
	DB	REV MOD 10+'0'
	DB	CR,LF,0
	RET
;
; Routine to exit just prior to exit-to-cpm
;
GOODBY:	RET			;not done here
;
; Send break to remote
;
SBREAK:	RET			;not yet implemented
;
; Disconnect the modem (not done here, relies on SM overlay)
;
DISCON:	RET
;
; SET command: select baud rate, port name. Port name may be any of
; ABC, DELTA, USR (names may be changed by altering PNMTBL entries),
; baud rate any of xxxxxxxxxxxxxxxxxxxxx
; Special set-port syntax allows baud rate after port name.  Examples:
;
;	SET PORT DELTA3
;	SET PORT ABC 1200
;	SET PORT USR 300
;	SET BAUD 9600
;
SETCMD:	MVI	C,SBLANK	;any arguments?
	CALL	MEX
	JC	TELL		;if not, go display port/baud
	LXI	D,CMDTBL
	MVI	C,LOOKUP
	CALL	MEX		;parse argument
	PUSH	H		;save any parsed argument adrs on stack
	RNC			;if we have one, return to it
	POP	H		;oops, input not found in table
SETERR:	MVI	C,ILP		;inline print
	CALL	MEX
	DB	CR,LF,'SET command error',CR,LF,0
	RET
;
; Argument table
;
CMDTBL:	DB	'?'+80H		;help
	DW	STHELP
	DB	'BAU','D'+80H	;"set baud"
	DW	STBAUD
	DB	'POR','T'+80H	;"set port"
	DW	SETPOR
	DB	0		;<<=== table terminator
;
; "SET ?" processor
;
STHELP:	MVI	C,ILP		;inline print
	CALL	MEX
	DB	CR,LF,'SET BAUD <rate>'
	DB	CR,LF,'SET PORT <port-number>'
	DB	CR,LF
	DB	CR,LF,'Baud rate is one of:'
	DB	CR,LF,'   300 600 1200 4800 9600 19200'
	DB	CR,LF,'Port number is one of:'
	DB	CR,LF,'   0-7 : interfacer 3 or 4 port number'
	DB	CR,LF,'   S   : System Support I serial port'
	DB	CR,LF,0
	RET
;
; "SET BAUD" processor
;
STBAUD:	MVI	C,BDPARS	;function code: parse a baudrate
	CALL	MEX		;let MEX look up code
	JC	SETERR		;jump if invalid code
	CALL	PBAUD		;no, try to set it
	JC	SETERR		;if not one of ours, bomb out
BDSHOW:	MVI	C,ILP		;inline print
	CALL	MEX		;display baud
	DB	'Baud: ',0
	LDA	MSPEED		;get current baud rate
	MVI	C,PRBAUD	;let MEX print it
	CALL	MEX
	RET
;
; SET PORT processor
;
SETPOR:	MVI	C,SBLANK	;scan to argument
	CALL	MEX
	JC	SETERR		;if no arg, bomb out
	MVI	C,GNC		;else consume it
	CALL	MEX
	SUI	'0'		;convert
	JC	SETERR
	CPI	5+1
	JNC	SETERR
	CALL	SPA		;set port addresses
	MVI	C,SBLANK	;any thing more?
	CALL	MEX
	JNC	STBAUD		;if so, go parse as baud rate
TELL:	MVI	C,ILP
	CALL	MEX
	DB	CR,LF,'Port: ',0
	LDA	PORT
	ADI	'0'		;get port # in ASCII
	STA	PORTAS
	MVI	C,ILP
	CALL	MEX
PORTAS:	DB	'    ',0
	JMP	BDSHOW
;
; Initialize channel ... as distributed, this code simply
; sets the default port, default port addresses, and default
; MSPEED (based on MSPTBL table).  You might want to modify
; this do do a full channel initialization, including SIO
; setup and baud rate.  If so, delete the commented-out code
; in between NITMOD and SPA, and enter your initial baudrate
; just prior to the call on PBAUD.  If you do this, you should
; be aware that whenever you enter MEX, the baudrate will be
; set to this default rate (even if a connection is in prog-
; ress at a different rate).
;
NITMOD:	MVI	A,NPORT		;get initial port number
;
;; De-comment the following for full initialization
;;
;;	CALL	SPA		;calculate harware port addresses
;;	MVI	A,??		;substitute MSPEED baud value for ??
;;	CALL	PBAUD		;set rate, init channel
;;	RET			;end of init block
;
; Calculate hardware status and data port addresses for
; relative port number passed in A.
;
SPA:	STA	PORT		;save port number
	MOV	E,A		;port # to DE
	MVI	D,0		;index into table
	LXI	H,PORTBL	;get table of port hardware addresses
	DAD	D
	DAD	D
	MOV	A,M		;fetch status port #
	STA	SPORT		;set it
	INX	H
	MOV	A,M		;fetch data port #
	STA	DPORT
	LXI	H,MSPTBL	;get port's MSPEED value
	DAD	D
	MOV	A,M		;set MSPEED
	STA	MSPEED
	RET
;
; Port assignment table for each SIO.  Each entry
; consists of status-port adrs followed by data-
; port address.
;
PORTBL:	DB	0EH,0CH		;port 0	 (SIO #1, A)
	DB	0FH,0DH		;port 1  (SIO #1, B)
	DB	16H,14H		;port 2  (SIO #2, A)
	DB	17H,15H		;port 3  (SIO #2, B)
	DB	1AH,18H		;port 4  (SIO #3, A)
	DB	1BH,19H		;port 5  (SIO #3, B)
;
; This routine sets baud rate passed as MSPEED code in A.
; Returns CY=1 if baud rate not supported (if supported,
; this routine must set the new MSPEED code).
;
PBAUD:	PUSH	H		;don't alter anybody
	PUSH	D
	PUSH	B
	MOV	E,A		;MSPEED code to DE
	MVI	D,0
	LDA	PORT		;get port #
	MOV	C,A		;to BC
	MVI	B,0
	LXI	H,BAUDFL	;offset to flags for this port
	DAD	B
	MOV	A,M		;software baudrate supported
	ORA	A		;  for this port?
	STC			;prep carry in case not
	JZ	PBEXIT		;jump if not supported
	LXI	H,MSPTBL	;yes. offset MSPEED for this port
	DAD	B
	MOV	M,E		;store current rate
	LXI	H,MSPEED	;set MSPEED value also
	MOV	M,E
	LXI	H,BAUDTB	;offset into divisor table
	DAD	D		;indexed by SPEED value
	MOV	A,M		;fetch divisor
	PUSH	PSW		;save divisor
	PUSH	B		;save relative port #
	LDA	SPORT		;get status port adrs
	MOV	C,A		;status port adrs to C
	MVI	B,SIOLEN	;b=length of SIO code
	LXI	H,SIONIT	;point to init code
	DB	0EDH,0B3H	;Z80 OUTIR
	POP	B		;recall relative port #
	LXI	H,CTCTBL	;offset to CTC register, this port
	DAD	B
	MOV	C,M		;PORT # IN C
	MVI	A,45H		;SEND COMMAND CODE
	DB	0EDH,079H	;Z80 OUTP A instruction
	POP	PSW		;recall divisor
	DB	0EDH,079H	;Z80 OUTP A instruction
	ORA	A		;return no-errors
PBEXIT:	POP	B
	POP	D
	POP	H
	RET
;
; table of CTC divisors for each rate
;
BAUDTB:	DB	175		;110 (not exact, but close enuf)
	DB	64		;300
	DB	48		;450
	DB	32		;600
	DB	27		;710 (not exact)
	DB	16		;1200
	DB	8		;2400
	DB	4		;4800
	DB	2		;9600
	DB	1		;19200
;
; baud rate flags for each SIO port.  Set to 0
; for a port that doesn't support software baudrate
; change, 1 for ports that can.
;
BAUDFL:	DB	1,1,1,0,0,0	;6 ports (I have only first 3 connected to CTC)
;
;
; the following table associates each port with a CTC
; hardware address.  Valid port addresses must correspond
; with the BAUDFL table above
;
CTCTBL:	DB	4,5,6,0,0,0	;only 3 channels available on 1 ctc
;
; The following table holds MSPEED for each port.
; Since it's not possible to tell divisors exist in
; the CTC prior to bringing up MEX, this table is
; set with defaults, and is filled in with actual
; values as each port gets a SET BAUD command.
;
MSPTBL:	DB	5,5,5,5,5,5	;speed for each port: 1200
;
; Init code for an SIO channel
;
SIONIT:	DB	18H		;reset channel
	DB	4		;select write reg 4
	DB	44H		;16*clock, 1 stop bit,  no parity
	DB	5		;select write reg 5
	DB	0EAH		;DTR, 8 bits xmit, TX enabl, RTS
	DB	3		;select write reg 3
	DB	0C1H		;8 bits recv, recv enable
SIOLEN	EQU	$-SIONIT	;length of SIO init code
;
;	Port access routines
;
; Input
;
INSP:	LDA	SPORT		;get status-port adrs
	JMP	INP1
INDP:	LDA	DPORT		;get data-port adrs
INP1:	STA	INP2+1		;modify the code
INP2:	IN	0		;do the input
	RET
;
;
; output status port
;
OUTSP:	PUSH	PSW		;save the value
	LDA	SPORT		;get port adrs
	JMP	OUTT		;on to common code
;
; output data port
;
OUTDP:	PUSH	PSW		;save the char
	LDA	DPORT		;get data-port adrs
OUTT:	STA	OUT1+1		;modify the code
	POP	PSW		;recall data byte
OUT1:	OUT	0
	RET
;
;
PORT:	DS	1		;put your initial port # here
;
DPORT:	DS	1		;data port address
SPORT:	DS	1		;status port address
;
; Clear-to-end-of-screen and clear-screen sequences
;
EOSMSG:	DB	ESC,'T','$'
CLSMSG:	DB	26,'$'
;
;
	END
;
