title 'M7-C1660 (MDM) C1660 and C1650 overlay for C128 31 Oct 85' ; M7-C1660.ASM -- Commodore 128 overlay file for MDM7xx. ; ; overlay setup by Von Ertwine for C128 using 1650 or 1660 modem ; 10/31/85 ; ; The default modem type (1650 or 1660) can be setected by ; setting parmater at 15Ch (modem$type) ; ; ; build new system by using to following: ; ; MAC M7-C1670 $pz-s ; MLOAD MDM7x0.com=MDM7x0.COM,M7-C1670.HEX ; ; = = = = = = = = = = = = = = = = = = page $*MACRO ; only show code produced by MAC not MACRO expansion ; eom equ 00h ; end of message bell equ 07h ; bell lf equ 0Ah ; linefeed cr equ 0Dh ; carriage return esc equ 1Bh ; escape no equ 0 yes equ not(no) page ; ; C128 info ; dev$no: equ 6 XxD$config: equ 0fd4Eh ; bit 7 0=no parity 1=parity ; bit 6 0=mark/space 1=odd/even ; bit 5 0=space/even 1=mark/odd ; bit 1 0=1 stop bit 1=2 stop bits ; bit 0 0=7 data bits 1=8 data bits RS232$status: equ XxD$config+1 ; bit 7 1=send data, 0=no data ; bit 6 1=sending data now ; bit 5 1=recv que active ; bit 4 1=parity error ; bit 3 1=framing error ; bit 2 not used ; bit 1 receiving data now ; bit 0 data byte ready xmit$data: equ RS232$status+1 recv$data: equ xmit$data+1 ; MODRCVB: EQU 01H ; bit to test for receive MODRCVR: EQU 01H ; value when receive ready MODSNDB: EQU 80H ; bit to test for send MODSNDR: EQU 00H ; value when send ready data$port$a equ 0DD00h ; bit 2 TxD Data (output) data$port$b equ data$port$a+1 data$port$b$dir equ data$port$b+2 ; bit 7 Data Set Ready (input) ; bit 6 Clear to Send (input) ; bit 5 Place Phone On Hook (active low output) ; bit 4 Carrier Detect (active low input) ; bit 3 Ring Indicator (active low input) ; bit 2 Data Terminal Ready (active hi output) ; bit 1 Request to Send (active hi output) ; bit 0 Received Data (input) page ; setb macro ?N,?R db 0cbh,?N*8+?R+0C0h endm res macro ?N,?R db 0cbh,?N*8+?R+80h endm bit macro ?N,?R db 0cbh,?N*8+?R+40h endm exx macro db 0D9h endm @chk macro ?DD if (?DD GT 7Fh) and (?DD LT 0FF80h) 'Displacement Error' endif endm jr macro ?N db 18h,?N-$-1 @chk ?N-$ endm jrz macro ?N db 28h,?N-$-1 @chk ?N-$ endm jrnz macro ?N db 20h,?N-$-1 @chk ?N-$ endm jrc macro ?N db 38h,?N-$-1 @chk ?N-$ endm jrnc macro ?N db 30h,?N-$-1 @chk ?N-$ endm inp macro ?R db 0EDh,?R*8+40h endm outp macro ?R db 0EDh,?R*8+41h endm cpir macro db 0edh,0b1h endm page ORG 100H DS 3 ;(for "JMP START" instruction) ; PMMIMODEM: DB NO ;yes=PMMI S-100 Modem 103H SMARTMODEM: DB yes ;yes=HAYES Smartmodem, no=non-PMMI 104H TOUCHPULSE: DB 'P' ;T=touch, P=pulse (Smartmodem-only) 105H CLOCK: DB 17 ;clock speed in MHz x10, 25.5 MHz max. 106H ;20=2 MHh, 37=3.68 MHz, 40=4 MHz, etc. MSPEED: DB 1 ;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 NOOFCOL: DB 5 ;number of DIR columns shown 10AH SETUPTST: DB YES ;yes=user-added Setup routine 10BH SCRNTEST: DB yes ;Cursor control routine 10CH ACKNAK: DB YES ;yes=resend a record after any non-ACK 10DH ;no=resend a record after a valid NAK BAKUPBYTE: DB no ;yes=change any file same name to .BAK 10EH CRCDFLT: DB YES ;yes=default to CRC checking 10FH TOGGLECRC: DB YES ;yes=allow toggling of CRC to Checksum 110H CONVBKSP: DB no ;yes=convert backspace to rub 111H TOGGLEBK: DB YES ;yes=allow toggling of bksp to rub 112H ADDLF: DB YES ;no=no LF after CR to send file in 113H ;terminal mode (added by remote echo) TOGGLELF: DB YES ;yes=allow toggling of LF after CR 114H TRANLOGON: DB YES ;yes=allow transmission of logon 115H ;write logon sequence at location LOGON SAVCCP: DB YES ;yes=do not overwrite CCP 116H LOCONEXTCHR: DB no ;yes=local command if EXTCHR precedes 117H ;no=external command if EXTCHR precedes TOGGLELOC: DB YES ;yes=allow toggling of LOCONEXTCHR 118H LSTTST: DB no ;yes=printer available on printer port 119H XOFFTST: DB YES ;yes=check for XOFF from remote while 11AH ;sending a file in terminal mode XONWAIT: DB NO ;yes=wait for XON after CR while 11BH ;sending a file in terminal mode TOGXOFF: DB YES ;yes=allow toggling of XOFF checking 11CH IGNORCTL: DB no ;yes=CTL-chars above ^M not displayed 11DH EXTRA1: DB 0 ;for future expansion 11EH EXTRA2: DB 0 ;for future expansion 11FH BRKCHR: DB 'V'-40H ;^V(^@) = Send a 300 ms. break tone 120H NOCONNCT: 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 TRANCHR: DB 'T'-40H ;^T = Transmit file to remote 125H SAVECHR: DB 'Y'-40H ;^Y = Open input text buffer 126H EXTCHR: DB 'O'-40H ;^O(^^) = Send next character 127H ; ; DS 2 ; used by PMMI 128H IN$MODCTL1: ; get the status bits 12AH lda on$hook$flag ora a jz read$status ; return modem status if off hook jmp modem$ring$test ; test modem? ringing ; ; ; OUT$MODDATP: ;out modem data port 134H push psw lda on$hook$flag ; 0FFh=on hook, 0=off hook ora a jrz modem$out$cont ; send to modem if off hook jmp modem$cmd ; modem command if on hook IN$MODDATP: ; in modem data port 13EH lda recv$data push h lxi h,RS232$status jmp in$moddtp$cont ANI$MODRCVB: ANI MODRCVB ! RET ; bit to test for receive ready 148H CPI$MODRCVR: CPI MODRCVR ! RET ; value of receive bit when rdy 14BH ANI$MODSNDB: ANI MODSNDB ! RET ; bit to test for send ready 14EH CPI$MODSNDR: CPI MODSNDR ! RET ; value of send bit when ready 151H ; PMMI Modem Vectors (not used by C128) DS 6 ; 154H OUT$MODCTL1: ret ; out modem control port 15AH on$hook$flag: db yes ; yes=0FFh=on hook, no=00=off hook modem$type: db 0ffh ; 0ffh=1660(no DTR) 0feh=1660(DTR) ; 000h=1650 15CH OUT$MODCTL2: ret ! nop ! nop ; out modem status port 15DH LOGONPTR: DW LOGON ; for user message. 160H jmp$dial ds 3 ; 162H ;jmp$disconnect ds 3 ; 165H ret ; 165H data$format: db 1 ; number bits and parity ; 7 bits add 0, 8 bits add 1 ; None=0, Odd=E0, Even=C0 ; Mark=A0, Space=80 db 0 ; not used JMP$GOODBYE: JMP GOODBYE ; 168H JMP$INITMOD: JMP INITMOD ; go to user written routine 16BH RET ! NOP ! NOP ; (by-passes PMMI routine) 16EH RET ! NOP ! NOP ; (by-passes PMMI routine) 171H RET ! NOP ! NOP ; (by-passes PMMI routine) 174H JMP$SETUPR: JMP SETUPR ; 177H JMP$SPCLMENU: JMP SPCLMENU ; 17AH JMP$SYSVER: JMP SYSVER ; 17DH JMP$BREAK: JMP SENDBRK ; 180H ; ; Do not change the following six lines. ; JMP$ILPRT: DS 3 ; 183H JMP$INBUF DS 3 ; 186H JMP$INLNCOMP: DS 3 ; 189H JMP$INMODEM DS 3 ; 18CH JMP$NXTSCRN: DS 3 ; 18FH JMP$TIMER: DS 3 ; 192H ; ; ; Clear sequences -- CLREOS is clear to end of screen, CLRSCRN is clear ; entire screen. Last entry must be 0. Any other 0's act as NOP's. ; CLREOS: CALL JMP$ILPRT ; 195H DB esc,'Y',eom SPCLMENU: ret db 0,0 ; CLRSCRN: CALL JMP$ILPRT ; 19EH DB 'Z'-40h,eom ret modem$out$cont: jmp modem$out ; ; ; SYSVER: CALL JMP$ILPRT ; 1A7H db 'C-128 Ver. for 1650 or 1660',cr,lf,eom RET ;..... ; ; ;----------------------------------------------------------------------- ; ; NOTE: You can change the SYSVER message to be longer or shorter. The ; end of your last routine should terminate by 0400H ; ;----------------------------------------------------------------------- ; ; ; in$moddtp$cont: res 0,m pop h ret ; ; modem$out: pop psw sta xmit$data push h lxi h,RS232$status setb 7,m pop h ret ; ; ; modem$ring$test: exx ; save HLDEBC lxi b,data$port$b inp a bit 3,a ; ring indicator bit (active low) jrnz ring$cont recieved$carrier: xri 20h ; toggle on/off hook bit outp a ; take off hook mvi a,no ; set phone off hook sta on$hook$flag lda modem$type ; LSB=0 if suports DTR ani 1 ; =1 if no support mov l,a carrier$yet: dcr l ; 1st time =0ffh if no support jrz ring$cont inp a ani 10h ; test if carrier present jrz ring$cont ; call delay ; delay .16 seconds jr carrier$yet ; will wait .16*255 = 40.8 seconds ; ; ; read$status: lda modem$type ; LSB=0 if suports DTR ani 1 jrnz read$status$cont exx ; save HLDEBC lxi b,data$port$B inp a ani 10h ; test if carrier present cnz phone$on$hook ; lost carrier, hang up the phone ring$cont: exx ; restore HLDEBC read$status$cont: lda RS232$status ret ; ; intersept$inmodem: mvi a,00 ora a exit$intersept: jz 0000 ; address filled in by INIT exx ; save HLDEBC lxi h,RS232$status setb 0,m ; set data advaliable flag mvi l,low(recv$data) ; point to recv$data mov m,a exx ; restore HLDEBC xra a sta intersept$inmodem+1 ; set no intersept stc ; tell caller 'no input data' ret ; ; This routine sends a 300 ms. break tone and sets DTR low for the same ; length of time to disconnect some modems such as the Bell 212A, etc. ; GOODBYE: ; TURN OFF DTR push b call phone$on$hook ; hang-up the phone ani not(6) ; clear DTR bit outp a call sendbrk ; send 300ms break inp a ori 6 outp a ; set DTR pop b ret ; ; This routine allows a 300 ms. break tone to be sent to reset some ; time-shar computers. ; SENDBRK: di push b lxi b,data$port$a inp a ani 0FBh ; send a break tone will be cleared outp a ; ..when interrupts turned on pop b mvi a,30 ; WAIT FOR 300 MS. jmp delay ; re-enables interrupts and returns ; ; Setup routine to allow changing modem speed with the SET command. ; SETUPR: CALL JMP$ILPRT DB 'Modem (1650,1660) ',0 call read$buffer CALL JMP$INLNCOMP ; compare to BAUDBUF+2 DB '1650',0 mvi l,0 jrnc set$type ; Cy=0 if match CALL JMP$INLNCOMP ; compare to BAUDBUF+2 DB '1660',0 jrc setupr test$carrier: CALL JMP$ILPRT DB 'Support carrier detect (Y,N) ',eom call read$buffer ldax d dcr l ; L=0FFh=1660 modem without cpi 'N' jrz set$type ; ..carrier detect cpi 'Y' jrnz test$carrier dcr l ; L=0FEh=1660 modem with set$type: ; ..carrier detect mov a,l sta modem$type lda on$hook$flag ; =FF if on hook ora a rz ; hang-up the phone (only if on hook) ; ; ; phone$on$hook: mvi a,yes sta on$hook$flag lxi b,data$port$b lda modem$type ; 0fxh=1660, 000h=1650 ora a jrz type$1650 ; type$1660: inp a ori 20h ; set, phone on hook (1660) jr on$hook$cont ; type$1650: inp a ani not(20h) ; set, phone on hook (1650) on$hook$cont: outp a ret ; ; C128 initialization -- set baudrate. ; INITMOD: lda data$format ; set number bits and parity sta XxD$config mvi e,3ch ; offset to jmp devtbl call vector$1 ; rets HL=char device table start lxi d,dev$no*8+7 ; offset to RS232 baud rate dad d ; point to RS232 baud rate byte mvi m,6 ; change baud rate to 300 mvi c,dev$no ; init RS232 baud rate mvi e,3fh ; offset to jmp ?cinit (change call vector$1 ; ..the rate) lxi b,data$port$b$dir mvi a,26h ; set data dir to output outp a call phone$on$hook ori 6 ; set DTR and CTS (active hi) outp a lhld jmp$inmodem+1 shld exit$intersept+1 lxi h,intersept$inmodem shld jmp$inmodem+1 mvi a,(RET) sta initmod ret vector$1: lhld 01 mov l,e pchl ; ; ; read$buffer: LXI D,BAUDBUF ; POINT TO INPUT BUFFER CALL JMP$INBUF inx d inx d ret ; ; ; BAUDBUF: DB 6,0 DS 6 ; ; ; modem$cmd: pop psw exx ; save HLDEBC next$dial$state equ $+1 call dial$state$A exx ; restore HLDEBC ret dial$state$A: cpi 'A' call set$next$state$test cpi 'T' call set$next$state$test cpi 'D' call set$next$state$test cpi 'P' call set$next$state$test ; 'A' will be a space at this point "ATDP 1234567" lxi b,data$port$b inp a xri 20h ; take phone off the hook outp a ; take phone off hook mvi a,200 call delay ; delay 2 seconds call set$next$state cpi cr jrz done$dialing cpi ',' jrz delay$1$sec not$comma: sui '0' jrc abort$dial jrnz not$10 mvi a,10 not$10: cpi 10+1 jrnc abort$dial mov d,a ; ; dial number in D ; dial$digit: lxi b,data$port$b ; point to CIA di inp a ; get phone off hook value mov e,a dial$digit$cont: xri 20h ; toggle dial port bit outp a ; output phone on hook value mvi a,6 call delay ; delay 0.06 seconds outp e ; phone back off hook mvi a,4 call delay ; delay 0.04 seconds mov a,e dcr d jrnz dial$digit$cont delay$1$sec: mvi a,100 ; delay 1 second ; ; delay for the number of 0.01 seconds in A ; 20,455 T states per 10 mSecond ; 4+10+7ah+7ahl+4ahl+12ahl-5ah+4ah+12ah-5a+4a+12a-5+10+4+10=23ahl+18ah+11a+29 ; if H=19, L=46 then ; # T states = 20455a+33 delay: di ;4 push h ;10 delay$more: mvi h,19 ;7ah outer$delay: mvi l,46 ;7ahl inter$delay: dcr l ;4ahl jrnz inter$delay ;12ah(l-1)+7ah = 12ahl-5ah dcr h ;4ah jrnz outer$delay ;12a(h-1)+7a = 12ah-5a dcr a ;4a jrnz delay$more ;12(a-1)+7 = 12a-5 pop h ;10 ei ;4 ret ;10 ; ; ; set$next$state$test: jrz set$next$state pop h set$start$state: lxi h,dial$state$A push h set$next$state: pop h shld next$dial$state ret ; ; ; done$dialing: lda modem$type ani 1 ; lsb=0 if it supports carrier detect jrnz send$C$responce lxi h,45000 wait$carrier: lxi b,data$port$b inp a ani 10h jrz send$C$responce mvi c,6 ; direct console I/O mvi e,0ffh ; input data/status push h call 5 pop h cpi 'X'-40h ; test for ^X jrz abort$dial dcx h mov a,h ora l jrnz wait$carrier abort$dial: mvi a,'N' ; send NO CARRIER to MDM7XX db 21 ; LXI H,(MVI A,'C') send$C$responce: mvi a,'C' ; send CONNECT message to MDM7XX send$responce: lxi h,on$hook$flag mvi m,no send$responce$error: sta intersept$inmodem+1 jr set$start$state ; ; You can put in a message at this location which can be called up with ; CTL-L if TRANLOGON has been set TRUE. You can put in several lines if ; desired. End with a 0. ; LOGON: DB 'C128 running MDM7x0 under CP/M Plus',CR,LF,eom ; ; ; ; NOTE: MUST TERMINATE PRIOR TO 0400H (with Smartmodem) ; END ;