home *** CD-ROM | disk | FTP | other *** search
-
-
-
- TITLE 'Commodore Modem Overlay V1.0 19 Nov 85'
- ;
- $*MACRO ; have MAC only display CODE not MACRO expansion
- ;
- ; This overlay was created for the C128
- ; by Von Ertwine 19 Nov 85
- ;
- ; SYSTEM CONSTANTS
- ;
- mdm$tp equ 0104h ; 7 (1670 if set)
- ; 6 (1650 or 1660 if set)
- ; 5 (1660 if set)
- ; 4 (supports CD if clear)
- ; 3 (set if 1200 baud is supported)
- ; 2 (set if 600 baud is supported)
- ; 1 (set if 300 baud is supported)
- ; 0 (set if 110 baud is supported)
- TPULSE EQU 0105h ;TONE/PULSE FLAG IN MODEM OVERLAY
- MSPEED EQU 0107h ; current baud rate
- MDM$ST EQU 012Ah ; normal status call
- SHOWBD EQU 012Eh ; show current baud rate
- out$mdm equ 0134h
- mask$s equ 014eh
- test$s equ 0151h
-
-
- DIALV EQU 0162h ;LOCATION OF DIAL VECTOR IN OVERLAY
- DISCV EQU 0165h ;LOCATION OF DISCONNECT VECTOR IN OVERLAY
- NEWBDV EQU 016Eh ;change baud rate (value in A)
-
- DIALOC EQU 0800h ;DIALING CODE GOES HERE
- MEX EQU 0D00h ;"CALL MEX"
- SMINIT equ 0d55h ; modem init vector
- ssetv equ 0d57h ; sset cmd vector
- smexit equ 0d59h ; modem exit vector
-
- page
- ;
- ; FOLLOWING ARE FUNCTION CODES FOR THE MEX SERVICE CALL PROCESSOR
- ;
- INMDM EQU 255 ;RETURN CHAR FROM MDM IN A, CY=NO CHR IN 100MS
- 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
- 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
- ;
- ;
-
- eom equ 00H
- 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
-
- 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 0=no data 1=send data
- ; bit 6 1=sending data now
- ; bit 5 1=recv queue 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
-
- bit macro ?N,?R
- db 0cbh,?N*8+?R+40h
- endm
-
- setb macro ?N,?R
- db 0cbh,?N*8+?R+0C0h
- endm
-
- res macro ?N,?R
- db 0cbh,?N*8+?R+80h
- 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
-
- exx macro
- db 0d9h
- endm
-
- page
- ;
- ;
- ;
- org mdm$st
- jmp mdm$stat ; default as 1670 and 1011A status
- ;
- org dialv
- jmp dial ; point system to dialer routine
- ;
- org discv
- jmp discon ; point disconect to modem disconect
- ;
- org SMINIT
- dw init$mod ; install modem init vector
- ;
- org ssetv
- dw do$sset ; install SSET comand vector
- ;
- ;
- ;
- org dialoc
- do$sset:
- mvi c,sblank
- call mex ; any arguments?
- jrc disp$options
- lxi d,opt$tbl
- mvi c,lookup
- call mex
- jrnc ipchl
- disp$options:
- call initmod
- mvi c,ilp
- call mex
- db cr,lf,'Select 1011A, 1650, 1670, 1660 or'
- db ' 1660CD (if Carrier Detect is supported)'
- db cr,lf,eom
- ret
-
- ipchl:
- pchl
-
- page
-
- opt$tbl:
- db '1011','A'+80h
- dw set$1011
- db '165','0'+80h
- dw set$1650
- db '1660C','D'+80h
- dw set$1660cd
- db '166','0'+80h
- dw set$1660
- db '167','0'+80h
- dw set$1670
- db 0
-
-
- set$1670:
- mvi a,10001010b
- db 21h ; lxi h,(mvi a,0Fh)
- set$1011:
- mvi a,00001111b
- db 21h ; lxi h,(mvi a,42h)
- set$1650:
- mvi a,01000010b
- db 21h ; lxi h,(mvi a,72h)
- set$1660:
- mvi a,01110010b
- db 21h ; lxi h,(mvi a,62h)
- set$1660cd:
- mvi a,01100010b
- sta mdm$tp
-
- page
-
- mvi c,sblank
- call mex ; any arguments?
- jrc no$parm
- ani 01011111b ; make upper case
- cpi 'T' ; user select Tone?
- jrz save$T$P ; yes, go set it
- cpi 'P' ; no, user select Pluse
- jrnz no$parm ; no, use old parameter
- save$T$P: ; yes, select Pluse
- sta TPULSE ; change to PLUSE or TONE
- no$parm:
- lda mspeed
- cpi 0 ; 110 baud
- jrz ck$110
- cpi 1 ; 300 baud
- jrz ck$300
- cpi 3 ; 600 baud
- jrz ck$600
- cpi 5 ; 1200 baud
- jrnz change$baud
-
- mvi a,00001000b
- db 21h ; lxi h,mvi a,4
- ck$600:
- mvi a,00000100b
- db 21h ; lxi h,mvi a,2
- ck$300:
- mvi a,00000010b
- db 21h ; lxi h,mvi a,1
- ck$110:
- mvi a,00000001b
-
- lxi h,mdm$tp ; point to allowed rates
- ana m ; is baud rate allowed for
- jrnz initmod ; ..this modem ? yes, go do it
-
- page
- ;
- ;
- ;
- change$baud: ; no, adjust to lowest allowed rate
- mvi a,-1
- try$next:
- inr a
- sta mspeed
- call NEWBDV ; change the baud rate
- lda mspeed ; ..(Cy set if bad rate)
- jrc try$next
- lxi h,showbd ; tell user the new baud rate
- push h ; ..after we are done
- ;
- ; C128 initialization -- set baudrate.
- ;
- INITMOD:
- mvi c,ilp
- call mex
- db cr,lf,'Current Device type is: ',eom
- call show$device
- shld MDM$ST+1
- mvi c,ilp
- call mex
- db cr,lf,eom
-
- lxi b,data$port$b$dir
- lda mdm$tp ; get current modem type
- ani 40h ; 1650, 1660 modem?
- jrz init$no$dial
- mvi a,26h ; set data dir to output
- outp a
-
- lda on$hook$flag ; =FF if on hook
- ora a
- cnz phone$on$hook ; hang-up the phone (only if on hook)
- mvi c,low(data$port$b)
- inp a
- init$no$dial:
- ori 6 ; set DTR and CTS (active hi)
- outp a
- ret
-
- page
- ;
- ;
- ;
- show$device:
- mvi c,ilp
- lxi h,mdm$stat
- lda mdm$tp ; get current type
- bit 7,a
- jrz test$1660$50
- lda tpulse
- sta msg$tpulse
- call mex
- db '1670 '
- msg$tpulse:
- db 'x',eom
- ret
- ;
- test$1660$50:
- bit 6,a
- jrnz test$1650
- call mex
- db '1011A - RS232 interface',eom
- ret
- ;
- test$1650:
- lxi h,mdm$stat$1650$60
- bit 5,a
- jrnz show$1660
- call mex
- db '1650',eom
- ret
- ;
- show$1660:
- bit 4,a
- jrnz show$1660$no$CD
- call mex
- db '1660 with CD',eom
- ret
- ;
- show$1660$no$CD:
- call mex
- db '1660 with-out CD',eom
- ret
-
- page
- ;
- ; FOLLOWING ROUTINE DISCONNECTS THE MODEM USING SMARTMODEM
- ; CODES. ALL REGISTERS ARE AVAILABLE FOR THIS FUNCTION.
- ; NOTHING RETURNED TO CALLER.
- ;
- DISCON:
- lda mdm$tp
- ani 80h
- jrz phone$on$hook ; go place phone on hook if not 1670
-
- call wait$2$sec ; 1670, send hayes disconnect seq.
- call mdm$snd$msg
- db '+++',eom
- call wait$2$sec
- call mdm$snd$msg
- db 'ATH',cr,eom ; not needed by 1670 but req for hayes
- ret
-
- wait$2$sec:
- mvi b,20
- mvi c,timer
- jmp mex ; delay 2 seconds
-
- page
- ;
- ; Place phone on hook (This routine is used if 1650 or 1660)
- ;
- phone$on$hook:
- mvi a,yes
- sta on$hook$flag
- lxi b,data$port$b
- lda mdm$tp
- ani 20h ; bit 5=1 if 1660, =0 if 1650
- 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
-
- page
- ;
- ; This is the DIAL routine called by MEX to dial a digit. The digit
- ; to be dialed is passed in the A register. Note that two special
- ; codes must be intercepted as non-digits: 254 (start dial sequence)
- ; and 255 (end-dial sequence). Mex will always call DIAL with 254
- ; in the accumulator prior to dialing a number. Mex will also call
- ; dial with 255 in A as an indication that dialing is complete. Thus,
- ; the overlay may use these values to "block" the number, holding it
- ; in a buffer until it is completely assembled (in fact, that's the
- ; scheme employed here for the Smartmodem).
- ;
- ; After the 254-start-dial sequence, MEX will call the overlay with
- ; digits, one-at-a-time. MEX will make no assumptions about the dig-
- ; its, and will send each to the DIAL routine un-inspected (some modems,
- ; like the Smartmodem, allow special non-numeric characters in the
- ; phone number, and MEX may make no assumptions about these).
- ;
- ; After receiving the end-dial sequence (255) the overlay must take
- ; whatever end-of-dial actions are necessary *including* waiting for
- ; carrier at the distant end. The overlay should monitor the keyboard
- ; during this wait (using the MEX keystat service call), and return
- ; an exit code to MEX in the A register, as follows:
- ;
- ; 0 - Carrier detected, connection established
- ; 1 - Far end busy (only for modems that can detect this condition)
- ; 2 - No answer (or timed out waiting for modem response)
- ; 3 - Keyboard abort (^C only: all others should be ignored)
- ; 4 - Error reported by modem
- ;
- ; <No other codes should be returned after an end-dial sequence>
- ;
- ; The overlay should not loop forever in the carrier-wait routine, but
- ; instead use either the overlay timer vector, or the INMDMV (timed 100
- ; ms character wait) service call routine.
- ;
- ; The DIAL routine is free to use any of the registers, but must return
- ; the above code after an end-dial sequence
- ;
- next$dial$state equ $+1
- dial:
- jmp dial$idle
-
- page
- ;
- ;
- ;
- dial$idle:
- cpi -2 ; start dial sequence?
- mvi a,4 ; dial error code (valid if last state)
- rnz ; exit if not (this is the start state)
- lda mdm$tp ; get the modem type byte
- bit 7,a ; is device a Commodore 1670 ?
- jrz dl$tst$1650$60 ; no, go test 1650 and 1660
- ;
- ; user has a Hayes compadable modem (1670)
- ;
- lda tpulse ; GET OVERLAY'S TOUCH-TONE FLAG
- sta ATDx ; PUT INTO STRING
- call mdm$snd$msg ;
- db 'ATD'
- ATDx: db 'T ',eom
- call set$next$state
- ;
- ; at this point we should recieve numbers to dial or exit code (-1)
- ;
- cpi -1
- jnz mdm$snd$A ; send it (do not change states)
-
- call mdm$snd$CR ; send CR to modem to end input
- mvi b,-1
- call strip$mdm ; remove any modem input
- call result ; returns with result is A
- push psw ; save result
- call mdm$snd$CR ; send CR to the modem
- pop psw ; ..will abort if error else
- ; ..just send CR to host.
- set$start$state:
- lxi h,dial$idle
- push h
- set$next$state:
- pop h
- shld next$dial$state
- ret
-
- page
- ;
- ; User has selected the 1011A or EQV. device. No dialing.
- ;
- dial$1011a:
- mvi a,4 ; device error code (1011A
- ret ; ..can not dial)
- ;
- ;
- ;
- dl$tst$1650$60:
- bit 6,a ; test if commodore 1650 or 1660 modem
- jrz dial$1011A ; if not 1650 or 1660 must be 1011A
- ;
- ; User has selected Commodore 1650 or 1660 modem
- ;
- call phone$on$hook
- xri 20h ; toggle on/off hook bit
- outp a ; take phone off hook
- call wait$2$sec
- call set$next$state
- ;
- ;
- ;
- cpi -1
- jrz done$1650$60
- cpi ','
- jrz delay$1$sec
- cpi '-'
- rz
- sui '0'
- jrc send$responce
- jrnz not$10
- mvi a,10
- not$10:
- cpi 10+1
- mov d,a
- jrnc send$responce
-
- page
- ;
- ; dial number in D
- ;
- dial$digit:
- lxi b,data$port$b ; point to CIA
- 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
- ; 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
-
- page
-
- ;
- ;
- ;
- done$1650$60:
- lda mdm$tp
- cma
- ani 10h ; bit 4=0 if it supports CD
- jrz send$responce ; send A=0 (connected)
- lxi h,45000
- wait$carrier:
- lxi b,data$port$b
- inp a
- ani 10h ; test carrier detect
- jrz send$responce ; send A=0 (connected)
-
- call test$abort ; user request abort ?
- jrz send$responce ; yes, send A=3 (abort code)
- dcx h
- mov a,h
- ora l
- jrnz wait$carrier
- mvi a,2 ; send - NO CARRIER code
- send$responce:
- lxi h,on$hook$flag
- mvi m,no
- jmp set$start$state
-
-
- page
- ;
- ; THE FOLLOWING LOOP WAITS FOR A RESULT FROM THE MODEM (UP TO
- ; 60 SECONDS: YOU MAY CHANGE THIS VALUE IN THE FOLLOWING LINE).
- ; NOTE THAT THE SMARTMODEM HAS AN INTERNAL 30 SECOND TIMEOUT WHILE
- ; FOR A CARRIER ON THE OTHER END. YOU CAN CHANGE BY PLAYING WITH THE
- ; S7 VARIABLE (I.E. SEND THE SMARTMODEM "AT S7=20" TO LOWER THE 30 SECOND
- ; WAIT TO 20 SECONDS).
- ;
- result:
- mvi c,60 ; wait 60 seconds for a responce
- result$loop:
- push b ; save current time
- lxi b,1*256+tmdinp ; wait for up to 1 second for input
- call mex ; any modem responce yet?
- pop b ; recover current time
- jrnc test$responce ; yes, go test it
- call test$abort ; no, user wish to abort
- rz ; yes, exit (A=3)
- dcr c ; no, 60 second over yet?
- jrnz result$loop ; no, test again
- mvi a,2 ; yes, return timeout code
- ret
- ;
- ;
- ;
- test$responce:
- call test$code ; check responce Cy=1 if unknown
- mov a,b ; place responce code in A
- push psw ; save responce and Cy flag
- mvi b,lf ; remove characters from modem until
- call strip$mdm ; ..none in 100MS or a LF
- pop psw ; recover responce and Cy flag
- jrc result ; start over if bad responce
- ret
-
- page
- ;
- ;
- ;
- test$abort:
- push h
- push b ; save count (in C)
- mvi c,chekcc
- call mex ; user type a ^C ?
- pop b
- pop h
- mvi a,3 ; return abort code (only
- ret ; ..used if abort)
- ;
- ;
- ;
- strip$mdm:
- mvi c,inmdm ; get modem character (Cy=1 if
- push b ; ..none in 100Ms)
- call mex
- pop b
- rc ; return if Modem is empty
- cmp b ; test for end character
- rz ; found user char, return
- jr strip$mdm ; get next character
-
- ;
- ; check modems responce against legal ones, return carry set if
- ; not a legal responce, else return code for responce
- ;
- test$code:
- ani 7FH ; strip parity bit
- mvi b,0 ; start with connect code
- cpi 'C' ; Connect?
- rz ; yes, ret
- cpi '1' ; # code for Connect?
- rz ; yes, ret
- cpi '5' ; # code for Connect 1200?
- rz ; yes, ret
- mvi b,2 ; no connect code
- cpi 'N' ; No Connect?
- rz ; yes, ret
- cpi '3' ; # code for No Connect?
- rz ; yes, ret
- mvi b,4 ; modem error code
- cpi 'E' ; Error ?
- rz ; yes, ret
- cpi '4' ; #code for Error?
- rz ; yes, ret
- stc ; set carry if none of above
- ret
-
- page
- ;
- ; send string following CALL to the modem (to EOM)
- ;
- mdm$snd$msg:
- xthl
- call mdm$snd$HL
- xthl
- ret
- ;
- ; send string pointed to by HL to modem (ended with a zero (EOM))
- ;
- mdm$snd$HL:
- mov a,m ; FETCH NEXT CHARACTER
- ora a ; END?
- rz ; DONE IF SO
- call mdm$snd$A
- inx h
- jr mdm$snd$HL
- ;
- ; send a CR to the modem
- ;
- mdm$snd$CR:
- mvi a,cr
- ;
- ; send character in A to modem
- ;
- mdm$snd$A:
- push psw ; save char to send
- mdm$snd$bzy:
- mvi c,snd$rdy ; test if modem is ready for a byte
- call mex ;
- jrnz mdm$snd$bzy ; if not ready loop back
- pop psw ; recover char to send
- jmp out$mdm
-
- page
- ;
- ;
- ;
- mdm$stat$1650$60:
- lda on$hook$flag
- ora a
- jrz read$status ; return modem status if off hook
- ;
- ; test if modem is ringing
- ;
- exx ; save HLDEBC
- lxi b,data$port$b
- inp a
- bit 3,a ; ring indicator bit (active low)
- jrnz ring$cont ; exit if not ringing
- ;
- ; ringing, take phone off hook and wait for CD (if used)
- ;
- xri 20h ; toggle on/off hook bit
- outp a ; take off hook
- mvi a,no ; set phone off hook
- sta on$hook$flag
- lda mdm$tp ; bit 4=0 if supports CD
- ani 10h ; =10h if no support
- jrz ring$cont
- mvi l,0
- carrier$yet:
- dcr l
- 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
-
- page
- ;
- ;
- ;
- read$status:
- lda mdm$tp ; bit 4=0 if supports CD
- ani 10h
- jrnz mdm$stat ; exit if CD is not supported
- ;
- ; make sure that the carrier is still present (hang up if not)
- ;
- 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
- ;
- ;
- ;
- mdm$stat:
- lda RS232$status
- ret
-
-
-
- ;
- ; data area
- ;
- on$hook$flag:
- db yes ; yes=0FFh=on hook, no=00=off hook
-
- end
-