home *** CD-ROM | disk | FTP | other *** search
- ;**********************************************************
- ; *
- ; EXTENDED CPM-- 12/06/81 *
- ; DESIGNED TO BE PORTABLE TO ANY CP/M 2.2 *
- ; SYSTEM THAT IS IN ORIGINAL 8080 CODE FOR CCP. *
- ; (will work with others also, but you will *
- ; have to find all of the CCP equates.) *
- ; RLP *
- ; *
- ; will assemble w/ASM.COM *
- ; *
- ; Donated 11/22/81 for the benefit of hobby *
- ; computing, but may not be sold or copied *
- ; for a profit. *
- ; *
- MSIZE EQU 61 ;MEMORY SIZE THIS VERS *
- ;CHANGE TO YOUR SIZE HERE *
- OVERLAY EQU OVERLAY ;COMPUTED SYSGEN OVERLAY *
- ; *
- ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
- ; >>
- ; *** I M P O R T A N T *** >>
- ; >>
- ; You must obtain the address for CBOOT from >>
- ; the argument of the first jump at the >>
- ; beginning of YOUR BIOS and place it in the >>
- ; conditional equate assembled for your system. >>
- ; Make it relative to the beginning of the >>
- ; BIOS as shown. >>
- ; >>
- ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
- ;
- ;**********************************************************
- ;
- ; XTCPM.ASM VERS 1.41
- ;
- ; THIS PROGRAM PROVIDES FOR AN EXPANSION OF YOUR
- ; SYSTEM BY EITHER ONE OR 2 KBYTES WITHOUT THE NEED
- ; FOR A SPECIAL SYSGEN. JUST ADD THIS CODE TO YOUR
- ; SYSTEM BY OVERLAYING YOUR CPMxx.COM FILE USING DDT.
- ; AFTER YOU HAVE OVERLAYED THE CODE INTO CPMxx.COM
- ; WITH DDT, DO TWO SAVES. ONE, SAVE YOUR CPMxx.COM
- ; FILE AS USUAL. TWO, DO A SAVE OF THE CODE WHICH
- ; WILL BE IN THE IMAGE AT 100H. THIS WILL BE A TRAN-
- ; SIENT THAT YOU MUST KEEP ON YOUR 'A' DRIVE AND CON-
- ; TAINS THE ADDITIONAL CODE - SO SAVE IT WITH ENOUGH
- ; SECTORS TO WRITE 1 OR 2 KB DEPENDING ON THE SIZE.
- ; NAME THE TRANSIENT 'XTCPM.COM'. BE SURE THAT YOUR
- ; BIOS IS SET TO DO A TURNKEY START BY HAVING IT
- ; JMP TO THE FIRST ENTRY POINT (CCP+0H) AFTER BIOS
- ; INITIALIZATION. SOME PROPRIETARY BIOS'S DO THIS
- ; THROUGH A MODE BYTE. FINALLY USE YOUR NORMAL
- ; 'SYSGEN' TO WRITE THE CPMxx.COM TO YOUR SYSTEM
- ; TRACKS. IT IS PREFERABLE THAT YOUR BIOS DO A JUMP
- ; TO THE SECOND ENTRY POINT IN THE CCP (CCP+3H) ON
- ; A WARM BOOT, HOWEVER THIS CODE WILL PROPERLY HANDLE
- ; THE SITUATION EVEN IF YOUR BIOS IS NOT IMPLEMENTED
- ; THAT WAY.
- ;
- ; THE EXPANDED CODE SHOWN HERE PROVIDES FOR AN
- ; EXTENDED CCP THAT CAN CONTAIN ADDITIONAL USER
- ; DEFINED CCP COMMANDS AS WELL AS TO MAKE TRANSIENTS
- ; APPEAR AS CCP-LIKE IN THAT THEY CAN BE INVOKED
- ; REGARDLESS OF LOGGED DRIVE/USER AREA. THUS IT IS
- ; COMPLETELY UN-NECESSARY TO PLACE THESE TRANSIENTS
- ; IN MULTIPLE USER AREAS. IT ALSO PROVIDES FOR
- ; TWO LEVELS OF PASSWORD PROTECTION. ADD A TURNKEY
- ; START OF WARD'S 'BYE' W/O PASSWORD TO MAKE A VERS-
- ; ATILE ON-LINE SYSTEM. JUST PUT 'BYE' AT 'FILNAM'
- ; PRECEEDED BY A '3' AND ADD A TEMINATING NULL.
- ; THEN PLACE 'BYE.COM' IN USER 13 ON YOUR 'A' DRIVE
- ; AND SET TNKY2 EQUAL TO TRUE.
- ;
- ; AS DISTRIBUTED HERE, ALL OF THE FEATURES ARE
- ; AVAILABLE WITH LESS THAN ONE KILOBYTE OF SPACE ABOVE
- ; CP/M. THE CODE REQUIRES A Z80 CPU BUT MAY BE
- ; CONVERTED TO 8080 OR 8085. STUFF THE HOLES W/CARE.
- ;
- ; TESTED OK WITH LIFEBOAT CP/M FOR NORTH STAR AND
- ; NORTH STAR'S CP/M PRODUCT. IF YOU ARE USING THE
- ; NORTH STAR CP/M WITH HARD DISK OR NON-STANDARD
- ; PROM, BE CAREFUL NOT TO OVERWRITE THE LAST 80H
- ; OF THE USER AREA CODE STARTING AT 3380H IN IMAGE.
- ; ALSO BE SURE TO SAVE 54 FOR A CPMXX.COM FILE SINCE
- ; THE IMAGE STARTS HIGHER THAN THE USUAL STANDARD.
- ;
- ; ALSO TESTED WITH A STANDARD CP/M USING 8 IN DISKS
- ; AND A MICROMATION DOUBLER.
- ;
- ; YOU CAN APPEND YOUR OWN CUSTOMIZED VERSION OF 'BYE'
- ; WITHOUT A MOVER INTO THE USER2 AREA IF YOU ARE CARE-
- ; FUL TO AVOID LABEL CONFLICTS. IF YOU DO SO, THEN ADD
- ; A COMMAND STRING AT THE 0 PASSWORD LEVEL AND POINT
- ; TO THE ADDRESS OF YOUR 'BYE' ENTRY POINT. ALSO,
- ; REDIRECT THE STACK IN 'BYE' TO BE THE SAME AS THE
- ; STACK IN THIS CODE AND ELIMINATE THE SEPARATE STACK.
- ; ALSO SEE THE NOTE AT LABEL CCPINIT.
- ;
- ; NOTE....THIS PROGRAM DOES NOT CLOBBER ANYTHING IN THE
- ; TPA EXCEPT WHEN LOADING 'BYE' AS A TRANSIENT WHICH
- ; CAN BE AVOIDED AS ABOVE.
- ;
- ; YOU CAN ELIMINATE THE USER1 CODE AREA IN ITS ENTIRETY
- ; IF YOU ARE ALREADY HAPPY WITH YOUR I/O DRIVERS. THERE
- ; IS A CONDITIONAL ASSEMBLY EQUATE TO ACCOMPLISH THIS.
- ;
- ; 12/6/81 Fixed warm boot branch address in CCPINIT.
- ; Added second DIR string and address so that CCP code
- ; for DIR will run at 0 password level and a DIR.COM
- ; transient will run above that level if it is on the
- ; system disk. See NOTE just above label DIR1.
- ; Changed location of PASBYTE vector to the buffer at
- ; the end of the BDOS (spare location) so that if the
- ; CCP is crashed by DDT or anything else, BYE will still
- ; be able to find the PASBYTE to reset it. Former loc-
- ; ation of this vector was at a spare location in the CCP.
- ; Clarified USER2 equate for IF STDCPM. RLP
- ;
- ; 12/4/81 Major revision, see the DOC file. Also
- ; cleaned up the code. RLP
- ;
- ; 11/30/81 Added code to make USERs 13, 14, & 15 on 'A'
- ; universal depending on password level achieved at
- ; log-on time. Removed nested IF's. Cleaned up code so
- ; that a warm boot will properly initialize the CCP.
- ; Also removed bug that would have prevented a file
- ; from being executed by a transient that loads the
- ; command line, sets the buffer pointer, and jumps to
- ; the beginning of the CCP. RLP
- ;
- ; 11/25/81 Added conditional assembly equate to
- ; allow removal of i/o drivers and added routines
- ; to link the code in USER2 to your own customized
- ; BIOS. RLP
- ;
- ***********************************************************
- ;
- ; SYSTEM EQUATES
- ; IMPORTANT You must check these system equates to
- ;be sure that they are valid for your system and change them
- ;if they are not. You may choose to integrate the USER1 code
- ;with your open BIOS if you have one and thus eliminate the
- ;USER1 equate. USER2 will usually be just above CP/M including
- ;any buffer and will usually be MSIZE*1024+32. 32 is to allow
- ;room for stack. Change the value of ADJUST until the values
- ;for CCP, BDOS and BIOS are correct for your system. The value
- ;0D00H for Lifeboat on North Star and for North Star CP/M is
- ;correct, and the value 600H is correct for standard CP/M.
- ;
- FALSE EQU 0
- TRUE EQU NOT FALSE ;SEE OPTIONS BLOCK
- ;TO SELECT ALL OPTIONS
- ;
- IOBYTE EQU 0003H ;I/O BYTE ADDRESS
- DRIVE EQU 0004H ;LOC OF CURR DRV BYTE
- STAKSIZ EQU 32 ;15 LEVEL STACK + BOOT FLAG
- ;AND PASBYTE
- ;
- ; - - - - - - - - - - - - -
- ;
- ;select only one of these true except that if Lifeboat BIOS
- ;then make decision on S22X
- ;
- STDCPM EQU FALSE ;true if standard CP/M on IBM
- ;compatible floppy disk.
- NSTRCPM EQU FALSE ;true if North Star CP/M
- LIFBOAT EQU TRUE ;true if Lifeboat CP/M for North
- ;Star DQ.
- S22X EQU TRUE ;TRUE FOR 2.21A & 2.22. THIS IS A
- ;SPECIAL EQUATE FOR LIFEBOAT BIOS'S
- ;AND ANY OTHERS THAT HAVE ADDED AN
- ;ADDITIONAL JMP FOR WINIT IN THE
- ;USER1 JUMP TABLE. SET TO FALSE
- ;FOR ALL OTHERS. BE SURE THAT YOUR
- ;BIOS JMP TABLE IS PROPERLY LINKED
- ;TO USER1 OR JUST FORGET IT IF YOU
- ;INTEGRATE THIS CODE INTO YOUR
- ;OPEN BIOS.
- M2BIOS EQU FALSE ;true if micromation bios
- ;
- ; - - - - - - - - - - - -
- ;
- ;
- SKIP EQU 0 ;EQUATE THIS TO SIZE OF ROM TO SKIP
- ;NOTE: This will add an additional offset to the
- ; USER2 equate if you wish to place the USER2
- ; code above any PROM or ROM areas. Thus, it
- ; will be unecessary to reserve space between
- ; the top of CP/M and ROM
- ;
- IF LIFBOAT
- ;
- ADJUST EQU 0D00H
- BIOS EQU (MSIZE*1024)-ADJUST ;BASE OF BIOS
- USER1 EQU BIOS+0700H ;BASE 1RST USER AREA
- USER2 EQU MSIZE*1024+STAKSIZ+SKIP ;BASE 2ND USER AREA
- RAMEND EQU 0FC00H ;CHANGE TO YOUR VALUE
- CBOOT EQU BIOS+80H ;COLDBOOT VECTOR FOR 2.22
- CCPIMAGE EQU 0A00H ;CHANGE THIS TO EQUAL THE
- ;ADDRESS OF YOUR CCP IN
- ;THE DDT/SYSGEN IMAGE.
- OVERLAY EQU 2000H-BIOS ;COMPUTED OVERLAY
- ;
- ENDIF
- ;
- IF NSTRCPM
- ;
- ADJUST EQU 0D00H
- BIOS EQU (MSIZE*1024)-ADJUST ;BASE OF BIOS
- USER1 EQU BIOS+0700H ;BASE 1RST USER AREA
- USER2 EQU MSIZE*1024+STAKSIZ+SKIP ;BASE 2ND USER AREA
- RAMEND EQU 0FC00H ;CHANGE TO YOUR VALUE
- CBOOT EQU BIOS+0xxH
- CCPIMAGE EQU 1500H
- OVERLAY EQU 2B00H-BIOS ;COMPUTED OVERLAY
- ;
- ENDIF
- ;
- IF STDCPM
- ;
- ADJUST EQU 600H
- BIOS EQU (MSIZE*1024)-ADJUST ;BASE OF BIOS
- ;USER1 EQU BIOS + (YOUR OFFSET TO USER1 PATCH AREA)
- USER2 EQU MSIZE*1024+STAKSIZ+SKIP ;*NOTE* IF YOUR BIOS CODE
- ;INCLUDING ITS BUFFER SPACE
- ;HAS SPACE LEFT BELOW
- ;MSIZE*1024, YOU CAN SUBTRACT
- ;THE AMOUNT OF SPACE YOU HAVE
- ;LEFT FROM THIS USER2 EQUATE.
- ;SEE THE CODE AT 'IF M2BIOS'
- ;BELOW FOR AN EXAMPLE OF THIS.
- ;RAMEND EQU (PUT YOUR VALUE HERE)
- CBOOT EQU BIOS+0xxH
- CCPIMAGE EQU 980H ;ADDR OF CCP IN DDT IMAGE
- OVERLAY EQU 1F80H-BIOS ;COMPUTED OVERLAY
- ;
- ENDIF
- ;
- IF M2BIOS
- ;This is for a particular user's CBIOS that uses a
- ;Micromation Doubler and has a user code area begin-
- ;ning at BIOS+23DH. Make your own conditional ass-
- ;embly equates for your values.
- ADJUST EQU 600H
- BIOS EQU (MSIZE*1024)-ADJUST
- USER1 EQU BIOS+23DH ;BASE 1RST USER AREA
- USER2 EQU MSIZE*1024+STAKSIZ-256+SKIP ;BASE 2ND USER AREA
- RAMEND EQU 0F400H ;CHANGE TO YOUR VALUE
- ;USED ONLY IN PARITY
- ;SETTING CODE IN 'INITIAL'
- CBOOT EQU BIOS+0ABH
- CCPIMAGE EQU 980H ;ADDR OF CCP IN DDT IMAGE
- OVERLAY EQU 1F80H-BIOS ;COMPUTED OVERLAY
- ;
- ENDIF
- ;
- BOOTFLG EQU USER2-1 ;LOC OF BOOT FLAG
- ;IF NOT 0, then a
- ;cold boot is in progress.
- PASBYTE EQU USER2-2 ;LOC OF PASBYTE
- STACK EQU USER2-2 ;TOP OF STACK
- CCP EQU BIOS-1600H ;BASE OF CCP
- BDOS EQU CCP+800H ;BASE OF BDOS
- ;
- ;
- IOBYT EQU 00000001B ;VALUE OF IOBYTE
- ; ; ; ;---------;CONSOLE IS TTY: 00
- ; ; ; ; CRT: 01
- ; ; ; ; BAT: 10
- ; ; ; ; UC1: 11
- ; ; ;-----------;READER IS TTY: 00
- ; ; ; RDR: 01
- ; ; ; UR1: 10
- ; ; ; UR2: 11
- ; ;-------------;PUNCH IS TTY: 00
- ; ; PUN: 01
- ; ; UP1: 10
- ; ; UP2: 11
- ;---------------;LIST IS TTY: 00
- ; CRT: 01
- ; LPT: 10
- ;-----------UL1: 11
- ;
- DRIVERS EQU TRUE ;WANT THE I/O DRIVERS? (CONTAINED
- ;IN USER1 CODE AREA)
- BGTST EQU TRUE ;WANT BACKGROUND MEMORY TEST?
- ;
- PARITY EQU TRUE ;WANT TO SET PARITY MEMORY
- ;
- TNKY2 EQU TRUE ;WANT 2ND TURNKEY START
- ;
- MAXUSER EQU 2 ;FOR EXAMPLE..MAX PUBLIC USER AREA
- ;
- SGNON EQU FALSE ;NEED SIGN ON MESSAGE?
- ;
- PASBYT EQU 00100100B ;PASSWORD BYTE
- ; ;----------;PASSWORD 2 REQUIRED
- ;-------------;PASSWORD 1 REQUIRED
- ;
- ;END OF OPTIONS BLOCK
- ;***********************************************************
- ;***********************************************************
- ;
- ; PORT ASSIGNMENTS
- ;
- ;Be sure to check port assignments for your system.
- ;
- PARAL EQU 0 ;PARALLEL I/O PORT
- SER1D EQU 2 ;LEFT SERIAL PORT DATA
- SER1ST EQU 3 ;LEFT SERIAL PORT STATUS
- SER2D EQU 4 ;RIGHT SERIAL PORT DATA
- SER2ST EQU 5 ;RIGHT SERIAL PORT STATUS
- MOTHER EQU 6 ;MOTHERBOARD COMMAND/STATUS
- MEMORY EQU 0C0H ;PARITY MEMORY PORT unique to
- ;North Star
- ;
- ;**********************************************************
- ;START OF USER1 CODE
- ;
- ; JUMP TABLE LINKS BIOS TO XTCPM
- ; The rest of the jumps are at base
- ; of the BIOS.
- ;
- ;NOTICE. The IOBYTE processor in this code saves and re-
- ;stores BC, DE, and HL registers.
- ;
- ;**********************************************************
- ;
- IF DRIVERS
- ;
- ORG USER1
- JMP INITIAL ;USER INIT ROUTINE
- ;
- ENDIF
- ;
- IF S22X
- ;
- DS 3 ;SPACE FOR JMP TO WINIT
- ;USED BY 221A & HIGHER ONLY
- ENDIF
- ;
- IF DRIVERS AND NOT (STDCPM OR M2BIOS)
- ;
- JMP CONST ;CONSOLE STATUS ROUTINE
- JMP CONIN ;CONSOLE INPUT
- JMP CONOUT ;CONSOLE OUTPUT
- ;
- ENDIF
- ;
- IF DRIVERS
- ;
- ;***********************************************************
- ;
- ; IOBYTE PROCESSOR
- ;
- ;***********************************************************
- ;
- CONSOL:
- MVI A,CONCNT ;SHIFT COUNTER
- ;
- DISPAT: ;I/O DISPATCHER - TO MAP LOGICAL TO PHYSICAL
- XTHL ;GET RETURN ADDR & SAVE HL
- PUSH B ;SAVE BC
- PUSH D ;SAVE DE
- MOV B,A ;PUT COUNTER VALUE IN B
- LDA IOBYTE ;GET THE IO BYTE
- ;
- DISPAT1:
- DCR B ;SHIFT IOBYTE UNTIL
- DB JRZ, DISPAT2-$-1 ;COUNT IN B=0
- RRC
- RRC
- DB JR, DISPAT1-$-1 AND 0FFH ;SHIFT NEXT TWO BYTES
- ;
- DISPAT2:
- ANI 03H ;MASK OUT BITS 0,1
- RLC ;DOUBLE
- MVI D,0 ;CLEAR D
- MOV E,A ;
- DAD D ;H,L POINTS TO ENTRY
- MOV A,M ;GET LOW BYTE
- INX H ;POINT TO HIGH BYTE
- MOV H,M ;GET HIGH BYTE
- MOV L,A ;H,L POINTS TO SUBR.
- POP D ;RESTORE DE
- POP B ;RESTORE BC
- XTHL ;RSTR HL & PUT RET ON STACK
- RET
- ;
- CONST: ;CONSOLE STATUS, RETURN 0FFH IF READY ,0 IF NOT
- CALL CONSOL ;COMMON ROUTINE
- DW TTYST ;TTY STATUS
- DW CRTST ;CRT STATUS
- DW RDRST ;READER STATUS
- DW UC1ST ;USER CONSOLE STATUS
- ;
- CONIN:
- ENDIF
- ;
- IF BGTST
- ;
- CALL TEST ;BACKGROUND MEMORY TEST
- ;
- ENDIF
- ;
- IF DRIVERS
- ;
- CALL CONST
- ORA A ;SET CC
- DB JRZ, CONIN-$-1 AND 0FFH
- ;CONSOLE INPUT ROUTINE
- CALL CONSOL ;COMMON CONSOLE ROUTINE
- DW TTYIN ;TTY INPUT
- DW CRTIN ;CRT INPUT
- DW READER ;READER INPUT
- DW UC1IN ;USER CONSOLE INPUT
- ;
- CONOUT: ;CONSOLE OUTPUT ROUTINE
- CALL CONSOL ;COMMON ROUTINE
- DW TTYOUT ;TTY OUTPUT
- DW CRTOUT ;CRT OUTPUT
- DW LIST ;LIST OUTPUT
- DW UC1OUT ;USER CONSOLE OUTPUT
- ;
- READER0:
- ENDIF
- ;
- IF BGTST
- ;
- CALL TEST ;BACKGROUND MEM TEST
- ;
- ENDIF
- ;
- IF DRIVERS
- ;
- READER: ;READER INPUT ROUTINE
- MVI A,RDRCNT ;SHIFT COUNTER
- CALL DISPAT ;GO TO LOOKUP ROUTINE
- DW TTYRDR ;READER IS TTY KBD.
- DW HSRIN ;IS HIGH SPEED READER
- DW UR1IN ;USER READER ONE
- DW UR2IN ;USER READER TWO
- ;
- PUNCH: ;PUNCH OUTPUT ROUTINE
- MVI A,PCHCNT ;SHIFT COUNTER
- CALL DISPAT ;LOOK UP ROUTINE
- DW TTYOUT ;PUNCH IS TTY
- DW PUNOUT ;HIGH SPEED PUNCH
- DW UP1OUT ;USER PUNCH ONE
- DW UP2OUT ;USER PUNCH TWO
- ;
- LIST: ;LIST OUTPUT ROUTINE
- MVI A,LSTCNT ;SHIFT COUNTER
- CALL DISPAT ;GO TO DISPATCHER
- DW TTYOUT ;LIST DEVICE IS TTY
- DW CRTOUT ;LIST DEVICE IS CRT
- DW LPTOUT ;LINE PRINTER
- DW UL1OUT ;USER LIST DEVICE
- ;
- LISTST: ;LIST DEVICE STATUS ROUTINE
- MVI A,LSTCNT ;SHIFT COUNTER
- CALL DISPAT ;LOOK UP ROUTINE
- DW TTYST ;RETURN TTY STATUS
- DW CRTST ;RETURN CRT STATUS
- DW LPTST ;LINE PRINTER STATUS
- DW UL1ST ;USER LIST DEVICE STATUS
- ;
- ;**********************************************************
- ;
- ; INPUT/OUTPUT DRIVERS
- ;
- ;**********************************************************
- ;
- ; CRT DRIVERS
- ;
- CRTST: ;CRT STATUS
- IN SER1ST ;GET SERIAL ONE STATUS
- DB JR, TSTSTAT-$-1
- ;
- CRTIN: IN SER1D ;GET DATA
- STRPRET: ANI 7FH ;STRIP PARITY
- RET
- ;
- CRTOUT: ;CRT OUTPUT
- IN SER1ST ;GET STATUS FOR 1RST SERIAL
- ANI OUTRDY ;READY TO RECEIVE DATA?
- DB JRZ, CRTOUT-$-1 AND 0FFH ;NO, LOOP TIL READY
- MOV A,C ;GET DATA
- OUT SER1D ;SEND TO DATA PORT
- RET
- ;
- ; TTY DRIVERS
- ;
- TTYST: ;TTY INPUT STATUS
- IN SER2ST ;GET SERIAL TWO STATUS
- DB JR, TSTSTAT-$-1
- ;
- TTYRDR: ;TTY KEYBOARD AS READER
- IN SER2ST
- ANI INRDY
- JZ READER0
- TTYIN: IN SER2D ;GET DATA
- DB JR, STRPRET-$-1 AND 0FFH
- ;
- TTYOUT: ;TTY OUTPUT
- IN SER2ST ;GET STATUS FOR SERIAL PORT 1
- ANI OUTRDY ;READY FOR DATA?
- DB JRZ, TTYOUT-$-1 AND 0FFH ;NO, WAIT TIL READY
- MOV A,C ;GET DATA
- OUT SER2D ;SEND TO SERIAL 2 DATA PORT
- RET
- ;
- ; READER DRIVER (PARALLEL INPUT PORT)
- ;
- RDRST: ;READER STATUS
- IN MOTHER ;GET STATUS
- TSTSTAT:
- ANI INRDY ;MASK FOR READY
- RRC ;SHIFT TO LSB
- DCRCMA:
- DCR A ;IF ZERO, MAKE FF
- CMA ;COMPLEMENT THE ACC.
- RET
-
- HSRIN: ;HIGH-SPEED READER INPUT
- IN MOTHER ;GET STATUS
- ANI INRDY ;READY WITH DATA?
- JZ READER0 ;LOOP UNTIL PI FLAG
- IN PARAL ;GET PARALLEL INPUT DATA
- ANI 07FH ;STRIP PARITY
- MOV B,A ;SAVE
- MVI A,30H ;LOAD COMMAND BYTE TO A
- OUT MOTHER ;RESET PI FLAG
- MOV A,B ;RECOVER DATA
- RET
- ;
- ; PUNCH DRIVER (PARALLEL OUTPUT PORT)
- ;
- PUNOUT: ;HIGH-SPEED PUNCH OUTPUT
- LPTOUT: ;LINE PRINTER OUT
- ;PUNOUT AND LPTOUT ARE SAME ROUTINE
- IN MOTHER ;GET STATUS
- ANI OUTRDY ;READY FOR DATA
- DB JRZ, LPTOUT-$-1 AND 0FFH ;NO, WAIT TIL READY
- MOV A,C ;GET DATA
- OUT PARAL ;SEND TO PARALLEL PORT
- MVI A,20H ;COMMAND BYTE
- OUT MOTHER ;RESET PO FLAG
- MOV A,C ;GET DATA AGAIN
- RET
- ;
- LPTST: ;LINE PRINTER STATUS
- IN MOTHER ;GET STATUS
- ANI OUTRDY ;READY TO RECEIVE CHAR
- DB JR, DCRCMA-$-1 AND 0FFH
- ;
- ;**********************************************************
- ;
- ; USER DEFINED I/O DEVICE DRIVERS
- ;
- ;**********************************************************
- ;
- UC1ST: ;USER CONSOLE 1 STATUS
- UL1ST: ;USER LIST DEVICE STATUS
- MVI A,0FFH ;ALWAYS READY
- RET
- ;
- UC1OUT: ;USER CONSOLE 1 IN (NULL)
- UP1OUT: ;USER PUNCH ONE OUT (NULL)
- UP2OUT: ;USER PUNCH TWO OUTPUT "
- UL1OUT: ;USER LIST OUTPUT (NULL)
- MOV A,C ;CHARACTER INTO A
- RET
- ;
- UC1IN: ;USER CONSOLE 1 IN (NULL)
- UR1IN: ;USER READER ONE INPUT
- UR2IN: ;USER READER TWO INPUT
- MVI A,EOF ;END OF FILE FOR NOW
- RET
- ;
- ;**********************************************************
- ;THIS IS THE INIT ROUTINE....You should change this for
- ;your hardware. Usually you should make it the same as
- ;the init routine that came with the version of CP/M that
- ;is customized for your system. The init routine below is
- ;for a North Star Horizon.
- ;
- INITIAL:
- MVI A,IOBYT ;THE VALUE
- STA IOBYTE ;THE LOCATION
- ;
- XRA A ;SET TO CLEAR MOTHERBOARD
- OUT MOTHER
- OUT MOTHER ;EXTRAS FOR TIMING,
- OUT MOTHER
- OUT MOTHER ;DON'T ASK
- ;
- ;
- MVI A,40H ;DISABLE PARITY LOGIC
- OUT MEMORY ;BEFORE READING RAM
- ;
- ENDIF
- ;
- IF PARITY
- ;
- LXI H,RAMEND ;PARITY SETTING CODE
- MOV D,H
- MOV E,L
- LXI B,RAMEND+1 ;NUMBER OF BYTES TO CLEAR
- DW LDDR ;SET PARITY ON ALL RAM
- MVI A,41H ;PARITY ENABLE CODE
- OUT MEMORY ;REARM PARITY LOGIC
- ;
- ENDIF
- ;
- IF DRIVERS
- ;
- MVI A,0CEH ;INITIALIZE UARTS
- ;2 STOPS, 16X CLOCK
- ;8 BITS, NO PARITY
- OUT SER1ST
- OUT SER2ST
- ;
- MVI A,37H ;COMMAND: RTS, ER,
- ;RXF, DTR, TXEN
- OUT SER1ST
- OUT SER2ST
- ;
- IN PARAL
- IN SER1D
- IN SER2D
- ;
- ;
- MVI A,30H ;RESET PI FLAG
- OUT MOTHER
- ;
- RET
- ;
- ENDIF
- ;
- USR1END: EQU $ ;END OF USER1 CODE FOR NOW
- USR1SIZE EQU USR1END-USER1 ;MUST NOT EXCEED SPACE
- ;ALLOCATED IN USER1
- ;
- ;**********************************************************
- ; USER2 code starts here. Will be loaded to just above
- ; CP/M by the CCP.
- ;The following ORG statement will provide for loading of
- ;USER2 code just above CP/M by the specially initialized
- ;CCP(which this program does); AND, will provide for the
- ;memory image to appear at 100H when the OVERLAY offset
- ;is used with DDT to patch in your code to a CPMxx.COM
- ;file. Save your USER2 code as a transient called XTCPM.COM
- ;and keep it on your A drive since it will be needed for all
- ;cold boots. Also save your CPMxx.COM file after patching
- ;with DDT and use your normal SYSGEN program to write it
- ;to the system tracks. Save both files to appropriate size.
- ;
- ;Any code placed in this area should have the EQU $+OFFSET
- ;at each label and Z80 jump relatives should use the FR and
- ;BR post-fixes as shown.
- ;
- ;THIS ORG STATEMENT SHOULD CAUSE THE FOLLOWING CODE TO APPEAR
- ;AT 100H IN THE DDT IMAGE AFTER OFFSETTING WITH THE OVERLAY
- ;BIAS THAT YOU USE IN PATCHING YOUR BIOS INTO CPMxx.COM.
- ;
- ORG CCP-(CCPIMAGE-100H)
- SOURCE: EQU $ ;SOURCE OF USER2 CODE
- OFFSET: EQU USER2-SOURCE ;OFFSET FOR USER2 CODE
- FR: EQU -1-OFFSET ;FORWARD RELATIVE
- BR: EQU FR+0FFH+1 ;BACKWARD RELATIVE
- ;
-
- ;**********************************************************
- ;This routine is the first to be called when going to the
- ;TPA on a coldboot turnkey start. It simply changes the
- ;CCP parameters to restore the dma and address for the TPA
- ;back to 100H and resets the address tested for CCP overwrite.
- ;The turnkey start in the mean time has loaded the rest of
- ;the code in the USER2 area to a location just above CP/M
- ;and all properly linked to the code in the USER1 area.
- ;
- RET ;TO RET IF EXECUTED FROM
- ;THE COMMAND LINE.
- ;This is the entry point when called by the CCP.
- XTCPM: EQU $+OFFSET ;ROUTINE TO RESTORE CCP DMA
- ;AND TPA ADDRESSES TO 100H
- LXI H,TPA
- SHLD CCPDMA
- SHLD TPASUB
- LXI H,CCP
- SHLD TSTOVWR
- ;
- MVI A,PASBYT ;GET THE PASSWORD BYTE
- ;If you use Ward's 'BYE' ,then
- ;you should restore the PASBYT
- ;to its initial value in the
- ;HANGUP routine of 'BYE'.
- ;Use the following code:
- ;LHLD 0001H ;get bios vector
- ;LXI D,-28H ;set to subtract (SEARA+2)
- ;DAD D ;hl pnts to PASBYTE address
- ;MOV A,M ;load hl with address
- ;INX H
- ;MOV H,M
- ;MOV L,A
- ;MVI M,24H ;reset PASBYTE
- ;
- STA PASBYTE ;STORE IT
- ;
- CALL RSTPRMS
- ;
- IF SGNON
- ;
- MVI C,WRBUF ;GIVE SYSTEM SIGNON MESSAGE
- LXI D,SIGNON
- CALL BDOSFNC
- ;
- ENDIF
- ;
- IF NOT TNKY2
- ;
- RET
- ;
- ENDIF
- ;
- IF TNKY2
- ;
- LXI H,COMBUF+1
- SHLD BUFPTR
- DCX H
- XCHG
- LXI H,FILNAM
- LXI B,5
- DW LDIR
- MVI C,0
- JMP CCP
- ;
- FILNAM: EQU $+OFFSET
- DB 3,'BYE',0
- ;
- ENDIF
- ;
- IF SGNON
- ;
- SIGNON: EQU $+OFFSET
- DB CR,LF
- DB MSIZE/10+30H
- DB MSIZE MOD 10 + 30H
- DB 'K CP/M 2.2 - XTCPM$'
- ;
- ENDIF
- ;
- ;**********************************************************
- ;The password checking routine- uses string comparator
- ;that is contained in the CCP.
- ;
- CKPASS0: EQU $+OFFSET
- LXI H,PASBYTE
- DW BIT2M
- DB JRZ, OK-$+FR
- LXI H,PAS2
- SHLD STRPTR
- LXI H,PASTBL2
- SHLD CMDPTR
- DB JR, CKPASS-$+FR
- ;
- PASSINT: EQU $+OFFSET
- CALL LOGTST
- DB JRZ, OK-$+FR
- LXI H,PAS1
- SHLD STRPTR
- LXI H,PASTBL1
- SHLD CMDPTR
- ;
- CKPASS: EQU $+OFFSET
- MVI A,1
- STA CMDCNT
- MVI A,10
- STA CMDLEN
- MVI C,4 ;GIVES 4 TRIES
- PUSH B
- ;
- CKAGIN: EQU $+OFFSET
- CALL ILPRT
- DB 'Password:',0
- POP B
- MVI B,14 ;TO KEEP HIM FROM CLOBBERING
- ;THE CODE
- LXI H,NAME
- DRCON: EQU $+OFFSET
- CALL VCONIN
- CPI CR
- DB JRNZ, DRCN2-$+FR
- MVI A,20H
- MVI B,1
- DRCN2: EQU $+OFFSET
- MOV M,A
- INX H
- DCR B
- DB JRNZ, DRCON-$+BR
- ;
- DCR C
- JZ RELOG0
- PUSH B
- JMP SRCHCMD
- ;
- OK: EQU $+OFFSET
- CALL ILPRT
- DB 'Ok.',0
- JMP RETCCP
- ;
- PASTBL1: EQU $+OFFSET
- DW OK1
- DW CKAGIN
- PASTBL2: EQU $+OFFSET
- DW OK2
- DW CKAGIN
- ;
- ;**********************************************************
- ;This is the in-line print subroutine.
- ;
- ILPRT: EQU $+OFFSET
- DB EXX
- CALL CRLF
- DB EXX
- ;
- ILPRT2: EQU $+OFFSET
- XTHL ;SAVE HL, GET MSG
- ILPLP: EQU $+OFFSET
- MOV C,M ;GET CHAR
- CALL VCONOUT ;OUTPUT IT
- INX H ;POINT TO NEXT
- MOV A,M ;TEST
- ORA A ;..FOR END
- DB JRNZ, ILPLP-$+BR
- XTHL ;RESTORE HL, RET ADDR
- RET ;RET PAST MSG
- ;
- ;***********************************************************
- ;ROUTINE TO TEST LOG IN
- ;
- LOGTST: EQU $+OFFSET
- LXI H,PASBYTE
- DW BIT5M
- RET
- ;
- ;**********************************************************
- ;
- RELOG0: EQU $+OFFSET
- CALL CRLF
- RELOG: EQU $+OFFSET
- CALL LOGTST
- DB JRZ, EXIT-$+FR
- CALL LGMSG
- EXIT: EQU $+OFFSET
- JMP RETCCP
- ;
- LGMSG: EQU $+OFFSET
- CALL ILPRT2
- DB 'Login please. ',CR,LF,0
- RET
- ;
- ;**********************************************************
- ;Routines to trap transient files if they are resident
- ;on drive A. If DIR.COM not present, then the CCP code for
- ;the DIR command will be executed. If TYPE.COM not present,
- ;then the CCP code for the TYPE command will be executed.
- ;This trapping is useful for SD.COM and MLIST.COM re-named
- ;to DIR.COM and TYPE.COM respectively.
- ;**NOTE** Do not use a Directory transient that scans user
- ;areas such as SD-21 or SD-22. KDIR is ok. You can use SD-42
- ;if you set AOPT to FALSE and add an IF AOPT and ENDIF around
- ;the [lda,newusr; cmp m; jnz mordir] sequence at the label,
- ;SYSFOK. Otherwise you will defeat the universal user area
- ;features in this program so far as directories are concerned,
- ;although the universallity will still apply to execution and
- ;finding of files in users 13, 14, and 15.
- ;
- DIR1: EQU $+OFFSET
- LXI H,TRAPBYT
- DW SET0M ;SET DIR TRAP
- JMP GETRANS
- ;
- TYPE1: EQU $+OFFSET
- LXI H,TRAPBYT
- DW SET1M
- JMP GETRANS
- ;
- HUH0: EQU $+OFFSET
- LXI H,TRAPBYT
- DW BIT0M ;SEE IF DIR TRAP SET
- JNZ DIR ;CCP DIR CODE IF NOT
- DW BIT1M ;SEE IF TYPE TRAP SET
- DW RES1M
- JNZ TYPE ;CCP TYPE CODE IF NOT
- CALL ILPRT
- DB 'No!, ',BELL,0
- CALL LOGTST
- DB JRNZ, RELOG-$+BR
- JMP HUH+3
- ;
- ;**********************************************************
- ;This is the command string which is divided into private
- ;and public sections. Do not use more than five letters for
- ;the name of any command/transient and fill out each string
- ;to exactly five characters by using spaces below. Strings
- ;must occur at 5 character intervals. If you use some
- ;other string length such as 4 as in the original CCP, just
- ;change string lengths below and change the LENCMD equate
- ;from 5 to 4. I use 5 below so that LOGIN & LOGON can fit.
- ;
- CMDSTR2: EQU $+OFFSET
- DB 'ERA REN SAVE '
- CMDSTR1: EQU $+OFFSET
- DB 'TYPE USER PASS DIR '
- CMDSTR0: EQU $+OFFSET
- DB 'DIR LOGINLOGON'
- ;
- ;**********************************************************
- ;This is the command address table which is divided into
- ;private and public areas. The address of the routine to be
- ;jumped to must be here for CCP-included code as well as
- ;any that you put in your customized BIOS.
- ;You can expand the table to any extent that you have space
- ;and the command string above must be expanded in synchronism.
- ;
- CMDTBL2: EQU $+OFFSET
- DW ERA ;ERA....PRIVATE COMMANDS
- DW REN ;REN
- DW SAVE ;SAVE
- CMDTBL1: EQU $+OFFSET
- DW TYPE1 ;TYPE..In case MLIST.COM renamed
- ;to 'TYPE.COM'. Put the transient
- ;in USER 14 on drive A.
- DW USER ;USER
- DW CKPASS0 ;PASS(word) to gain access to
- ;private user areas. Can also
- ;be set at LOGIN by entering the
- ;second password.
- DW DIR1 ;DIR....If you wish to use SD or
- ;KDIR as a CCP transient instead of
- ;the CCP DIR code, just change the
- ;name of your transient to DIR.COM
- ;and put it in USER 14 on drive A.
- ;The transient will run only if 1rst
- ;password level has been achieved.
- ;If transient not present then CCP
- ;'DIR' code will run.
- ;These commands will be the only ones allowed until the user
- ;logs in to the system with LOGIN.
- CMDTBL0: EQU $+OFFSET
- DW DIR ;WILL RUN THE CCP 'DIR' CODE
- DW PASSINT ;LOGIN
- DW PASSINT ;LOGON
- GETRAN0: EQU $+OFFSET ;This must be last entry in table.
- DW GETRANS ;GET THE TRANSIENT AND EXECUTE OR
- ;RETURN TO CCP W/HUH MESSAGE IF NOT
- ;ON DISK.
- ;
- ;**********************************************************
- ;This patch which is called from the CCP provides for a
- ;report of USER number at the prompt....i.e. A2> for USER 2,
- ;'A' drive.
- ;
- UPATCH: EQU $+OFFSET
- CALL GETUSR ;GET USER NUMBER
- ANI 0FH ;KILL UNWANTED BITS
- DB JRZ, UPA2-$+FR ;IF USER 0, DON'T REPORT
- CPI 10
- DB JRC, UPA1-$+FR ;JIF USER NUM = 0 THRU 9
- SUI 10 ;USER NUM = 10 THRU 15
- PUSH PSW
- MVI C,'1'
- CALL VCONOUT ;PRINT A '1'
- POP PSW
- ;
- UPA1: EQU $+OFFSET
- ADI '0'
- MOV C,A
- CALL VCONOUT ;PRINT DIGIT
- ;
- UPA2: EQU $+OFFSET
- MVI C,'>'
- CALL VCONOUT ;PRINT '>', EXIT
- XRA A
- STA TRAPBYT ;CLEAR THE TRAPS
- ;FALL THROUGH TO RESET PARAMETERS & RETURN
- ;
- ;**********************************************************
- ;Routines to reset parameters for string matching and other
- ;purposes.
- ;
- RSTPRMS: EQU $+OFFSET
- MVI A,0C3H ;SET BDOS TO TREAT USERS
- STA BDOS+75EH ;..13, 14 AND/ OR 15 AS
- LXI H,UNIV ;..UNIVERSAL DEPENDING ON
- SHLD BDOS+75FH ;..PASSWORD LEVEL.
- ;
- MVI A,LENCMD
- STA CMDLEN
- LXI H,PASBYTE
- DW BIT2M
- DB JRNZ, RST1-$+FR
- ;
- RST2: EQU $+OFFSET
- LXI H,CMDSTR2
- SHLD STRPTR
- MVI A,(GETRAN0-CMDTBL2)/2
- STA CMDCNT
- LXI H,CMDTBL2
- SHLD CMDPTR
- MVI A,16
- STA TSTUSR
- RET
- ;
- RST1: EQU $+OFFSET
- LXI H,CMDSTR1
- SHLD STRPTR
- MVI A,(GETRAN0-CMDTBL1)/2
- STA CMDCNT
- LXI H,CMDTBL1
- SHLD CMDPTR
- MVI A,MAXUSER+1
- STA TSTUSR
- LDA PASBYTE
- DW BIT5A
- RZ
- RST0: EQU $+OFFSET
- MVI A,(GETRAN0-CMDTBL0)/2
- STA CMDCNT
- LXI H,CMDSTR0
- SHLD STRPTR
- LXI H,CMDTBL0
- SHLD CMDPTR
- RET
- ;
- ;**********************************************************
- ;BIOS routines called herein.
- ;
- VCONIN: EQU $+OFFSET
- DB EXX
- CALL BIOS+9H
- DB EXX
- RET
- ;
- VCONOUT: EQU $+OFFSET
- PUSH H
- PUSH D
- PUSH B
- CALL BIOS+0CH
- POP B
- POP D
- POP H
- RET
- ;
- ;**********************************************************
- ;This routine will make USER 13, 14, and/or 15 universal on
- ;drive A only depending on password level. Files placed in
- ;user 13 will be universal without any password. Files placed
- ;in user 14 will additionally be universal on drive A at the
- ;first password level, and files placed in user 15 will be
- ;universal at the second password level in addition to those
- ;in users 13 and 14.
- ; ***** WARNING! *****
- ;NEVER have two files by the same name & extension on the
- ;same disk (one in USER 15 and the other in some other
- ;USER) because CP/M will take which ever one comes first
- ;in the directory.
- ;
- UNIV: EQU $+OFFSET
- MOV A,B ;duplicate instruction overlayed
- ORA A ;check pointer for zero byte
- DB JRNZ, UNIV1-$+FR ;skip if not zero byte of fcb
- ;
- LDA CURDSK ;get current disk
- ANI 0FH ;mask out high nibble
- CPI 0 ;is it drive A? (may be changed
- ;to any drive. 0,1,2.. = A,B,C..)
- DB JRNZ, UNIV1-$+FR ;skip if not
- ;
- LDAX D ;get fcb first byte
- CPI 0E5H ;check for erased
- DB JRZ, UNIV1-$+FR ;skip if erased
- ;
- LDA PASBYTE
- DW BIT5A
- DB JRNZ, DFU13-$+FR
- DW BIT2A
- DB JRNZ, DFU14-$+FR
- ;
- MOV A,M
- CPI 15 ;and check for user 15
- DB JRZ, MATCH0-$+FR ;jump if zero
- ;
- DFU14: EQU $+OFFSET
- MOV A,M
- CPI 14 ;check for user 14
- DB JRZ, MATCH0-$+FR
- ;
- DFU13: EQU $+OFFSET
- MOV A,M
- CPI 13 ;check for user 13
- MATCH0: EQU $+OFFSET
- JZ MATCH
- ;
- UNIV1: EQU $+OFFSET
- MOV A,B ;duplicate instuction overlayed
- CPI 0DH ; " " "
- JMP TINUSRCH ;and return where routine left off
- ;
- ;**********************************************************
- ;This is a background memory test that runs whenever the
- ;current console (including remote) is waiting for an input
- ;character to be typed.
- ;
- ;TEST ROUTINE TO CONSTANTLY TEST MEMORY
- ;
- IF BGTST AND DRIVERS
- ;
- TSTPT: EQU $+OFFSET
- DW 0
- TEST: EQU $+OFFSET
- DI
- PUSH H
- LHLD TSTPT
- INX H
- MOV A,H
- CPI ($+OFFSET)/100H-SKIP/100H
- DB JRNZ, TEST1-$+FR
- LXI H,0
- ;
- TEST1: EQU $+OFFSET
- SHLD TSTPT
- MOV A,M
- CMA
- MOV M,A
- CMP M
- DB JRZ, TEST2-$+FR
- XRA M
- PUSH PSW
- PUSH H
- CALL CRLF
- POP H
- POP PSW
- PUSH PSW
- CALL PRTHX
- CALL ILPRT2
- DB 'H Bits bad at: ',0
- MOV A,H
- CALL PRTHX
- MOV A,L
- CALL PRTHX
- POP PSW
- ;
- TEST2: EQU $+OFFSET
- CMA
- MOV M,A
- POP H
- EI
- RET
- ;
- PRTHX: EQU $+OFFSET
- PUSH PSW
- RRC
- RRC
- RRC
- RRC
- CALL PRTHX1
- POP PSW
- ;
- PRTHX1: EQU $+OFFSET
- ANI 0FH
- CPI 10
- DB JRC, PRTHX2-$+FR
- ADI 7
- ;
- PRTHX2: EQU $+OFFSET
- ADI '0'
- MOV C,A
- DB JR, VCONOUT-$+BR
- ;
- ;END OF CONSTANT MEMORY TEST
- ;
- ENDIF
- ;
- USR2END: EQU $+OFFSET ;END OF USER2 CODE FOR NOW
- INITSIZE EQU INITSIZE ;
- USR2SIZE EQU USR2END-USER2 ;DO NOT EXCEED SPACE ALLOCAT-
- ;ED ABOVE YOUR RUNNING CP/M.
- ;
- ;**********************************************************
- ; EQUATES FOR CCP PATCHES
- LENCMD EQU 5 ;LENGTH OF CCP CMD STRINGS
- GETUSR EQU CCP+113H ;GET USER #
- SETUSR EQU CCP+115H ;SET USER #
- TSTUSR EQU CCP+692H ;TEST USER #
- USRSAV EQU CCP+118H
- UPATCH0 EQU CCP+390H
- UPATCH1 EQU CCP+393H
- HUH EQU CCP+209H ;CCP HUH RESPONSE
- CRLF EQU CCP+98H ;CCP CR/LF FUNCTION
- RETCCP EQU CCP+382H ;RE-ENTRY TO CCP
- GETCMD EQU CCP+398H ;GET THE ENTERED COMMAND
- SRCHCMD EQU CCP+3B1H ;ENTRY TO SEARCH OF COMMANDS
- COMBUF EQU CCP+7H ;LOC OF CMD BUFFER
- BUFPTR EQU CCP+88H ;LOC OF CMD BUFFER POINTER
- CMDPTR EQU CCP+3B5H ;LOC OF CMD ADDR TBL PTR
- GETRPTR EQU CCP+3AFH ;LOC OF GET TRANS PTR
- STRPTR EQU CCP+32FH ;POINTER TO CCP CMD STRINGS
- CMDCNT EQU CCP+335H ;BYTE VALUE = # OF COMMANDS
- CMDLEN EQU CCP+33BH ;BYTE VALUE = LENGTH OF EACH
- ;COMMAND STRING.
- TSTOPN EQU CCP+6DCH ;TEST FILE OPEN FUNCTION
- CMDDRV EQU CCP+7F0H ;BYTE INDICATES DRV IN CMD
- CMDERR EQU CCP+76BH ;HUH RESPONSE IF DR #
- NAME EQU CCP+7CEH ;LOC FOR FN IN FCB
- XTNSN EQU CCP+7D6H ;STORAGE LOC FOR FILE TYPE,
- ;EXT #, AND RECORD COUNT
- RELOOK EQU CCP+6CDH ;RELOOK W/INDICATED DRIVE
- TSTOVWR EQU CCP+6F5H ;TEST OVERWRITE OF CCP
- CCPDMA EQU CCP+6DFH ;LOC TO SUBSTITUTE FOR
- ;DMA ADDRESS
- TPASUB EQU CCP+75DH ;LOC TO SUSTITUTE BEFORE
- ;CALLING THE TPA
- CLDBOOT EQU CCP+35CH ;COLDBOOT ENTRY POINT
- CONTINUE EQU CCP+75FH ;CONTINUE AFTER CALL TO TPA
- GETRANS EQU CCP+6A8H ;GET TRANS OR CCP COMMAND
- ERA EQU CCP+51FH ;ADDR OF ERA ROUTINE
- REN EQU CCP+610H ;ADDR OF REN ROUTINE
- SAVE EQU CCP+5ADH ;ADDR OF SAVE ROUTINE
- DIR EQU CCP+477H ;ADDR OF DIR ROUTINE
- TYPE EQU CCP+55DH ;ADDR OF TYPE ROUTINE
- USER EQU CCP+68EH ;ADDR OF USER ROUTINE
- TPA EQU 100H ;OR YOUR TPA ADDRESS
- STKPTR1 EQU CCP+35DH
- STKPTR2 EQU CCP+760H
- STKPTR3 EQU CCP+383H
- PRNSTR1 EQU CCP+0A7H ;PRINT STRING WITH LEADING
- ;CR/LF..POINT TO IT WITH BC
- PRNSTR2 EQU CCP+0ACH ;PRINT STRING..POINT WITH HL
- CCPSPARE EQU CCP+7F2H ;14 SPARE BYTES AT END CCP
- ;Addresses of holes left in CCP that are filled in
- ;with patches.
- HOLE1 EQU CCP+79BH ;16 BYTES
- HOLE2 EQU CCP+310H ;30 BYTES
- HOLE3 EQU CCP+3C1H ;24 BYTES
- HOLE4 EQU CCP+1F5H ;20 BYTES
- HOLE5 EQU CCP+6A5H ;3 BYTES
- ;
- ;**********************************************************
- ; CCP patches
- ;**********************************************************
- ORG GETRPTR
- DW GETRANS
- ;
- ORG CMDCNT
- DB 0
- ;
- ORG CMDPTR
- DW GETR0
- ;
- ORG HOLE5
- GETR0: DW GETRANS
- DB 0 ;3 BYTES AT HOLE5
- ;
- ;Patch the turnkey start string into the CCP command buffer.
- ORG COMBUF
- TNKY: DB 05,'XTCPM',0
- ;
- ;**********************************************************
- ;To trap the HUH message.
- ;
- ORG HUH
- JMP HUH0
- ;
- ;**********************************************************
- ;To redirect the CCP stack so a larger stack is available.
- ;
- ORG STKPTR1
- DW STACK
- ORG STKPTR2
- DW STACK
- ORG STKPTR3
- DW STACK
- ;
- ;**********************************************************
- ; This patch is used to restrict access to the higher user
- ; areas while leaving the lower user areas public. The high-
- ; est available public user area is defined by MAXUSER.
- ;
- ORG HOLE1
- OK2: LXI H,PASBYTE
- DW RES2M
- ;
- OK1: LXI H,PASBYTE
- DW RES5M
- JMP OK
- ;
- TRAPBYT:
- DB 0
- DB 0,0 ;SPARES
- ;DO NOT EXPAND
- ;16 BYTES AT HOLE1
- ;***********************************************************
- ;The following sequence of statements are to patch the CCP
- ;so that the transient 'XTCPM.COM' will be loaded above CP/M
- ;by the CCP without the need for a special 'sysgen' routine.
- ;Use the normal SYSGEN program with your system.
- ORG CCP+1
- DW CCPINIT
- ;
- ORG HOLE2
- CCPINIT:
- LXI H,CCP+35CH
- SHLD CCP+1
- ;
- LXI H,BOOTFLG
- DW BIT1M ;SEE IF COLD BOOT
- DW RES1M
- JZ CCP+358H ;ELSE GOTO WARM BOOT ENTRY
- ;
- LXI H,USER2+800H ;TO MOVE OVERWRITE TEST LOC
- ;TO TOP OF SYS MEMORY
- SHLD TSTOVWR
- LXI H,USER2 ;TO SUBSTITUTE DMA AND TPA
- ;TO USER2 ADDRESS TEMPORARILY
- JMP BRIDGE
- ;
- DB 0,0 ;SPARES
- ;Do not expand, 30 bytes available here.
- ;
- ;**********************************************************
- ORG USRSAV
- DW SAVUSR
- ;
- ORG HOLE3
- SAVUSR: MOV A,E
- CPI 0FFH
- JZ BDOSFNC
- RLC
- RLC
- RLC
- RLC
- MOV B,A
- LDA DRIVE
- ANI 0FH
- ORA B
- STA DRIVE
- JMP BDOSFNC
- DB 0 ;DO NOT EXPAND, 24 BYTES HERE
- ;
- ;**********************************************************
- ;These are the passwords for entry to CP/M from BYE
- ;and to USER area and command privileges above MAXUSER
- ;repectively. Passwords may be up to 10 characters, and
- ;must be filled out to this value with spaces.
- ORG HOLE4
- PAS1: DB 'PASSWORD1 '
- PAS2: DB 'PASSWORD2 '
- ;DO NOT EXPAND, EXACTLY 20 BYTES
- ;ARE AVAILABLE HERE.
- ;
- ;**********************************************************
- ; This patch causes user number to be reported at the cp/m
- ; prompt.....i.e. - A2>. User 0 report is suppressed.
- ;
- ORG UPATCH0
- MVI C,USRFNC
- ;
- ORG UPATCH1
- DW UPATCH
- ;the routine UPATCH is located in the USER2 area
- ;**********************************************************
- ; This patch causes the CCP of a cp/m 2.x system to look on
- ; drive A when you are logged into a drive other than A and
- ; call for a .COM file that does not exist on that drive.
- ; Giving an explicit drive reference overrides this feature,
- ; so that you can always force the file to be loaded from a
- ; specific drive.
- ;
- ORG TSTOPN
- DW APATCH ;REPLACES 'CMDERR'
- ;
- ORG CCPSPARE
- APATCH: LXI H,CMDDRV ;GET DRIVE FROM CURRENT CMD.
- ORA M ;FETCHES DRIVE
- JNZ CMDERR ;GIVE ERR IF CMD HAS DRIVE #
- INR M ;FORCE TO DRIVE A
- LXI D,XTNSN ;UNDO WHEN...
- JMP RELOOK ;REENTERING
- ;DON'T EXPAND. 14 BYTES HERE.
- ;
- ;**********************************************************
- ; BDOS patches
- ;**********************************************************
- ;
- BDOSPARE EQU BDOS+0DEEH ;18 SPARE BYTES AT END BDOS
- MATCH EQU BDOS+077CH
- CURDSK EQU BDOS+342H
- TINUSRCH EQU BDOS+761H
- ;
- ORG BDOS+0DDBH ;SEARA+2
- DW PASBYTE ;ADDRESS OF PASS WORD BYTE
- ;
- ORG BDOSPARE
- BRIDGE: SHLD CCPDMA
- INX H
- SHLD TPASUB
- JMP CLDBOOT ;COLDBOOT ENTRY POINT
- ;end of CCP initialization
- ;
- CBOOT0: LXI H,BOOTFLG
- DW SET1M
- JMP CBOOT
- ;DO NOT EXPAND, EXACTLY 18 BYTES HERE
- ;
- ;**********************************************************
- ; BIOS patches
- ;**********************************************************
- ;This jump table overlays the table at the base of the BIOS
- ;thus making it unecessary to have all of the jumps in the
- ;jump table at the base of the USER1 area.
- ;
- ORG BIOS
- JMP CBOOT0
- ;
- IF DRIVERS AND NOT (STDCPM OR M2BIOS)
- ;
- ORG BIOS+0FH
- JMP LIST
- JMP PUNCH
- JMP READER
- ;
- ORG BIOS+2DH
- JMP LISTST
- ;
- ENDIF
- ;
- IF DRIVERS AND (STDCPM OR M2BIOS)
- ;
- ORG BIOS+6H
- JMP CONST
- JMP CONIN
- JMP CONOUT
- JMP LIST
- JMP PUNCH
- JMP READER
- ;
- ORG BIOS+2DH
- JMP LISTST
- ;
- ENDIF
- ;
- ;************************************************************
- ;
- ; SPECIAL ASCII CODES
- ;
- LF EQU 0AH ; LINE FEED
- CR EQU 0DH ; CARRIAGE RETURN
- EOF EQU 1AH ; END OF FILE
- BELL EQU 07H ; DING
- NULL EQU 00H ; NOTHING
- ESC EQU 1BH ; ESCAPE - USED IN TWO CHAR COMMANDS
- LIN EQU 6CH ; CHAR AFTER ESCAPE TO CLEAR LINE
- SCRN EQU 45H ; CHAR AFTER ESCAPE TO CLEAR SCREEN
- ;
- ; STATUS MASKS
- ;
- INRDY EQU 02H ;INPUT READY MASK
- OUTRDY EQU 01H ;OUTPUT READY MASK
- ;
- ; POSITION OF BIT PAIR IN IOBYTE
- ;
- CONCNT EQU 1 ;CONSOLE BITS 0,1
- RDRCNT EQU 2 ;READER BITS 2,3
- PCHCNT EQU 3 ;PUNCH BITS 4,5
- LSTCNT EQU 4 ;LIST BITS 6,7
- ;
- ;**********************************************************
- ;
- ; Z80 EQUATES
- ;
- JR EQU 18H ;JUMP RELATIVE
- JRZ EQU 28H ;JUMP RELATIVE ON ZERO
- JRNZ EQU 20H ;JUMP RELATIVE ON NOT ZERO
- JRC EQU 38H ;JUMP RELATIVE ON CARRY
- JRNC EQU 30H ;JUMP RELATIVE IF CARRY RESET
- LDIR EQU 0B0EDH ;MEMORY BLOCK MOVE
- LDDR EQU 0B8EDH ;MOVE BLOCK UNTIL COUNTER=0
- MOVIVA EQU 47EDH ;MOVE ACC TO INTERRUPT REGISTER
- IM2 EQU 5EEDH ;SET INTERRUPT MODE 2
- BIT2A EQU 57CBH ;TEST BIT 2 IN ACC.
- BIT5A EQU 6FCBH ;TEST BIT 5 IN ACC.
- BIT0M EQU 46CBH ;TEST BIT 0 IN MEM
- BIT1M EQU 4ECBH ;TEST BIT 1 IN MEM
- BIT2M EQU 56CBH ;TEST BIT 2 IN MEM
- BIT5M EQU 6ECBH ;TEST BIT 5 IN MEM
- SET0M EQU 0C6CBH ;SET BIT 0 IN MEM
- SET1M EQU 0CECBH ;SET BIT 1 IN MEM
- RES1M EQU 8ECBH ;RESET BIT 1 IN MEM
- RES2M EQU 96CBH ;RESET BIT 2 IN MEM
- RES5M EQU 0AECBH ;RESET BIT 5 IN MEM
- EXX EQU 0D9H ;EXCH REG PAIRS B, D, & H
- ;
- ;
- ;BDOS EQUATES
- ;
- BDOSFNC EQU BDOS+6H
- USRFNC EQU 32
- WRBUF EQU 9