;HOST.ASM REMOTE ACCESS DRIVER for CP/M 2.x computers. ;10/09/89 ;Roy Lipscomb [] Uses low memory only; uses no TPA (program) space. ; ; [] Needs no customization or reassembly for different ; brands of computer. (Manipulates CP/M's iobyte, ; instead of directly addressing the serial port.) ; ; [] For help, type HOST and press return. ; ; (Based on 2CON.ASM, a generic dual-console program by the same author.) ; ; ***************************************************************************** * * * Copyright 1989, Logic Associates, 1433 W. Thome, Chicago, IL 60660 * * (312) 274-0531. (Contact us about our other packages for CP/M.) * * * * Permission is granted to distribute free copies of the HOST package. * * All other rights are reserved. * * * * HOST package includes-- * * * * HOST.ASM * * HOST.DOC * * HOST.COM * * HOSTTEST.SUB * * PASSWORD.ASM * * PASSWORD.DOC * * PASSWORD.COM * * 2CON.ASM * * * * (We are interested in your comments and suggestions about this program.) * * * ***************************************************************************** ; org 100h jmp start exit: jmp boot ;---------------------------------------------------------------- cr equ 0dh lf equ 0ah mlogon db ' HOST Copyright 1989 Logic Associates, Chicago',cr,lf db ' Active consoles: Local = ' mloc1: db '...' db ' Remote = ' mrem1: db '---',cr,lf,cr,lf,'$' mpoll db '--> WAITING for input from any device... <--',cr,lf,'$' mok db '--> ' mrem2: db '... ATTACHED as remote console. <--',cr,lf mok2 db ' $' moff db '--> ' mrem3: db '... DETACHED; HOST removed. <--',cr,lf,'$' minvcon db 7,'--> No action: ' mrem4: db '... device already active. <--',cr,lf,'$' mnoon: db 7,'--> No action: HOST already active. <--',cr,lf,'$' mnooff db 7,'--> No action: HOST not active. <--',cr,lf,'$' mbadopt db 7,'--> No action: Invalid option. <--',cr,lf,'$' mabort db 7,'--> ABORTED: Character was from local console. <--',cr,lf,'$' mhelp: db 'HOST makes your system accessible to a remote terminal,' db cr,lf,'by "attaching" one of the four console devices of CP/M.' db cr,lf db cr,lf,' OPTION: ACTION:' db cr,lf,'--------- ----------------------------------------' db cr,lf,'HOST Show active consoles and help screen.' db cr,lf,'HOST TTY Attach the "Teletype" device.' db cr,lf,'HOST CRT Attach the "Video" device.' db cr,lf,'HOST BAT Attach the "Batch" device.' db cr,lf,'HOST UC1 Attach the "User Console 1" device.' db cr,lf,'HOST AUTO Attach first device that sends a char.' db cr,lf,'HOST OFF Remove HOST.' db cr,lf db cr,lf,'Notes: 1. HOST will not configure the serial port.' db cr,lf,' 2. If attaching a wrong device hangs your' db cr,lf,' system: Press reset, reinitialize the' db cr,lf,' port, and try a different device.' db cr,lf,' 3. Designed for any CP/M 2.x system that--' db cr,lf,' a. Implements the I/O byte feature, and' db cr,lf,' b. Does not use low memory, 8H to 37H.' db '$' tty equ 0 crt equ 1 bat equ 2 uc1 equ 3 aut equ 4 off equ 5 help equ 6 FALSE equ 0 TRUE equ 1 ;---------------------------------------------------------------- ; customization variables ; ;---------------------------------------------------------------- ;Changing this value MAY POSSIBLY allow running with CP/M+. iobyte equ 3 ;address of iobyte. ;Do not change if using CP/M 2.x. ;Nothing below this point needs customization. ;---------------------------------------------------------------- ; constants ; ;---------------------------------------------------------------- boot equ 0 ;warm boot vector. bdos equ 5 ;bdos jump vector. base equ 8 ;load point for resident portion ; of this module. fcb equ 5ch ;default fcb area. diriof equ 6 ;BDOS direct-console-out function. printf equ 9 ;BDOS display-string function. constat equ 06h ;displacement from BIOS start. conin equ 09h ;displacement from BIOS start. conout equ 0ch ;displacement from BIOS start. rst1 equ 0cfh ;restart 1 instruction. poph equ 0e1h ;POP H instruction. fcbparm db false ;request to turn HOST "OFF"? remtrap db true ;get remote's code from installed trap? remote equ 0 ;(initial value is arbitrary.) contab: db tty,'TTY ' db crt,'CRT ' db bat,'BAT ' db uc1,'UC1 ' db aut,'AUTO' db off,'OFF ' db help,' ' numopt equ ($-contab)/5 badparm equ 255 ;---------------------------------------------------------------- ; installation routines ; ;---------------------------------------------------------------- start: call hskp ;do housekeeping lda isiton ;is HOST active? cpi true jnz start4 ; no, skip ;HOST active. call insrem ;insert remote device into messages. call dologon ;display logon message lda fcbparm cpi badparm ;is requested option invalid? lxi d,mbadopt jz startx ; yes, exit with message. cpi help ;asking for help? lxi d,mhelp jz startx ; yes, display help. cpi off ;asking for turn off? cz dooff ; yes, do it and exit. jz startx lxi d,mnoon ;say "error: already active". jmp startx ;HOST not active start4: call dologon ;display logon message call testcc ;requested remote equals local? jz startw ; yes, exit. lda fcbparm cpi badparm ;is requested option invalid? lxi d,mbadopt jz startx ; yes, exit with message. cpi help ;asking for help? lxi d,mhelp jz startx ; yes, display help. cpi off ;asking for removal? lxi d,mnooff jz startx ; yes, error: "not loaded." call load ;load HOST: move trap into place, call patchin ; active it. lda fcbparm cpi aut ;asking for auto? jnz startw ; no, skip call doauto ;select device by polling. lxi d,mok ;aborted? jnz startw ; no: skip call dooff ; yes: remove it, lxi d,mabort ; set "abort" message, jmp startx ; skip. startw: call insrem ;insert remote device into messages. startx: call printd ;display result message. (also goes ; to 2nd console if HOST active.) ;exit to system. jmp exit ;---------------------------------------------------------------- ;get/set iobyte getiob: lda iobyte ret setiob: sta iobyte ret ;---------------------------------------------------------------- ;print message whose address is in de. printd: mvi c,printf call bdos ret ;---------------------------------------------------------------- ;do housekeeping hskp: ;store parm, if any, from command line call getparm ;set isiton flag if HOST is already active. call testact ;initialize flag telling where to get remote name for messages. mvi a,true sta remtrap ;store original value of I/O byte console value into trap. call getiob ;get actual iobyte ani 3 mov b,a lda isiton ;is HOST active? cpi true jnz hskp4 ; no, use actual iobyte. lda local+base ; yes, get original iobyte from trap. mov b,a hskp4: mov a,b sta local+adjust ;save pointer to bios start-page. lhld boot+1 mov a,h sta biospag+adjust ;insert local console device into messages. lda local+adjust lxi d,mloc1 call minsert ret ;---------------------------------------------------------------- ;insert remote device name into messages. Get it from active trap. insrem: push d ;save result message. lda fcbparm ;get code of proposed remote, mov b,a ; save it. lda remtrap ;get actual remote, from trap? cpi true jnz insrem4 ; no, use proposed remote. lda local+base ;get local device code, lxi h,flipio2+base+1 ; point to "local XRI remote", xra m ; convert "local" to "remote", mov b,a ; save in b. insrem4: mov a,b ;copy remote code. push psw lxi d,mrem1 call minsert pop psw push psw lxi d,mrem2 call minsert pop psw push psw lxi d,mrem3 call minsert pop psw push psw lxi d,mrem4 call minsert pop psw pop d ;restore result message. xra a ;set flag. ret ;---------------------------------------------------------------- ;get command-line parameter (if any). getparm: lda fcb+1 ;get first byte of parm. lxi h,contab-4 mvi b,numopt getpr2: inx h inx h inx h inx h mov c,m inx h cmp m jz getpr6 dcr b jnz getpr2 mvi c,badparm getpr6: mov a,c sta fcbparm ret ;---------------------------------------------------------------- ;is current console the requested remote? testcc: lxi d,minvcon ;(set errmsg, just in case.) lda local+adjust lxi h,fcbparm cmp m ;proposed remote = local? jnz testccx ; no, skip mvi a,false sta remtrap ; yes, set remote-code retrieval. testccx: ret ;if "yes," returns z = 0. ;---------------------------------------------------------------- ;Is 2con already installed and active? testact: ;initialize test flag to say "2con2 not active." mvi a,false sta isiton ;compare if code in low memory matches. lxi d,trap+adjust lxi h,base mvi b,complen call compare ;same code? jnz testacx ; no, not active: exit. ;save original commands at start of trap. lhld base push h lhld base+2 push h ;patch in the call to the test routine. mvi a,poph sta base mvi a,jmp sta base+1 lxi h,teston shld base+2 ;output anything to the console. mvi e,0 mvi c,diriof call bdos ;restore original commands at start of trap. pop h shld base+2 pop h shld base testacx: ret ;............................................................... ;set flag if 2con already active. teston: mvi a,true sta isiton ret isiton: db false ;if turned to true, trap is active. ;............................................................... ;compare (hl) to (de) for length b compare: ldax d cmp m jnz comparx inx d inx h dcr b jnz compare comparx: ret ;if match, z = 0. ;---------------------------------------------------------------- ;move traps into place. (Uses bytes 8 through 37h. Doesn't interfere ;with DDT jump vector at 38h.) load: lxi h,trap+adjust lxi d,base mvi b,tlength call move xra a ;initialize trap's XRI command. sta flipio2+base+1 ;(use neutral (deactivated) value.) lda fcbparm cpi aut ;"auto" parm on command line? jz loadx ; yes, skip. lxi h,local+adjust ; no, set up swap-device xra m ; command in trap. sta flipio2+base+1 loadx: ret ;............................................................... ;move (hl) to (de) for length b move: mov a,m stax d inx d inx h dcr b jnz move ret ;---------------------------------------------------------------- ;activate trap by installing interrupts into BIOS jump table. patchin: lda biospag+base mov h,a push h mvi a,conout lxi b,cotrapx+base lxi d,cotrap+base call patch pop h push h mvi a,constat lxi b,cstrapx+base lxi d,cstrap+base call patch pop h mvi a,conin lxi b,citrapx+base lxi d,citrap+base call patch lxi d,mok ;set result message to "ok." ret ;---------------------------------------------------------------- ;patch bios vector and corresponding trap vector. patch: push b mov l,a inx h mov c,m ;save lo byte of contents, mov m,e ; change lo byte to trap addr lo. inx h mov b,m ;save hi byte of contents, mov m,d ; change hi byte to trap addr hi. pop h ;<--was pushed as b. inx h mov m,c ;put bios-routine addr into trap. inx h mov m,b ret ;---------------------------------------------------------------- ;auto: poll devices until char ready on one. doauto: mvi a,pchl ;turn off second console in trap. sta trapoff+base ; portion of trap. lxi d,mpoll ;say "polling..." call printd doauto2: call getiob ;get iobyte, mov b,a ; save it. inr a ;step to next console device. ani 3 ;strip all but console device. mov c,a mov a,b ;insert new console device ani 0fch ; into iobyte, and save iobyte. ora c call setiob mvi e,0ffh mvi c,diriof ; get input status of device. call bdos ora a ;char ready? jz doauto2 ; no, loop and try again. sta mok2 ;save char for later output. call getiob ani 3 lxi h,local+base ;compute and insert new ani 3 xra m ; flip-console command into trap. sta flipio2+base+1 ;(if zero, no harm done.) push psw mvi a,poph ;turn on second console in trap. sta trapoff+base ; portion of trap. pop psw ret ;if a=0, char was from local console: ; this means user requested "abort." ;---------------------------------------------------------------- ;remove 2con. dooff: mvi a,constat lxi h,cstrapx+base call toff mvi a,conin lxi h,citrapx+base call toff mvi a,conout lxi h,cotrapx+base call toff lxi h,local+base lda iobyte ani 0fch ora m sta iobyte lxi d,moff ;set to say "removed." xra a ret ;..................................................... toff: inx h mov c,m ;get addr of bios routine. inx h mov b,m mov l,a ;get addr of bios vector contents. lda biospag+base mov h,a inx h mov m,c ;restore addr of bios routine into vector. inx h mov m,b ret ;----------------------------------------------------; ; Update, display logon message. ; ;----------------------------------------------------; dologon: lxi d,mlogon call printd ret ;.................................................... ;insert notification of console settings into logon msg. minsert: lxi h,contab-4 mvi b,numopt+1 minser2: dcr b jz minserx inx h ;skip previous value inx h inx h inx h cmp m inx h jnz minser2 mvi c,3 minser4: mov a,m stax d inx h inx d dcr c jnz minser4 minserx: ret ;**************************************************** ; co-resident routine * ;**************************************************** adjust equ $ ;----------------------------------------------------; ; Modified jump-table for console. ; ;----------------------------------------------------; trap equ $-adjust pop h ;get address of jump-to-BIOS-routine. trapoff equ $-adjust ;(changed to "ret" during doauto routine.) push b ;save possible out-byte in c. push h ;save addr of jump-to-BIOS-routine. call dobios+base ;do the BIOS function. pop h pop b mov b,a ;save result (if any) mov a,l cpi cstrap+base ;constat function? mov a,b rc ; no, conin function: return. jnz flipio+base ; no, conout function: continue. ora a ; yes: char ready? rnz ; true, return. ;----------------------------------------------------; complen equ $-adjust ;end of code to compare during ; test of whether 2con2 is active. ;---------------------------------------------------- ;perform same function, using other console. flipio equ $-adjust ;toggle the I/O byte. lxi d,iobyte ldax d flipio2 equ $-adjust XRI local xor remote ; <-value set at run time. stax d ;----------------------------------------------------; ;perform the bios function pointed to by hl. dobios equ $-adjust pchl ;=======================================================; ; trap save areas ; ;=======================================================; biospag equ $-adjust ;save area for bios-start page. db $-$ local equ $-adjust db $-$ ;savearea for original I/O byte ; console value. ;=======================================================; ; trap entry points ; ;=======================================================; citrap equ $-adjust ;from bos conin vector. rst 6 ;be sure char is ready. ora a jz citrap+base rst 1 ; citrapx equ $-adjust jmp $-$ ;to bios conin routine. ;----------------------------------------------------; ;this vector must be at RST 6 location, addr 30h. IF ( (adjust-base+30h) - $ ) shr 15 | | Problem detected during testing of revisions to code: --> End of "citrap" overlays start of next routine. | db $-1-adjust+base ! <--Last-byte addr of "citrap". db 30H ! <--First-byte addr of next routine. | | ENDIF org adjust-base+30h cstrap equ $-adjust ;from bios constat vector. rst 1 cstrapx equ $-adjust jmp $-$ ;to bios constat routine. ;----------------------------------------------------; cotrap equ $-adjust ;from bios conout vector. rst 1 cotrapx equ $-adjust jmp $-$ ;to bios conout routine. ;-------------------------------------------------------; ; end of trap routine ; ;-------------------------------------------------------; tlength equ $-adjust IF (37h - (base - 1) - tlength) shr 15 | | Problem detected during testing of revisions to code: --> Trap routine too long for allowed space: | db tlength ! <--Length of trap routine. db base+tlength-1 ! <--Addr of last byte of trap. db 37h ! <--Last allowable addr for that byte. ;dw 37h - (base - 1) - tlength ! <--Should be "FFFx" ;dw (37h - (base - 1) - tlength) shr 15 ! <--Should be "1" | | ENDIF end