home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
OSBORNE
/
CONSOLE.ASM
< prev
next >
Wrap
Assembly Source File
|
2000-06-30
|
14KB
|
601 lines
;
; ---- MODEM REMOTE CONSOLE PROGRAM ----
; VERSION 1.1
; ----- TRS-80 MODEL III EQUATES -----
; (ORIGINAL)
; (--- VERSION FOR OSBORNE O-1 ---)
; BY BRK
;
; revised by Jim Woolley, FOG Disk Librarian, 11/82
;
;***** MODIFIED by Garry Pribble 02/12/85 *****
;++++++Modified by Steven A. Bland 2/13/85++++++
;
; THIS PROGRAM ATTACHES A REMOTE CONSOLE, TYPICALLY
; THRU A MODEM CHANNEL, IN PARALLEL WITH THE USUAL
; CP/M CONSOLE DEVICE. IN THIS MODE, CHARACTERS TYPED
; ON EITHER CONSOLE ARE ECHOED TO BOTH. THIS ALLOWS
; A REMOTE USER TO CONTROL THE COMPUTER ... TO RUN
; DIAGNOSTICS... OR TO GIVE INSTRUCTION ON HOW TO
; PERFORM CERTAIN OPERATIONS.
;
; THE PROGRAM IS INITIATED BY THE COMMAND:
;
; A>REMOTE
; OR
; A>REMOTE XXXX
; WHERE XXXX IS A HEX MEMORY ADDRESS
;
; IN THE FIRST CASE, THE MODEM DRIVERS WILL BE RELOCATED AND
; COPIED JUST UNDER THE CCP ( OR JUST UNDER WHATEVER PROGRAM
; IS ALREADY PROTECTED UNDER THE CCP ). IN THIS MODE, WARM BOOTS
; ARE DISABLED. IN THE SECOND CASE, WHEN A HEX MEMORY ADDRESS
; IS SPECIFIED, THE MODEM DRIVERS ARE RELOCATED AND COPIED TO THIS
; ADDRESS (ASSUMED TO BE "ABOVE" THE BIOS).
;
; THE DRIVERS MAY BE DETACHED BY RUNNING THE PROGRAM AGAIN. IT WILL
; LOAD AND IF IT FINDS MODEM DRIVERS ALREADY ATTACHED, IT WILL ASK
; IF YOU WANT THEM DISCONNECTED.
;
; ---- CP/M EQUATES ----
;
BDOS EQU 5 ; FUNCTION CALL ENTRY POINT
FCB EQU 5CH ; DEFAULT FCB LOCATION
CDISC EQU 4 ; BUFFER FOR LOGGED ON DRIVE #
CHOUT EQU 2 ; BDOS COMMAND FOR CONSOLE OUTPUT
LST EQU 9 ; BDOS COMMAND TO PRINT A STRING
DIO EQU 6 ; BDOS COMMAND FOR DIRECT I/O ( CP/M 2.X )
;
CR EQU 0DH ; CARRIAGE RETURN
LF EQU 0AH ; LINE FEED
;
;
ORG 100H
;
JMP START ; JUMP OVER MSG
DB 'REMOTE CONSOLE PGM V1.1, (C) 1982 BY BRK',1AH
;
START: POP H ; GET RETURN ADDRESS FROM STACK
LXI SP,STACK ; SET NEW STACK
PUSH H ; PUT RETURN ADDRESS ON NEW STACK
;
LXI D,STMSG ; POINT TO STARTUP MESSAGE
CALL PTMSG ; ANNOUNCE PRESENCE
;
XRA A
STA ABOVE ; INIT ABOVE FLAG TO "BELOW" STATUS
;
LHLD 1 ; GET POINTER TO BIOS+3
SHLD BIOS3 ; SET INTO PROGRAM MODULE
LXI D,-1600H
DAD D ; COMPUTE ADDRESS OF CCP+3 (CP/M 2.X)
SHLD CCP3 ; SAVE IN PROGRAM MODULE
LXI D,1621H ; OFFSET TO BIOS SETDMA LOCATION
DAD D
SHLD STDMA ; SET IN PROGRAM MODULE
;
LHLD 6
SHLD BDJ+1 ; SAVE BDOS ENTRY ADDRESS
;
LHLD 1
LXI D,4
DAD D ; POINT TO BIOS+7
MOV E,M ; GET ADDRESS OF CONSOLE STATUS ROUTINE
INX H
MOV D,M
XCHG
LXI D,-10 ; LENGTH OF POSSIBLE TEST STRING+POINTER
DAD D ; POINT TO POSSIBLE START OF STRING
LXI D,TMSG ; POINT TO TEST STRING
MVI C,8 ; SET COMPARISON LENGTH
CALL COMPARE ; COMPARE THEM
SHLD CDPTR ; SAVE POSSIBLE POINTER
JNZ INSTALL ; IF NOT EQUAL, ASSUME NO MODEM DRIVER IS
; ; ATTACHED ALREADY
LXI D,ALMSG ; IF DRIVER IS ATTACHED, ASK TO DETACH
CALL PTMSG
CALL YES
RNZ ; IF "NO", JUST RETURN
;
LXI D,DTMSG
CALL PTMSG ; NOTIFY OF DETACHMENT
;
LHLD CDPTR
CALL GTDE ; GET POINTER TO OLD JUMP TABLE IN MODULE
LHLD 1 ; GET POINTER TO STD JUMP TABLE
XCHG
LXI B,12 ; LENGTH OF TABLE
CALL MOVE ; DETACH MODULE
JMP EXIT ; DO WARM BOOT TO RE-INIT BASE PAGE JUMPS
;
INSTALL: LXI H,FCB+1 ; POINT TO STD CP/M FCB LOCATION
SHLD CHPTR ; SAVE FOR HEX ROUTINE
MOV A,M ; GET FIRST CHAR.
CALL THEX ; CHECK IF VALID HEX #
JC BELOW ; IF NOT, PUT MODULE "BELOW"
CALL GTHEX ; IF VALID, TRY TO EXTRACT HEX NUMBER
SHLD LDADDR ; SAVE IT
MVI A,1
STA ABOVE ; SET ABOVE MODE
JC INST1 ; IF GOOD HEX VALUE
LXI D,EMSG1
JMP EXMG ; EXIT WITH ERROR MESSAGE
;
INST1: PUSH H
LHLD 1 ; GET BIOS+3
LXI D,40H ; ASSUME JUMP TABLE AT LEAST
DAD D
POP D
CALL COMPDE ; IS # REALLY ABOVE THE BIOS
JC INSTA ; IF IT LOOKS OK
;
LXI D,EMSG2
JMP EXMG ; " ABOVE ADDRESS IS TOO SMALL"
; AND EXIT BACK TO CP/M
;
BELOW: LHLD CCP3 ; GET ADDRESS OF CCP+3
XCHG
LHLD BDOS+1 ; GET BDOS ENTRY JUMP ADDRESS
CALL COMPDE ; COMPARE THEM
JC INST2 ; IF CCP+3>BDOS ENTRY
XCHG
INST2: LXI D,-LENC-10
DAD D ; ALLOW ROOM BELOW FOR CODE
MVI L,6 ; MAKE START ADDRESS LIKE BDOS ENTRY
SHLD LDADDR ; SAVE ADDRESS TO COPY MODULE TO
;
INSTA: LHLD 1 ; POINT TO PART OF BIOS JUMP TABLE
LXI D,OWBOOT ; POINT TO DESTINATION IN MODULE
LXI B,12 ; LENGTH OF TABLE
CALL MOVE ; COPY INTO MODULE
;
LXI D,BDJ ; POINT TO START OF MODULE
LHLD LDADDR ; POINT TO CODE DESTINATION
CALL SUBDE
SHLD OFFSET ; SAVE RELOCATION OFFSET
CALL RELOC ; RELOCATE CODE IN MODULE
;
LHLD LDADDR ; SET DESTINATION ADDRESS
XCHG
LXI H,BDJ ; SET SOURCE ADDRESS
LXI B,LENC+1; SET LENGTH OF CODE IN MODULE
CALL MOVE ; COPY MODULE TO DESTINATION
;
LHLD 1
XCHG ; GET BIOS+3 IN (D,E)
;
LXI H,NWBOOT ; POINT TO NEW JUMP TABLE
LXI B,12 ; LENGTH OF TABLE
LDA ABOVE
ORA A ; TEST IF "ABOVE" MODE
JZ INST3 ; NO, SO DO MOVE
INX D ; YES, SO DO NOT COPY OVER WARM BOOT JUMP
INX D
INX D
LXI H,NWBOOT+3
LXI B,9
INST3: CALL MOVE ; LINK IN MODULE BY SWITCHING IN JUMP TABLE
; CALL MXINIT ; INIT REMOTE DRIVERS deleted, jw
LXI D,ATMSG
CALL PTMSG
LHLD LDADDR ; GET LOAD ADDRESS
CALL HEXW ; PRINT IT OUT
LXI D,ATMSG1
JMP EXMG ; LET WARM BOOT CORRECT BASE PAGE JUMPS
;
; ------ SUBROUTINES ------
;
; --- COMPARE STRINGS AT (H,L) AND (D,E) FOR (C) BYTES ---
;
COMPARE: LDAX D
CMP M
RNZ ; IF NO MATCH
INX H
INX D
DCR C ; COUNT DOWN
JNZ COMPARE ; LOOP UNTIL ERROR OR DONE
RET
;
; --- COMPARE (H,L) & (D,E) BY SUBTRACTION (H,L)-(D,E) ---
;
COMPDE: MOV A,L
SUB E
MOV A,H
SBB D
RET
;
; --- SUBTRACT: (H,L)=(H,L)-(D,E) ---
;
SUBDE: MOV A,L
SUB E
MOV L,A
MOV A,H
SBB D
MOV H,A
RET
;
; --- COPY CODE FROM (H,L) TO (D,E) FOR (B,C) BYTES ---
;
MOVE: MOV A,M
STAX D
INX H
INX D
DCX B
MOV A,B
ORA C
JNZ MOVE
RET
;
; --- TEST & CONVERT CHAR. IF VALID HEX # ---
;
THEX: SUI '0' ; REMOVE ASCII BIAS
RC ; IF ERROR
CPI 'G'-'0'
CMC
RC ; IF ERROR
CPI 10 ; IS IT 0-9?
CMC
RNC ; YES, SO RETURN
SUI 7
CPI 10 ; IF NOT A-F, SET CARRY
RET
;
; --- GET 16 BIT WORD POINTED TO BY (H,L) INTO (D,E) ---
;
GTDE: MOV E,M
INX H
MOV D,M
INX H
RET
;
; --- PUT 16 BIT WORD FROM (D,E) INTO MEMORY AT (H,L) ---
;
PTDE: MOV M,E
INX H
MOV M,D
INX H
RET
;
;
; --- HEX INPUT ROUTINE ----
;
GTHEX: LXI H,0 ; CLEAR CONVERSION REGISTER
H1: CALL GTCHR ; GET CHAR.
CPI CR ; IS IT A CR
RZ ; YES, SO RETURN
HEX2: CALL THEX ; TEST CHAR. AND REMOVE ASCII BIAS
RC ; IF ERROR
HEX1: DAD H ; SHIFT 16 BIT REGISTER OVER 4 PLACES
DAD H
DAD H
DAD H
ADD L ; ADD IN NEW NIBBLE
MOV L,A
JMP H1
;
GTCHR: PUSH H
LHLD CHPTR ; POINT TO CHAR.
MOV A,M ; GET IT
INX H
SHLD CHPTR ; POINT TO NEXT ONE
POP H
RET
;
; --- OUTPUT BYTE IN ACC IN HEX ---
;
HEXOT: PUSH PSW ; SAVE BYTE
RRC ; SHIFT UPPER NIBBLE DOWN
RRC
RRC
RRC
CALL HEXB ; OUTPUT UPPER NIBBLE IN HEX
POP PSW ; GET BYTE BACK
HEXB: ANI 0FH ; MASK OFF UPPER NIBBLE
ADI '0' ; ADD ASCII BIAS
CPI '9'+1 ; TEST IF NUMERIC
JC PRT ; YES, SO DO IT
ADI 7 ; NO, SO ADD BIAS FOR A-F
PRT: MOV C,A ; SETUP FOR OUTPUT
COUT: PUSH PSW
PUSH H ; BUFFERED CONSOLE OUTPUT
PUSH D
PUSH B
MOV E,C
MVI C,CHOUT ; BDOS CHAR. OUTPUT COMMAND
CALL BDOS
POP B
POP D
POP H
POP PSW
RET
;
; --- OUTPUT (H,L) IN HEX ---
;
HEXW: PUSH H
MOV A,H
CALL HEXOT ; PRINT OUT UPPER BYTE
POP H
MOV A,L
JMP HEXOT ; PRINT OUT LOWER BYTE
;
; --- PRINT STRING POINTED TO BY (D,E) ---
;
PTMSG: MVI C,LST
JMP BDOS
;
;
; -- YES FUNCTION --
;
YES: CALL CONNC ; GET CONSOLE CHAR.
CPI 'Y' ; IS IT A Y?
JZ YES1
CPI 'N' ; IS IT A N?
JNZ YES ; IF NEITHER, KEEP TRYING
INR A ; SET N STATUS
YES1: PUSH PSW ; SAVE FLAGS
CALL COUT ; OUTPUT TO CONSOLE
POP PSW ; RESTORE FLAGS
RET
CONNC: CALL CONIN ; GET CHAR. FROM CONSOLE
MOV C,A ; SAVE FOR ECHO
CPI 60H ; IS IT LOWER CASE?
JC CON1 ; NO, SO CONTINUE
ANI 5FH ; YES, SO MASK TO UPPER CASE
CON1: CPI 'C'-40H ; IS IT A CONTROL-C?
RNZ ; NO, SO RETURN
CTC: LXI D,CMSG ; POINT TO CONTROL-C MESSAGE
EXMG: CALL PTMSG ; ISSUE MESSAGE
EXIT: LXI D,CRLF
CALL PTMSG ; ISSUE A CRLF
JMP 0
;
CONIN: MVI E,0FFH
MVI C,DIO
CALL BDOS
ORA A
JZ CONIN
RET
;
; --- RELOCATE ADDRESSES POINTED TO BY ADDRESS TABLE ---
;
RELOC: LXI H,RELTAB ; POINT TO ADDRESS TABLE
REL1: CALL GTDE ; GET POINTER INTO (D,E)
MOV A,D
ORA E ; TEST IF ADDRESS IS ZERO
RZ ; RETURN (DONE) IF IT IS
PUSH H ; SAVE TABLE POINTER
XCHG ; GET ADDRESS INTO (H,L)
PUSH H ; SAVE POINTER
CALL GTDE ; GET REFERENCED ADDRESS WORD
LHLD OFFSET ; GET OFFSET
DAD D ; COMPUTE RELOCATED ADDRESS
XCHG
POP H
CALL PTDE ; UPDATE ADDRESS WORD IN CODE
POP H ; GET TABLE ADDRESS POINTER BACK
JMP REL1 ; LOOP UNTIL DONE
;
; --- RELOCATION ADDRESS TABLE ---
;
RELTAB EQU $
DW NWBOOT+1
DW NWBOOT+4
DW NWBOOT+7
DW NWBOOT+10
DW PTX00
DW PTX0+1
DW MCNST+1
DW MCNIN+1
DW PTX1+1
DW PTX2+1
DW PTX3+1
DW PTX4+1
DW PTX41+1
DW PTX5+1
DW PTX6+1
DW PTX7+1
DW DVX1+1
DW MXIN+1
DW DVX2+1
DW DVX3+1
DW DVX4+1
DW 0 ; TABLE TERMINATOR
;
; --- MESSAGES -----
;
STMSG: DB CR,LF
DB CR,LF,' --- REMOTE CONSOLE ATTACHMENT PROGRAM ---'
DB CR,LF,' VERS. 1.2'
DB CR,LF,' FOR TRS-80 III RS-232 PORT'
DB CR,LF,' by BRK (TRS-80 3 by Garry Pribble and)'
DB CR,LF,' Steven A. Bland'
DB CR,LF,'$'
;
ALMSG: DB CR,LF,07,' REMOTE CONSOLE IS ALREADY ATTACHED'
DB CR,LF,' ----------------> DETACH IT (Y/N) ?$'
;
DTMSG: DB CR,LF
DB CR,LF,' --> REMOTE CONSOLE DRIVERS ARE DETACHED !!'
CRLF: DB CR,LF,'$'
;
EMSG1: DB CR,LF,07,' *** INVALID "ABOVE" ADDRESS SPECIFIED ***'
DB CR,LF,'$'
;
EMSG2: DB CR,LF,07,' *** "ABOVE" ADDRESS IS TOO SMALL ***'
DB CR,LF,'$'
;
ATMSG: DB CR,LF,' --- REMOTE CONSOLE DRIVERS ATTACHED AT $'
;
ATMSG1: DB 'H ---',CR,LF,'$'
;
CMSG: DB ' ^C',CR,LF,'$'
;
; --- BUFFERS ---
;
CHPTR: DS 2 ; BUFFER POINTER FOR HEXIN ROUTINE
LDADDR: DS 2 ; BUFFER FOR SAVING DRIVER LOAD ADDRESS
OFFSET: DS 2 ; BUFFER FOR SAVING ADDRESS OFFSET
CDPTR: DS 2 ; BUFFER FOR POINTER TO JUMP TABLE IN DRIVER
ABOVE: DS 1 ; FLAG FOR "ABOVE" OR "BELOW" MODE
;
; ---------------------------------------------------------------
; ---- REMOTE CONSOLE DRIVERS ----
;
; THIS SECTION GETS RELOCATED AND COPIED UP TO THE "TOP"
; OF AVAILABLE MEMORY. ANY ADDRESSES IN THIS CODE THAT
; NEED RELOCATION MUST BE REFERENCED IN THE RELOCATION TABLE.
;
BDJ: JMP $-$ ; THIS GETS PATCHED
;
; --- COPY OF ORIGINAL CP/M JUMP TABLE
;
OWBOOT: JMP $-$ ; COPY OF OLD WARM BOOT
OCNST: JMP $-$
OCNIN: JMP $-$
OCNOUT: JMP $-$
;
; --- NEW JUMP TABLE TO BE COPIED INTO CP/M JUMP TABLE ---
;
NWBOOT: JMP WBOOT
NCNST: JMP MCNST
JMP MCNIN
JMP MCNOUT
;
; --- FAKE WARM BOOT ROUTINE USED IN "BELOW" MODE ---
;
WBOOT: LXI SP,0FFH
MVI A,(JMP)
STA 0 ; SET JUMP OPCODE AT 0000H
BIOS3 EQU $+1
LXI H,$-$
SHLD 1 ; SET BIOS+3 WARM BOOT ADDRESS
STA 5
PTX0: LXI H,BDJ
SHLD 6
LXI B,80H ; SET DEFAULT DMA ADDRESS
STDMA EQU $+1
CALL $-$
LDA CDISC ; GET DEFAULT DRIVE #
MOV C,A
CCP3 EQU $+1
JMP $-$ ; RE-ENTER CCP AT CCP+3
;
; THE FOLLOWING 10 BYTES MUST NOT BE CHANGED OR MOVED
;
TMSG: DB 'REMOTE C' ; IDENTIFIER STRING
PTX00: DW OWBOOT ; POINT TO SAVED OLD JUMP TABLE
;
; --- NEW CONSOLE STATUS ROUTINE ---
;
MCNST: CALL OCNST ; SEE IF STD CONSOLE HAS A CHAR.
ORA A
RNZ ; RETURN IF IT DOES
PTX1: JMP MXISTAT ; OTHERWISE, CHECK MODEM DRIVER
;
; --- NEW CONSOLE INPUT ROUTINE ---
;
MCNIN: CALL OCNST ; IS CHAR. AVAIL. FROM STD CONSOLE?
ORA A
PTX2: JNZ OCNIN ; YES, SO GO GET IT
PTX3: CALL MXISTAT ; NO, SO TRY MODEM
ORA A
PTX4: JZ MCNIN ; IF NO CHAR., KEEP LOOKING
PTX41: CALL MXIN ; GET CHAR.
ORA A ; IS IT A NULL?
PTX5: JZ MCNIN ; YES, IGNORE IT
ANI 7FH ; MASK PARITY
RET
;
; --- NEW CONSOLE OUTPUT ROUTINE ---
;
MCNOUT: PUSH B ; SAVE OUTPUT CHAR.
PTX6: CALL OCNOUT ; SEND IT TO STD CONSOLE
POP B
PTX7: JMP MXOUT ; SEND IT TO REMOTE CONSOLE ALSO
;
; ----- HARDWARE DEPENDENT I/O DRIVER ----
; -------------------------------------
; THE ORIGINAL VERSION FOR THE OSBORNE
; IS COMPLICATED BY A DESIGN FLAW
; IN THE RS232 PORT HARDWARE. WHEN
; NO CONNECTIONS ARE MADE, UART IS
; BEING GIVEN NULLS.
; -------------------------------------
;
MODCTLP EQU 00EAH ;PUT YOUR MODEM CONTROL PORT HERE
MODSNDB EQU 40H ;YOUR BIT TO TEST FOR SEND
MODSNDR EQU 40H ;YOUR VALUE WHEN READY
MODRCVB EQU 80H ;YOUR BIT TO TEST FOR RECEIVE
MODRCVR EQU 80H ;YOUR VALUE WHEN READY
MODDATP EQU 00EBH ;YOUR MODEM DATA PORT
; these are setup for TRS-80 III serial WD TR1602 UART+ (G.P. & S.B.)
; Running Under Holmes Engineering VID-80 (tm)(c) CP/M 2.22J
;
; --- ALL OF THE MODEM ROUTINES MAY ONLY CHANGE ---
; THE A-REGISTER AND THE FLAGS. NO OTHER
; REGISTERS MAY BE CHANGED.
;
; --- INPUT DATA FROM MODEM ---
;
MXIN: LXI H,CHRSAV ; POINT TO CHAR. BUFFER
MOV A,M ; GET CHAR.
MVI M,0 ; INDICATE CHAR. RECEIVED
RET
;
; --- OUTPUT DATA TO MODEM ---
;
MXOUT DI
IN MODCTLP
EI
ANI MODSNDB
CPI MODSNDR
DVX1: JNZ MXOUT
MOV A,C
DI
OUT MODDATP
EI
RET
;
; --- TEST IF DATA IS AVAILABLE FROM MODEM ---
;
;
MXISTAT: DI
IN MODCTLP
EI
ANI MODRCVB
CPI MODRCVR
;
DVX2: LDA CHRSAV ; GET POSSIBLE SAVE CHAR.
DVX3: JNZ MXI1 ; IF NO CHAR., TEST BUFFER FOR ONE
;
DI ; IF CHAR., GET IT
IN MODDATP ; GET DATA
EI
;
DVX4: STA CHRSAV ; SAVE IT
MXI1: ORA A ; WAS IT A NULL?
RZ ; YES, SO RETURN NOT READY STATUS
MVI A,0FFH ; SET READY STATUS
RET
;
CHRSAV: DB 0 ; BUFFER FOR ONE CHAR.
;
; --- INIT MODEM ROUTINES (NOT HARDWARE) ---
; THIS ROUTINE NEED NOT PRESERVE ANY
; OF THE REGISTERS.
;
;MXINIT EQU $ ;deleted following code, jw
;
; MVI C,56H ; USE 56H FOR 300 BAUD, 55H FOR 1200
; LHLD 1
; MVI L,3CH ; SETUP SPECIAL OSBORNE JUMP
; PCHL
;
LENC EQU $-BDJ ; LENGTH OF CODE MODULE TO COPY UP
; ------------------------------------------------------
;
DS 80
STACK EQU $
END