title MEX Overlay fuer CPM 3 page 60 ;Autor Wilfried Schmitten, Heidebloeck 16, 2 Hamburg 74 ;letzte Aenderung : 30.1.1989 ; Benutzt AUXIN und AUXOUT ; Waehlroutinen fuer Smartmodem eingebaut ; Abbruch der Waehlroutinen mit ~C = no connection ; ~X = no answer fuer Wahlwiederholung ; Automatische Baudrateneinstellung fuer Wahl aus der Phone.lib ; setze default Device in defdev: unten ; 2 kleine Besonderheiten des verwendeten Assemblers ; defz wie db mit zus{tzlichem byte 0 am Stringende ; defc wie db , aber letztes bytes mit bit 7 = 1 REV: EQU 10 NO: EQU 0 YES: EQU NOT NO test: equ no ;yes fuer Test mit ZSID grip: equ yes speed: equ 60 ;cpu speed in MHz x10, 25.5 MHz max. ;20=2 MHh, 37=3.68 MHz, 40=4 MHz, etc. dpuls: equ 'P' ;T=tone- P=pulse dialing save macro push bc push de push hl endm restore macro pop hl pop de pop bc endm ; ; MEX service processor stuff ; MEX EQU 0D00H ;address of the service processor INMDM EQU 255 ;get char from modem to A, CY=no char in >100 ms TIMER EQU 254 ;delay 100ms * reg B TMDINP EQU 253 ;B=# 10 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, char moving from input 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 auxin equ 3 auxout equ 4 consio equ 6 auxinstat equ 7 auxoutstat equ 8 retvers equ 12 sysctrl equ 49 bioscall equ 50 bdos equ 5 BELL EQU 7 ;bell TAB EQU 9 CR EQU 13 ;carriage return LF EQU 10 ;linefeed ESC EQU 1BH ;escape tpa equ 100h org tpa ; ; ; Defaulteinstellungen fuer MEX ; ------------------------ FIXED FORMAT AREA ---------------- Addr soll ; DEFS 3 ;(for "JMP START" instruction) PMODEM: DEFB NO ;yes=PMMI S-100 Modem 103H SMODEM: DEFB YES ;yes=HAYES Smartmodem, no=non-PMMI 104H TPULSE: DEFB dpuls ;T=tone- P=pulse dialing 105H ;These 3 locations are not referenced ;by MEX CLOCK: DEFB speed MSPEED: DEFB 5 ;0=110 1=300 2=450 3=600 4=710 5=1200 107H ;6=2400 7=4800 8=9600 9=19200 default BYTDLY: DEFB 0 ;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: DEFB 0 ;0=0 delay 1=100 ms 5=500 ms - 9=900 ms 109H ;default time for extra wait after CRLF ;in terminal mode COLUMS: DEFB 6 ;number of DIR columns shown 10AH SETFLG: DEFB YES ;yes=user-added Setup routine 10BH SCRTST: DEFB YES ;home Cursor clears screen 10CH DEFB 0 ;spare 10DH BAKFLG: DEFB YES ;yes=change any file same name to .BAK 10EH CRCDFL: DEFB YES ;yes=default to CRC checking 10FH ;no = checksum checking TOGCRC: DEFB YES ;yes=allow toggling of CRC to Checksum 110H CVTBS: DEFB NO ;yes=convert backspace to rub 111H TOGLBK: DEFB YES ;yes=allow toggling bs/rub 112H ADDLF: DEFB NO ;no=no LF after CR to send file in 113H ;terminal mode (added by remote echo) TOGLF: DEFB YES ;yes=allow toggling of LF after CR 114H TRNLOG: DEFB YES ;yes=allow transmission of logon 115H not used ;write logon sequence at location LOGON SAVCCP: DEFB NO ;yes=do not overwrite CCP 116H DEFB NO ;yes=local command if EXTCHR precedes 117H ;no=external command if EXTCHR precedes DEFB YES ;yes=allow toggling of LOCONEXTCHR 118H LSTTST: DEFB YES ;yes=printer available on printer port XOFTST: DEFB YES ;yes=checks for XOFF from remote while 11AH ;sending a file in terminal mode XONWT: DEFB NO ;yes=wait for XON after CR while 11BH ;sending a file in terminal mode TOGXOF: DEFB YES ;yes=allow toggling of XOFF checking 11CH IGNCTL: DEFB NO ;yes=CTL-chars above ^M not displayed 11DH EXTRA1: DEFB 0 ;for future expansion 11EH EXITCHR: DEFB 'E'-40H ;^E = Exit to main menu 11FH BRKCHR: DEFB '@'-40H ;^@ = Send 300 ms. break tone 120H NOCONN: DEFB 'N'-40H ;^N = disconnect from phone 121H LOGCHR: DEFB 'L'-40H ;^L = Send logon 122H not used LSTCHR: DEFB 'P'-40H ;^P = Toggle printer 123H UNSAVE: DEFB 'R'-40H ;^R = Close input text buffer 124H TRNCHR: DEFB 'T'-40H ;^T = Transmit file to remote 125H SAVCHR: DEFB 'Y'-40H ;^Y = Open input text buffer 126H EXTCHR: DEFB '^'-40H ;^^ = Send next character 127H Š DEFS 2 ;unused by MEX 128H INCTL1: JP INSP ;go input status port 12AH DEFS 7 OTDATA: JP OUTDP ;go output data port 134H DEFS 7 INPORT: JP INDP ;go input data port 13EH DEFS 7 MASKR: AND 0ffh ; 148H RET ;bit to test for receive ready TESTR: CP 0ffh ; 14BH RET ;value of rcv. bit when ready MASKS: JP outsp ;go output status port 14EH ; TESTS: CP 0ffh ;bit to test for send ready 151H RET defs 14 ; DIALV: JP DIAL ;dial digit in A 162H DISCV: JP DISCON ;disconnect the modem 165H GOODBV: JP GOODBY ;called before exit to cpm 168H INMODV: JP NITMOD ;Initialization 16BH NEWBDV: JP PBAUD ;Change Baudrate 16EH NOPARV: DB 0C9H,0,0 ; 171H PARITV: DB 0C9H,0,0 ; 174H SETUPV: JP SETCMD ; 177H DB 0,0,0 ;not used by MEX 17AH VERSNV: JP SYSVER ;Sign On 17DH BREAKV: JP SBREAK ; 180H defdev: db 'SIOA ' ;6 Zeichen, mit space auffuellen db '$' ds 11 ;not used ; Routine to clear to end of screen. If using CLREOS and CLRSCRN, set ; SCRTEST to YES at 010CH (above). ; CLREOS: LD DE,EOSMSG ; 195H LD C,PRINT CALL MEX RET ; CLS: LD DE,CLSMSG ; 19EH LD C,PRINT CALL MEX RET ; 1A7H ; ;----------------------- END OF FIXED AREA ---------------------------- ; Sign On Message SYSVER: if test xor a ;fuer debugging mit ZSID ld (80h),a ;erforderlich endif call ilprint Š if grip defb esc,esc,'70' ;GRIP ASCII Zeichensatz endif db cr, lf,' Overlay CPM 3.0 / ' db speed/10 + '0','.',speed mod 10 + '0',' MHz ' db ' Smartmodem ( WS V' if test defz '-TEST )' else db REV/10+'0','.' defz REV MOD 10+'0',' )' endif jp aktport ; ; Routine to exit just prior to exit-to-cpm ; GOODBY: RET ; ; Send break to remote ; SBREAK: RET ;fehlt noch ; Disconnect the modem ; DISCON: ld b,20 ld c,timer call mex ;warte 2 Sekunden ld hl,mbreak1 call send ld b,20 ld c,timer call mex ld hl,mbreak2 call send ld b,1 ;notwendig ? ld c,timer call mex ret ; ; Port access routines ; ; Input ; INDP: save ld c,auxin call mex restore ret ; Input status ; INSP: save ld c,auxinstat call mex restore ret ; ; output ; OUTDP: save ld c,auxout ld e,a call mex restore ret ; ; Output Status ; MEX kennt nur den globalen Ansprung INCTL1 fuer den Status des Modem ; Control Port. ; Deshalb Output Status ueber MASKS holen OUTSP: save ld c,auxoutstat call mex restore or a ret ilprint: ld c,ilp jp mex ;Initialisierung nitmod: ld c,retvers ;evtl. CP/M Versionsnr. pruefen call bdos ld a,h or a jp nz,wrongv ld a,l cp 31h jp c,wrongv xor a ld (ings),a ;get code ld (outgs),a ld c,sysctrl ld de,reauxin ;get redirection vector call bdos ;fuer auxin und auxout ld (inv),hl ld c,sysctrl ld de,reauxout call bdos ld (outv),hl ;get device table address ld c,bioscall ld de,gettbl call bdos ld (biostblptr),hl ;Pointer ld bc,8 ld e,0 ;Zaehler Anzahl nitm1: add hl,bc ;Pointer weiter inc e ;Zaehler weiter ld a,(hl) or a ;Tabelle Ende? jr nz,nitm1 ld a,e ld (devanz),a ;Anzahl phys. Device ;Pr}fung, ob bereits initialisiert ;wenn ja, Ausgang um evtl. Verbindung ;nicht zu unterbrechen ld de,defdev call calcport ; wird redirection vector SOLL jp c,errdev ;Device nicht gefunden ld de,(inv) ;redirection vector IST ld a,d ;IST high byte and h xor h ;Vergleich mit SOLL jr nz,nitm2 ;ungleich ld a,e ;IST low byte and l xor l ;Vergleich mit SOLL jr nz,nitm2 ;ungleich ;das gleiche fuer auxout Vector ld de,(outv) ld a,d ;IST high byte and h xor h ;Vergleich mit SOLL jr nz,nitm2 ;ungleich ld a,e ;IST low byte and l xor l ;Vergleich mit SOLL jr nz,nitm2 ;ungleich call calcbdptr ;Vergleich der Baudrate ld a,(hl) ;CP/M Baudrate or a jr z,nitm2 ;Baudrate ungeeignet ld hl,baudtb ;Umrechnen auf MEX Baudrate ld bc,bdtblg cpir jr nz,nitm2 ;nicht gefunden ld a,bdtblg inc c sub a,c ; MEX Baudrate ld c,a ld a,(mspeed) ;Vergleich mit default cp c ret z ;Donerwetter, es ist alles richtig ;Initialisieren Auxin Auxout Vector und Baudrate nitm2: ld de,defdev call calcport jr c,errdev ;Device gibt es nicht call setport ld a,(mspeed) call pbaud ret nc ;FERTIG ;Normal Ausgang Initialisiert errbd: ;Baudrate unter CP/M nicht verfuegbar call ilprint defz 'G'-'@',' Invalid baudrate' ret errdev: call ilprint defz 'G'-'@',' Invalid physical device' ret wrongv: call ilprint defz 'G'-'@',cr,lf,' Sorry, you need CP/M 3' ret ;Setzen der Baudrate MEX Baudrate Code pbaud: save ld d,0 ld e,a ;MEX Baudrate Code ld hl,baudtb add hl,de ld a,(hl) ;CPM Baudrate Code ld d,a or a scf ;carry bei Fehler jr z,pb1 call calcbdptr jr c,pb1 ;Phys Device nicht gefunden ld a,d call setbaud ld a,e ld (mspeed),a pb1: restore ret ;Ausgang Pointer auf Baudrate in Device Table calcbdptr: push de ld de,defdev ;Pointer Device Name call calcdev ;ermittle Device Nr. jr c,cp1 ;nicht gefunden ld b,c ;Dev Nr inc b ld de,8 ;8 byte pro Eintrag ld hl,(biostblptr) cp2: add hl,de djnz cp2 dec hl ;Pointer auf Baudraten byte cp1: pop de ret ;Eingang CP/M Baudrate Device Nr Pointer auf Eintrag setbaud: push de ld (hl),a ;Baudrate eintragen ld a,c ld (devc),a ;Dev Nr eintragen ld c,bioscall ld de,devinit call bdos pop de ret ;Ausgang Redirection Vector calcport: call calcdev ;Device Nr. ermitteln ret c ;unbekannt ld b,c ;Dev. Nr inc b ld hl,0 scf cap1: rr h ;Bit an zugehoerige Position rrc l ;schieben djnz cap1 ret ;log Device auxin und auxout dem phys. Device zuordnen setport: ld (inv),hl ld (outv),hl ld a,0feh ;set word code ld (ings),a ld (outgs),a ld de,reauxin ld c,sysctrl ;SCB setzen call bdos ld de,reauxout ld c,sysctrl jp bdos ;Device Nr ermitteln calcdev: ld a,(devanz) ;Anzahl phys. Device's ld b,a ld c,0 ld hl,(biostblptr) ;Device Table cdev1: save ld bc,6 ;Laenge Name cdev2: ld a,(hl) ;Teste ob space cp 20h jr z,cdev3 ;dann fertig ld a,(de) ;Zeichen Vergleichsstring cpi jr nz,cdev3 ;ungleich, abbrechen inc de ;Pointer +1 jp pe,cdev2 cdev3: restore jr z,cdev4 ;gefunden push bc ld bc,8 add hl,bc pop bc inc c ;Device Nr + 1 djnz cdev1 scf ;Kennung nicht gefunden cdev4: ret ;Waehlen dial: ld hl,(dialptr) cp 254 jr z,stdial cp 255 jr z,enddial ld (hl),a ;digit inc hl ld (dialptr),hl ret stdial: ld hl,dialbuf ;pointer normieren ld (dialptr),hl ret enddial: ld (hl),cr inc hl ld (hl),0 ld hl,dialstr call send wed1: ld c,inmdm call mex jr nc,wed1 ;Modem Echo abfangen ld c,60 ;warte 60 sec auf Ergebnis wed2: push bc ld b,1 ;1 sec timed input ld c,timer call mex ld c,inmdm call mex pop bc jr c,wed10 cp cr ;LF und CR ueberspringen jr z,wed10 cp lf jr nz,wed3 ;Modem hat Char wed10: push bc ld c,consio ;direct console I/O ld e,0ffh call bdos pop bc or a jr z,wed4 ;kein char ld b,3 ;Return code :Keyboard abort cp 'C'-'@' jr z,wed5 dec b ;Return code :No answer cp 'X'-'@' jr nz,wed4 wed5: push bc ld b,cr ;shut down modem ld c,sndchr call mex pop bc ld a,b ;return code ret ;AUSGANG bei Abbruch wed4: dec c ;timer jr nz,wed2 ld a,2 ;return code :No answer ret ;timeout wed3: ;Modeminput auswerten and 7fh push bc ld hl,modtab ld bc,modtlg wed6: cpi jr z,wed7 ;gefunden cpi ;skip naechsten char jp pe,wed6 ;weiter wed7: pop bc ld a,(hl) ;MEX Errorcode cp 0ffh ;unbekannt? jr z,wed2 ;dann weiter warten push af ;Modem Echo wed8: ld c,inmdm ;bis zum naechsten call mex ;LF abfangen jr c,wed9 ;kein Zeichen mehr cp lf jr nz,wed8 wed9: pop af ;Normalausgang ret send: ld c,sndrdy call mex jr nz,send ;warte bis output ready to send xor a ld b,(hl) inc hl or b ret z ;Endemarkierung ld c,sndchr call mex jr send ret ;Set Command setcmd: ld c,sblank call mex jp c,aktport ;kein Argument ld de,cmdtbl ld c,lookup call mex push hl ret nc pop hl ;hier nicht gefunden setcerr: call ilprint defz cr,lf,'SET command error',cr,lf ret setp: ld c,sblank call mex ;skip spaces jr c,setcerr ld b,6 ;max 6 char holen ld hl,portinp setp1: push bc push hl ld c,gnc call mex ;hole 1 Zeichen pop hl pop bc jr c,setp2 ;kein Zeichen mehr da cp 20h ;nicht die Baudrate jr z,setp2 ;fressen cp 'A' jr c,setp3 and 0dfh ;Grossbuchstaben machen setp3: ld (hl),a inc hl djnz setp1 setp2: ld (hl),'$' ld de,portinp call calcdev jp c,errdev ;gueltiges Device ld hl,portinp ld de,defdev ld bc,6 ldir ;wird default device ld de,defdev call calcport call setport ld c,sblank call mex ;weitere Zeichen? jr nc,setb ;Baudrate folgt? ld a,(mspeed) call pbaud ;nein, aber neues Devices initialisieren aktport: call ilprint defz cr,lf,' AUX connected to ' ld de,defdev ld c,print call mex jr aktbaud setb: ld c,bdpars call mex ;Parse Baudrate jp c,errbd ;Fehler call pbaud ;versuche einzustellen jp c,errbd jr aktport aktbaud: call ilprint defz ' Baudrate : ' ld a,(mspeed) ld c,prbaud call mex call ilprint defz cr,lf,' ' ret sethelp: call ilprint db cr,lf,'set port ' db cr,lf,'set port ' db cr,lf,'set baud ' db cr,lf db cr,lf,' baud rates available' DB cr,lf,' --------------------' db cr,lf,'110 300 600 1200 2400 4800 9600 19200' db cr,lf db cr,lf,' physical serial devices available' db cr,lf,' ---------------------------------' defz cr,lf ld hl,(biostblptr) ld a,(devanz) ld b,a ld a,(colums) ld c,a sethloop: push hl push bc push hl ld bc,6 add hl,bc ld a,(hl) pop hl and 0fh cp 0fh ;var baud,ser,i,o jr nz,seth1 ld de,devprt ldir ;name umschaufeln ld de,devprt ld c,print call mex ex (sp),hl ;!BC Register dec l ex (sp),hl jr nz,seth1 call ilprint defz cr,lf,32 ld a,(colums) ex (sp),hl ld l,a ex (sp),hl seth1: pop bc pop hl ld de,8 add hl,de djnz sethloop call ilprint defz cr,lf,32 ret ;-------------------------------- ; D A T A A R E A ;-------------------------------- cmdtbl: defc '?' dw sethelp defc 'BAUD' dw setb defc 'BAU' dw setb defc 'BA' dw setb defc 'PORT' dw setp defc 'POR' dw setp defc 'PO' dw setp db 0 ;Uebersetzung Modemmeldung in MEX Code ;byte 1 Modem byte 2 MEX modtab: db 0,0ffh ;ignorieren db 1,0 ;connected db 2,0ffh ;ignorieren db 3,2 ;no connect db 4,4 ;Modem Error db 5,0 ;connected db 6,0ffh ;ignorieren db 7,1 ;far end busy db 8,0ffh ;ignorieren ; evtl auch alphanumerisch db 'O',0ffh db 'C',0 db 'R',0ffh db 'N',2 db 'E',4 db 'B',1 db 0ffh,0ffh modtlg: equ $-modtab portinp: ds 7 dialstr: db 'ATD',dpuls,',' ;vorher 2 Sek. Pause dialbuf: ds 40 dialptr: ds 2 devinit: db 21 db 0 devc: dw 0,0,0 baudtb: db 3,6,0,7,0,8,10,12,14,15 ;110,300,-,610,-,1200,2400,4800,9600,19200 bdtblg: equ $ - baudtb reauxin: db 26h ings: db 0 ;get=0/set word=fe inv: dw 0 ;value fuer set reauxout: db 28h outgs: db 0 outv: dw 0 biostblptr: dw 0 gettbl: db 20 ds 7 devanz: db 0 mbreak1: defz '+++' mbreak2: defz 'ATH',cr eosmsg: db esc,'T' ;clear to screen end db '$' clsmsg: db 'L'-'@' ;clear screen db '$' devprt: db ' $' END