; ; driver to allow pmmi to be a cp/m3 io device ; version equ 03 ;5/22/83 show version support - strip parity ; 02 5/15/83 ; by dick lieber 4/1/83 maclib z80 maclib cpm3cnfg public ?min, ?minst, ?mout, ?moutst, ?minit, ver$pm extrn @mbaud ;modem baud rate in chartable extrn ?bnksl desg ver$pm: db 'pmmi ', version / 10 + '0', version mod 10 + '0', 0 cseg ;this gets driven by CON ; ; io redirection vector data ; ; ; this mask will be applied to the half of the ; io redirection vector that might contain the modem bit ; modem$mask: equ 1101$1111b ;mask to strip off modem from ;vector ; ; since the io redirection vector is a word, you ; must specify whether the upper or lower byte ; contains the modem bit ; vector$half: equ 1 ;0=low byte (device 8-11) ;1=high byte (device 0-7) ; ;*********** pmmi modem i/o area ************ ; ;pmmi modem port equates ; tport equ 0c8h ;uart control/status port (base) ; dport equ tport+1 ;data port rport equ tport+2 ;rate gen/modem status cport equ tport+3 ;modem control ; ;switch hook and modem commands, output to tport (port 0) ; p0bye equ 0 ;on hook, or dialing break p0orig equ 1 ;off hook, orig. p0answ equ 2 ;answer phone p08bit equ 0ch ;8 data bits p0nopy equ 10h ;no parity p0eps equ 20h ;even parity select p0tsb equ 40h ;2 stop bits p0ei equ 80h ;enable interrupts p0norm equ p08bit+p0nopy ;normal 8 bits, no parity p0110 equ p08bit+p0nopy+p0tsb ;same w/2 stop bits ; ;modem status, input on rport (port 3) ; p2dtd equ 1 ;dial tone detect p2rdet equ 2 ;ring detect p2cts equ 4 ;cts (carrier detect) p2rxbrk equ 8 ;receive break p2conn equ 10h ;connected? (0=yes, 1=modem chip hung up) p2tmpul equ 80h ;timer pulses (40% up cycle) ; ;timer rate selection ; trate equ 250 ;value for .1 sec ; ;pmmi uart status masks ; p0tbmt equ 1 ;xmit buff empty p0dav equ 2 ;data available p0teoc equ 4 ;test end of char p0rpe equ 8 ;rec'd parity err p0orun equ 10h ;overrun p0ferr equ 20h ;framing error ; ;baud rate divisors ; b110 equ 142 ;110 baud b300 equ 52 ;300 baud b450 equ 35 ;450 baud b600 equ 26 ;600 baud b710 equ 22 ;710 baud ; ; baud rate table ; baud$table: db 208 ;0 no baud ;same as none db 208 ;50 db 208 ;75 db b110 ;110 db 116 ;134.5 db 104 ;150 db b300 ;300 db b600 ;600 db b710 ;1200 wrong data will show in device cmd db b710 ;1800 db b710 ;2400 db b710 ;3600 db b450 ;4800 db b710 ;7200 db b710 ;9600 db b710 ;19.2k ; ; remote system rsx function numbers ; online equ 51 ;return a=1 if not running with modem ; a=2 if modem connected turnoff equ 52 ;disconnect, redirection to modem off ;and remove rsx ;function to call when carrier loss detected remove equ 53 ;remove rsx only ; ; subroutines ; ; ; see if other end is still sending carrier ; process loss or return nz if carrier still present ; testcarrier: in rport ;get modem status cma ;active low ani p2cts ;see if still connected jrz lost$carrier ;carrier lost ori 0ffh ret ;with not zero (ok) ; ; process having lost carrier ; lost$carrier: ; ; select tpa bank - we were probably in bank 0 when carrier loss ; was detected. ; if banked mvi a,1 call ?bnksl endif ; ; remove modem from io redirection vectors ; mvi a,22h + vector$half ;conin call remove$modem mvi a,24h + vector$half ;conout call remove$modem mvi a,26h + vector$half ;auxin call remove$modem mvi a,28h + vector$half ;auxout call remove$modem mvi a,2ah+ vector$half ;lstout call remove$modem ; ; restore jump at zero ; mvi a,0c3h sta 0 ; ; attempt to pass control to rsx ; mvi c,calrsx ;call rsx function lxi d, lost$rsxpb call 5 ; ; normally the rsx won't return but if it does ; jmp 0 ;warmstart ; ; rsx parameter block ; lost$rsxpb: db turnoff ;tell rsx to disconnect db 0 ;no parameters ; ; this will remove the modem device from the io vector ; whose offset in the scb is in A ; remove$modem: mvi c,scb ;set/get scb lxi d,scb$pb stax d ;set offset inx d xra a stax d ;read scb value set type dcx d ;point back to start of block call bdos ani modem$mask ;remove modem from vector sta scb$val ;put in parameter block lxi d,scb$pb + 1 ;point to set type mvi a,0ffh ;set byte value command stax d dcx d ;point back to start of block mvi c,scb call bdos ret ; ; scb parameter table ; scb$pb: ds 1 ;offset scb$set ds 1 ;0=read fe=set word ff=set byte scb$val ds 2 ;value when setting ; ; test if character ready ; ?minst: call testcarrier in tport ;get status ani p0dav rz ;not ready ani 0ffh ret ;ready ; ; get character ; ?min: call ?minst jrz ?min in dport ani 07fh ;strip parity ret ; ; test if character may be sent ; ?moutst: call testcarrier in tport ani p0tbmt rz ani 0ffh ret ; ; send character ; ?mout: call ?moutst jz ?mout mov a,c out dport ret ; ; set baud rate ; ?minit: lda @mbaud ;get dri baud rate number for modem mov e,a mvi d,0 lxi h,baud$table dad d ;point to pmmi divisor mov a,m ;get divisor out rport ret ; ; bdos functions (cp/m 3.0) ; bdos equ 5 sysrst equ 0 ;warmstart rdcon equ 1 ;wait for & read console character wrcon equ 2 ;write to console rdaux equ 3 ;wait for & read aux wraux equ 4 ;write to aux list equ 5 ;write to list device drcon equ 6 ;direct console i/o character or ; ff=read ; fe=status only ; fd=wait for input auxinst equ 7 ;aux in status auxotst equ 8 ;aux out status prstr equ 9 ;de=string rdbuff equ 10 ;de=buffer max, count, c1,c2,... const equ 11 ;console in status getvers equ 12 ;return version in HL dskrst equ 13 ;reset disk system seldsk equ 14 ;select disk 0=a: openf equ 15 ;open file de=fcb closef equ 16 ;close file searchf equ 17 ;search for first occurance searchn equ 18 ;find next occurance delete equ 19 ;delete file read equ 20 ;read sequential write equ 21 ;write sequential make equ 22 ;make file rename equ 23 ;rename file new name at fcb+16 loginv equ 24 ;return login vector in hl curdsk equ 25 ;return current disk in a setdma equ 26 ;set new dma getalv equ 27 ;get allocation vector address wrtprt equ 28 ;write protect current disk rovec equ 29 ;get r/o vector in hl setflag equ 30 ;set file attributes getdpb equ 31 ;return dpb address user equ 32 ;get/set user ff=get readran equ 33 ;read random record writeran equ 34 ;write random record flsize equ 35 ;compute file size setran equ 36 ;set random record from last sequential read rstdrv equ 37 ;reset drive accdrv equ 38 ;mpm only - access drive freedrv equ 39 ;mpm only - free drive wrran0 equ 40 ;fill a random record with 0 tstwrt equ 41 ;mpm only - test and write lock equ 42 ;mpm only - lock record unlock equ 43 ;mpm only - unlock record multi equ 44 ;set multi sector count errmd equ 45 ;set bdos error mode freesp equ 46 ;return free space in 1st 3 bytes of dma chain equ 47 ;chain to pgm name in def buff (80h) flush equ 48 ;flush buffers scb equ 49 ;get set scb de=.scb pb db offset ; db ffh set byte ; feh set word ; 00h get ; dw value drbios equ 50 ;direct bios call de=.bios pb db bios func # ; db = A ; dw =BC ; dw =DE ; dw =HL ldovl equ 59 ;load overlay calrsx equ 60 ;call rsx de=.rsx pb db rsx func # ; db # of word parameters ; dw p1 ; dw p2 frblks equ 98 ;free temporary blocks trunf equ 99 ;truncate file setdirl equ 100 ;set driectory label dirl equ 101 ;return directory label data e=drive rdstamp equ 102 ;read file stamps & password mode wrxfcb equ 103 setdate equ 104 rdtime equ 105 defpwd equ 106 ;set def password retsn equ 107 ;return serial number address retcode equ 108 ;get/set return code conmode equ 109 ;get/set console mode delim equ 110 ;get/set string output delimiter prtblk equ 111 ;print block de = ccb dw=address ; dw=length lstblk equ 112 ;list block parse equ 152 ;parse file name de=pfcb dw=input addr ; dw=fcb addr end