home *** CD-ROM | disk | FTP | other *** search
- ; REL1.ASM
- ;
- ;
- ; THIS IS A MODIFIED SOURCE TEXT OF THE PROGRAM PORTION OF
- ; RELOC.COM. THE COM FILE ALSO CONTAINS A COPY OF CP/M,
- ; BEGINNING AT 900H, AND A RELOCATION TABLE, PRESENTLY
- ; BEGINNING AT 2100H.
- ;
- ; THIS VERSION OF RELOC DIFFERS FROM THE STANDARD VERSION IN
- ; THAT THE SERIAL-NUMBER CHECKS HAVE BEEN REMOVED. IT COPIES THE
- ; SERIAL NUMBER FROM THE USER'S BDOS INTO THE RELOCATED SYSTEM, THUS
- ; INSURING COMPATIBILITY. IN ADDITION, THIS VERSION CAN BE RUN UNDER
- ; DDT WITHOUT CAUSING A "SYNCRONIZATION" ERROR.
- ;
- ;
- ORG 100H
- ;
- ; LOCATIONS OF INFORMATION FROM COMMAND LINE, PUT IN DEFAULT BUFFERS
- ; BY CCP:
- ;
- NAME1 EQU 5DH ;FIRST "FILENAME" (NO. OF K)
- NAME2 EQU 6DH ;2ND "FILENAME" (BLANK OR *)
- ;
- ENTRY EQU 5 ;LOCATION OF JUMP TO BDOS
- REBOOT EQU 0 ;LOCATION TO JUMP TO FOR REBOOT
- SYSTEM EQU 900H ;WHERE RELOC'S COPY OF SYSTEM RESIDES
- SERIALB EQU 1300H ;START OF BDOS SERIAL NUMBER IN THAT SYSTEM
- SERIALC EQU 0CA0H ;START OF CCP SERIAL NUMBER IN THAT SYSTEM
- SIZE EQU 801H ;WHERE LENGTH OF SYSTEM IS STORED
- ;
- ;
- CR EQU 0DH
- LF EQU 0AH
- ;
- ;
- ;
- ;
- FIRST: JMP START
- ;
- ;
- ;
- ;
- ORG 012CH
- ;
- START: LXI SP,800H
- ;
- ;
- LXI D,NAME1
- LDAX D ;GET FIRST CHAR. OF WHAT IS ASSUMED TO BE NO. OF K
- CPI ' '
- JZ UNSPEC ;JUMP IF NO NUMBER TYPED IN COMMAND
- CPI '?'
- JZ UNSPEC ;RECOGNIZE BLANK OR QUESTION MARK AS NO-NUMBER
- ;
- ;
- ; IF WE ARE HERE, THERE IS A DECIMAL NUMBER AT 5DH WAITING TO BE READ
- ;
- LXI H,0 ;H WILL CONTAIN THE VALUE OF THE NUMBER
- DIGIT: LDAX D ;GET NEXT DIGIT (ASCII)
- INX D ;INCREMENT DIGIT POINTER
- CPI ' '
- JZ TESTNO ;FINISHED GETTING NUMBER IF BLANK OR NULL
- ORA A ;TEST FOR NULL (0)
- JZ TESTNO
- SUI '0' ;SUBTRACT ASCII 0; THIS CONVERTS DIGIT TO NUMBER
- CPI 10 ;MAKE SURE IT WAS REALLY A DIGIT (0-9)
- JNC INVAL ;JUMP IF NOT
- DAD H ;DOUBLE ACCUMULATED VALUE
- PUSH H ;SAVE RESULT
- DAD H ;DOUBLE IT AGAIN
- DAD H ;AND AGAIN
- POP B ;NOW GET RESULT SAVE ABOVE AND ADD TO VALUE
- DAD B ;WE HAVE NOW MULTIPLIED VALUE BY 10
- MOV C,A ;NOW ADD TO IT THE VALUE OF THE NEW DIGIT
- MVI B,0
- DAD B
- JMP DIGIT ;AND GO BACK FOR NEXT DIGIT
- ;
- ;
- TESTNO: MOV A,H ;GET HIGH BYTE OF NUMBER OF K SPECIFIED
- ORA A ;IF IT'S NOT ZERO, NUMBER WAS 256 OR BIGGER
- JNZ INVAL ; AND THEREFORE NOT A VALID MEMORY SIZE
- MOV A,L ;GET LOW BYTE
- CPI 16 ;SYSTEM MUST BE AT LEAST 16K
- JC INVAL ; SO ERROR IF <16.
- ;
- ;
- ; NOW MULTIPY NO. OF K BY 1024 TO GET SPECIFIED MEMORY SIZE
- ;
- MVI L,0 ;L WAS SAVED IN A ABOVE
- MOV H,A ;THIS MULTIPLIES BY 256
- DAD H ;MULTIPLY BY 2
- DAD H ;MULTIPLY BY 2 AGAIN
- JMP PUTK ;GO TO NEXT SECTION WITH H=MEMORY SIZE IN BYTES
- ;
- ;
- INVAL: LXI D,INVMSG
- CALL MSG ;OUTPUT "INVALID MEMORY SIZE" MESAGE TO CONSOLE
- JMP REBOOT ;REBOOT SYSTEM
- ;
- ;
- INVMSG: DB CR,LF,'INVALID MEMORY SIZE$'
- ;
- ;
- ; COME HERE IF MEMORY SIZE WAS NOT SPECIFIED IN COMMAND LINE
- ;
- UNSPEC: LXI H,0 ;SET UP TO FIND MEMORY SIZE
- PAGE: INR H ;POINT TO 1ST LOCATION OF NEXT PAGE
- JZ FOUND ;GET OUT OF LOOP IF WE FOUND 256 PAGES OF MEMORY (WHY?)
- MOV A,M ;GET 1ST BYTE OF PAGE POINTED TO BY H
- CMA ;COMPLEMENT IT
- MOV M,A ; AND PUT IT BACK
- CMP M ;NOW READ BACK AND COMPARE
- CMA ;RESTORE MEMORY BEFORE JUMPING
- MOV M,A
- JZ PAGE ;KEEP LOOPING IF MEMORY VALID
- FOUND: MOV A,H ;L IS STILL ZERO, SO HL IS NUMBER OF BYTES OF MEMORY,
- ANI 0FCH ; TRUNCATED TO NEAREST 256. NOW ZERO BITS 0,1 OF H TO
- MOV H,A ; TRUNCATE TO A MULTIPLE OF 1024
- PUTK: PUSH H ;SAVE TRUNCATED MEMORY SIZE ON STACK
- ;
- LHLD ENTRY+1 ;GET STARTING ADDRESS OF PRESENT BDOS FROM THE JUMP AT LOC. 5
- MOV A,L ;SEE IF WE'RE IN DDT
- CPI 6
- JZ NOTDDT ;DDT CHANGES LOW BYTE
- INX H ;POINT TO ADDRESS OF BDOS IN DDT
- MOV A,M
- INX H
- MOV H,M
- MOV L,A
- NOTDDT: SHLD BDOS ;SAVE IT FOR LATER USE
- ;
- POP H ;GET MEMORY SIZE AGAIN
- PUSH H ; BUT LEAVE IT ON STACK TOP
- MOV A,H ;TAKE NUMBER OF PAGES AND DIVIDE BY 4 (INTEGER)
- RRC ;TO GET NUMBER OF K.
- RRC
- ANI 3FH
- MOV B,A ;SAVE NUMBER OF K IN B
- LXI H,CPMMSG+15 ;POINT TO OF NUMBER OF K (ASCII) IN "CONSTRUCTING" MESSAGE TEXT
- MVI A,'0' ;SET IT TO ASCII 00
- MOV M,A
- INX H
- MOV M,A
- CNVRT1: LXI H,CPMMSG+16 ;LOOP TO CONVERT NO. OF K TO DECIMAL ASCII (2 DIGITS)
- INR M ;INCREMENT LOW DIGIT
- MOV A,M ;GET ITS NEW VALUE
- CPI '9'+1
- JC CNV1A ;CONTINUE LOOP IF STILL IN THE RANGE '0' TO '9'
- MVI M,'0' ;ELSE SET IT TO ASCII 0 AND INCREMENT HIGH DIGIT.
- DCX H
- INR M
- CNV1A: DCR B ;DECREMENT REMAINDER OF NUMBER BEING CONVERTED
- JNZ CNVRT1 ; AND CONTINUE IN LOOP IF NOT YET ZERO
- ;
- ;
- LXI D,CPMMSG
- CALL MSG ;OUTPUT "CONSTRUCTING . . ." MESSAGE TO CONSOLE
- ;
- ;
- LXI H,SIZE ;GET LENGTH OF SYSTEM IN BYTES
- MOV C,M
- INX H
- MOV B,M
- PUSH B ;SAVE LENGTH IN B AND ON STACK
- ;
- ;
- ; SEARCH RELOC'S COPY OF THE SYSTEM FOR THE STRING "K CP/M VERS 1.3". THE
- ; SEARCH PRESENTLY BEGINS AT 900H AND CONTINUES THROUGH 900+LENGTH
- ;
- ;
- LXI H,SYSTEM
- SEARCH: LXI D,CPMMSG+17
- MOV A,B
- ORA C
- JZ NOFIND ;EXIT IF SEARCH COMPLETED WITHOUT FINDING STRING
- DCX B ;DECREMENT SEARCH COUNT AND SAVE ON STACK
- PUSH B
- ;
- MVI C,15 ;SET STRING LENGTH FOR COMPARE LOOP
- PUSH H ;SAVE CURRENTLY SEARCH ADDRESS ON STACK
- COMPR: LDAX D ;LOOP TO COMPARE STRINGS- D POINTS TO ONE, H TO THE OTHER
- CMP M
- JNZ NEWLOC ;GO TRY NEXT MEMORY POSITION IF COMPARISON FAILED
- INX D
- INX H
- DCR C
- JZ GOTIT
- JMP COMPR
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- NEWLOC: POP H ;GET SEARCH POINTER AGAIN
- INX H ;INCREMENT IT
- POP B ;RESTORE REMAINING SEARCH COUNT
- JMP SEARCH ;GO BACK TO LOOK FOR STRING AGAIN
- ;
- ;
- GOTIT: POP H ;STRING FOUND- GET ITS LOCATION
- POP B ;CLEAN UP STACK
- DCX H ;POINT TO 2ND DIGIT OF NUMBER OF K IN STRING
- LXI D,CPMMSG+16
- LDAX D ;GET ASCII NUMBER OF K FROM STRING, AND PUT IT INTO STRING JUST FOUND
- MOV M,A
- DCX H
- DCX D
- LDAX D
- MOV M,A
- ;
- ;
- ;
- ;
- NOFIND: LXI B,BDOS ;GET LOW BYTE OF CURRENT BDOS ADDRESS
- MVI A,0
- STAX B ;SET LOW BYTE OF BDOS ADDRESS TO ZERO, SO ADDRESS IS THAT OF SERIAL NUMBER
- ;
- ;
- ;
- ;
- POP B ;GET SYSTEM LENGTH
- POP H ;GET MEMORY SIZE IN BYTES
- MOV A,L ;SUBTRACT B FROM H TO GET MSIZE-LENGTH
- SUB C ; THIS IS ADDRESS NEW SYSTEM WILL RUN FROM
- MOV L,A
- MOV A,H
- SBB B
- MOV H,A
- SHLD NEWSYS ;SAVE THIS ADDRESS AT NEWSYS AND IN D
- XCHG
- ;
- ;
- ;
- ;
- LXI H,SYSTEM ;POINT TO BEGINNING OF SYSTEM LOADED WITH RELOC.COM
- PUSH B ;SAVE LENGTH
- ;
- LDA NAME2 ;GET 2ND ITEM IN COMMAND LINE
- CPI ' ' ;IF BLANK, SYSTEM IS TO BE PLACED AT ITS EXECUTION ADDRESS
- JZ EXEC
- DAD B ;SET H TO POINT TO FIRST LOC. AFTER SYSTEM (START OF RELOCATION TABLE)
- JMP REL1
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ;
- ; IF 2ND ITEM IN COMMAND WAS BLANK, THEN COME HERE TO MOVE A COPY
- ; OF THE SYSTEM FROM 900 TO ITS EVENTUAL EXECUTION ADDRESS.
- ;
- ;
- EXEC: MOV A,B
- ORA C
- JZ REL1
- DCX B
- MOV A,M
- STAX D
- INX D
- INX H
- JMP EXEC
- ;
- ;
- ;
- ;
- ; LOOP TO PERFORM THE RELOCATION.
- ; MSIZE-LENGTH+100H IS ADDED TO EACH ADDRESS
- ; MARKED BY A '1' IN THE RELOCATION BIT TABLE.
- ;
- ;
- REL1: POP B ;GET LENGTH
- PUSH H ;SAVE TABLE ADDRESS
- LHLD NEWSYS
- XCHG ;ADDRESS OF NEW SYSTEM IN D
- LXI H,100H
- DAD D ;H IS NOW NEWSYS+100H
- ;
- ;
- LDA NAME2 ;GET 2ND COMMAND ITEM AGAIN
- CPI ' '
- JZ REL2
- LXI D,SYSTEM ;IF NOT A SPACE, SET D TO PUT NEW SYSTEM IN PLACE FOR SYSGEN
- REL2: MOV A,B
- ORA C
- JZ FINISH ;JUMP IF COUNT HAS REACHED ZERO
- JMP REL3
- ;
- ;
- ;
- ;
- REL3: DCX B ;DECREMENT BYTE COUNT
- MOV A,E ;GET LOW BYTE OF CURRENT ADDRESS IN NEW SYSTEM
- ANI 7 ;IF IT IS A MULTIPLE OF 8, WE NEED TO GET ANOTHER
- JNZ REL4 ; BYTE OF THE RELOCATION TABLE
- XTHL ;GET H=CURRENT ADDRESS IN TABLE
- MOV A,M ;GET THE BYTE THERE
- INX H ;INCREMENT TABLE ADDRESS
- XTHL ;PUT IT BACK ON STACK
- MOV L,A
- REL4: MOV A,L ;TEST NEXT BIT OF CURRENT TABLE BYTE
- RAL
- MOV L,A
- JNC REL5 ;IF NOT SET, CONTINUE IN LOOP
- LDAX D ;GET HIGH BYTE OF ADDRESS AT CURRENT LOCATION IN NEW SYSTEM
- ADD H ;ADD HIGH BYTE OF 100H+EXECUTION ADDRESS
- STAX D ; AND PUT BACK IN NEW SYSTEM
- JMP REL5
- REL5: INX D ;POINT TO NEXT BYTE OF NEW SYSTEM
- JMP REL2
- ;
- ;
- ;
- ;
- FINISH: POP D ;CLEAN UP STACK
- ;
- ;
- ; COPY SERIAL NUMBER FROM SYSTEM CURRENTLY IN USE (INTO NEW SYSTEM)
- ;
- ;
- LXI D,SERIALB ;ADDR OF BDOS SERIAL IN RELOC.COM
- CALL SERPUT
- LXI D,SERIALC ;ADDR OF CCP SERIAL IN RELOC.COM
- CALL SERPUT
- JMP SER2
- ;
- SERPUT: LHLD BDOS ;ADDRESS OF SERIAL NO. IN CURRENT SYSTEM
- MVI C,6 ;LOOP COUNT
- SERLP: MOV A,M
- STAX D
- INX H
- INX D
- DCR C
- JNZ SERLP
- RET
- SER2:
- ;
- ;
- ; IF SYSTEM WAS PUT AT EXECUTION ADDRESS, GO THERE
- ;
- LDA NAME2
- CPI ' '
- JZ SYSGO
- ;
- ;
- ; IF 900-97F IS ALL ZEROES, THEN MOVE THE WHOLE SYSTEM DOWN 80H BYTES
- ; FROM 980 TO 900
- ;
- ;
- MVI B,80H
- LXI H,SYSTEM
- TEST1: MOV A,M
- ORA A
- JNZ NOMOVE
- INX H
- DCR B
- JNZ TEST1
- ;
- XCHG ;D IS 980H
- LHLD SIZE ;GET SYSTEM LENGTH
- LXI B,-80H
- DAD B
- MOV B,H
- MOV C,L ;BC = LENGTH-128
- LXI H,900H
- MOVE: MOV A,B
- ORA C
- JZ NOMOVE
- DCX B
- LDAX D
- MOV M,A
- INX D
- INX H
- JMP MOVE
- ;
- ;
- ;
- ;
- NOMOVE: LXI H,SIZE
- MOV C,M
- INX H
- MOV B,M ;B = LENGTH
- LXI H,900H
- DAD B
- MOV B,H ;C IS ALREADY ZERO- NOW B IS NUMBER OF PAGES IN NEW SYSTEM
- ;
- ;
- ; PUT NUMBER OF PAGES IN THE NEW SYSTEM INTO THE "SAVE NN . . ." MESSAGE TEXT
- ;
- LXI H,ENDMSG+31
- MVI A,30H
- MOV M,A
- INX H
- MOV M,A
- PUTN: DCR B
- JZ PUTK2
- LXI H,ENDMSG+32
- INR M
- MOV A,M
- CPI '9'+1
- JC PUTN
- MVI M,30H
- DCX H
- INR M
- JMP PUTN
- ;
- ;
- PUTK2: LHLD CPMMSG+15
- SHLD ENDMSG+37 ;PUT NO. OF K IN MESSAGE
- LXI D,ENDMSG
- CALL MSG ;OUTPUT MESSAGE TO CONSOLE
- JMP REBOOT ;RETURN TO CP/M
- ;
- ;
- ;
- ;
- ENDMSG: DB CR,LF,'READY FOR "SYSGEN" OR',CR,LF
- DB '"SAVE 00 CPM00.COM"$'
- ;
- ;
- ;
- ;
- SYSGO: LXI D,1600H
- LHLD NEWSYS
- DAD D
- PCHL ;JUMP TO NEW SYSTEM
- ;
- ;
- ;
- ;
- MSG: MVI C,9
- SYSCAL: JMP ENTRY
- BDOS DW 0
- NEWSYS DW 0
- ;
- CPMMSG: DB CR,LF,'CONSTRUCTING 00K CP/M VERS 1.3$'
- ;
- ;
- ;
- ;
- END
-