; DVRPATCH.ASM ver 1.0 ; by Keith Petersen, W8SDZ ; (revised 3/14/81) ; ;This program moves alternate console and list ;drivers into high memory and then patches CP/M ;to use them instead of the regular CBIOS routines. ;The patches will remain intact until the next ;cold boot. ; ;Why this is useful: if your console and/or list ;drivers are too long to fit into your CBIOS, this ;program can be used to patch them in after CP/M is ;booted. Another use might be when some special ;drivers are temporarily needed, such as allowing ;a modem port to be patched in so it is the console ;or the list device. ; ;------------------------------------------------ ;Change the following equate to an area in your high ;memory where the alternate console and list drivers ;may be located without interference to or from CP/M. ; DEST EQU 0FB80H ;RUNNING LOCATION OF CODE ; ;------------------------------------------------ ; ;Define I/O ports and status bits ; CRTS EQU 20H ;CRT STATUS PORT CRTD EQU 21H ;CRT DATA PORT CRTRDY EQU 04H ;CRT TRANS. BUF. EMPTY KBDS EQU 0EH ;KBD STATUS PORT KBDD EQU 0CH ;KBD DATA PORT KBDRDY EQU 01H ;KBD RECEIVE DATA AVAIL. LISTS EQU 02H ;LIST STATUS PORT LISTD EQU 03H ;LIST DATA PORT LISRDY EQU 80H ;LIST TRANS. BUF. EMPTY ; CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED NULL EQU 00H ;NULL CHARACTER BDOS EQU 0005H ;BDOS ENTRY ADRS ; ORG 100H ; ;Move the console and list drivers up to high RAM ; MOVEUP: LXI B,PEND-START+1 ;NUMBER OF BYTES TO MOVE LXI H,DEST+PEND-START+1 ;END OF MOVED CODE LXI D,SOURCE+PEND-START ;END OF SOURCE CODE ; MVLP: LDAX D ;GET BYTE DCX H ;BUMP POINTERS MOV M,A ;NEW HOME DCX D DCX B ;BUMP BYTE COUNT MOV A,B ;CHECK IF ZERO ORA C JNZ MVLP ;IF NOT, DO SOME MORE ; ;Now patch CP/M to use the new drivers LHLD 1 ;GET CP/M JUMP TABLE ADRS LXI D,4 ;READY TO ADD 4 DAD D ;HL = CONSTAT + 1 ; MVI M,CSTAT AND 0FFH ;PATCH LSB OF JMP ADRS INX H MVI M,CSTAT SHR 8 ;PATCH MSB JMP ADRS ; INX H INX H ;HL = CONIN + 1 MVI M,CONIN AND 0FFH ;PATCH LSB OF JMP ADRS INX H MVI M,CONIN SHR 8 ;PATCH MSB JMP ADRS ; INX H INX H ;HL = CONOUT + 1 MVI M,CONOUT AND 0FFH ;MODIFY LSB JMP ADRS INX H MVI M,CONOUT SHR 8 ;MODIFY MSB JMP ADRS ; INX H INX H ;HL = LISTOUT + 1 MVI M,LISOUT AND 0FFH ;MODIFY LSB JMP ADRS INX H MVI M,LISOUT SHR 8 ;MODIFY MSB JMP ADRS ; ;Print message saying what has been done, then exit to CP/M LXI D,MSG ;POINT TO MESSAGE MVI C,9 ;BDOS PRINT STRING FUNCTION JMP BDOS ;PRINT MSG THEN RETURN TO CCP ; MSG: DB '++Alternate CONSOLE and LIST ' DB 'drivers now patched++',CR,LF,'$' ; SOURCE EQU $ ;BOUNDARY MEMORY MARKER ; OFFSET EQU DEST-SOURCE ;RELOC AMOUNT ;-----------------------------------------------; ; The following code gets moved ; ; to high RAM located at "DEST" ; ;-----------------------------------------------; ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XX C A U T I O N : If modifying anything XX ;XX in this program from here on: XX ;XX A-L-L labels MUST be of the form: XX ;XX LABEL EQU $+OFFSET XX ;XX in order that the relocation to high XX ;XX RAM work successfully. Forgetting to XX ;XX specify '$+OFFSET' will cause the pro- XX ;XX gram to JMP into whatever is currently XX ;XX in low memory, with unpredictable XX ;XX results. Be careful.... XX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; START EQU $+OFFSET ; ;This is the new console status routine CSTAT EQU $+OFFSET IN KBDS ;GET KEYBOARD STATUS ANI KBDRDY ;CHARACTER WAITING? MVI A,0 RZ ;NO, RETURN WITH 0 CMA ;ELSE MAKE IT 0FFH RET ; ;This is the new console input routine CONIN EQU $+OFFSET IN KBDS ;GET KEYBOARD STATUS ANI KBDRDY ;CHARACTER WAITING? JZ CONIN ;NO, LOOP AND WAIT IN KBDD ;GET CHARACTER ANI 7FH ;STRIP PARITY JZ CONIN ;IGNORE NULLS RET ; ;This is the new console output routine CONOUT EQU $+OFFSET IN CRTS ;GET CRT STATUS ANI CRTRDY ;READY FOR CHARACTER? JZ CONOUT ;NO, LOOP AND WAIT MOV A,C ;GET CHARACTER ANI 7FH ;STRIP PARITY RZ ;IGNORE NULLS CPI 7FH ;RUBOUT? RZ ;YES, IGNORE IT OUT CRTD ;ELSE SEND TO CRT RET ; ;This is the new list output routine LISOUT EQU $+OFFSET IN LISTS ;GET LIST STATUS ANI LISRDY ;READY FOR CHARACTER? JZ LISOUT ;NO, LOOP AND WAIT MOV A,C ;GET CHARACTER ANI 7FH ;STRIP PARITY OUT LISTD ;SEND TO PRINTER CPI LF ;WAS IT A LINE FEED? RNZ ;NO, RETURN ; ;Send NULL to printer to allow time for carriage to return MVI C,NULL ;GET A NULL CALL LISOUT ;SEND IT TO PRINTER MVI C,LF ;RESTORE LINE FEED RET ; PEND EQU $+OFFSET ;END OF RELOCATED CODE ; END