mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
422 lines
8.6 KiB
NASM
422 lines
8.6 KiB
NASM
TITLE 'CP/M VERSION 2.0 SYSTEM RELOCATOR - 8/79'
|
||
; CPM RELOCATOR PROGRAM, INCLUDED WITH THE MODULE TO PERFORM
|
||
; THE MOVE FROM 900H TO THE DESTINATION ADDRESS
|
||
;
|
||
; COPYRIGHT (C) 1979
|
||
; DIGITAL RESEARCH
|
||
; BOX 579, PACIFIC GROVE CALIFORNIA
|
||
; 93950
|
||
;
|
||
ORG 100H
|
||
JMP PASTCOPY
|
||
COPY: DB 'COPYRIGHT (C) DIGITAL RESEARCH, 1979 '
|
||
PASTCOPY:
|
||
BIOSWK EQU 03H ;THREE PAGES FOR BIOS WORKSPACE
|
||
STACK EQU 800H
|
||
MODSIZ EQU 801H ;MODULE SIZE IS STORED HERE
|
||
VERSION EQU 20 ;CPM VERSION NUMBER
|
||
BOOTSIZ EQU 100H ;SIZE OF THE COLD START LOADER
|
||
; (MAY HAVE FIRST 80H BYTES = 00H)
|
||
BDOSL EQU 0800H ;RELATIVE LOCATION OF BDOS
|
||
BIOS EQU 1600H ;RELATIVE LOCATION OF BIOS
|
||
;
|
||
BOOT EQU 0000H ;REBOOT LOCATION
|
||
BDOS EQU 0005H
|
||
PRNT EQU 9 ;PRINT BUFFER FUNCTION
|
||
FCB EQU 5CH ;DEFAULT FCB
|
||
MODULE EQU 900H ;MODULE ADDRESS
|
||
;
|
||
CR EQU 0DH
|
||
LF EQU 0AH
|
||
LXI SP,STACK
|
||
;
|
||
; MAY BE MEMORY SIZE SPECIFIED IN COMMAND
|
||
LXI D,FCB+1
|
||
LDAX D
|
||
CPI ' '
|
||
JZ FINDTOP
|
||
CPI '?' ;WAS * SPECIFIED?
|
||
JZ FINDTOP
|
||
;
|
||
; MUST BE MEMORY SIZE SPECIFICATION
|
||
LXI H,0
|
||
CLOOP: ;CONVERT TO DECIMAL
|
||
LDAX D
|
||
INX D
|
||
CPI ' '
|
||
JZ ECON
|
||
ORA A
|
||
JZ ECON
|
||
; MUST BE DECIMAL DIGIT
|
||
SUI '0'
|
||
CPI 10
|
||
JNC CERROR
|
||
; DECIMAL DIGIT IS IN A
|
||
DAD H ;*2
|
||
PUSH H
|
||
DAD H ;*4
|
||
DAD H ;*8
|
||
POP B ;*2 IN B,C
|
||
DAD B ;*10 IN H,L
|
||
MOV C,A
|
||
MVI B,0
|
||
DAD B ;*10+X
|
||
JMP CLOOP
|
||
ECON: ;END OF CONVERSION, CHECK FOR PROPER RANGE
|
||
MOV A,H
|
||
ORA A
|
||
JNZ CERROR
|
||
MOV A,L
|
||
CPI 16
|
||
JC CERROR
|
||
MVI L,0
|
||
MOV H,A
|
||
DAD H ;SHL 1
|
||
DAD H ;SHL 2 FOR KILOBYTES
|
||
; H,L HAVE TOP OF MEMORY+1
|
||
JMP SETASC
|
||
;
|
||
CERROR:
|
||
LXI D,CONMSG
|
||
CALL PRINT
|
||
JMP BOOT
|
||
CONMSG: DB CR,LF,'INVALID MEMORY SIZE$'
|
||
;
|
||
;
|
||
; FIND END OF MEMORY
|
||
FINDTOP:
|
||
LXI H,0
|
||
FINDM: INR H ;TO NEXT PAGE
|
||
JZ MSIZED ;CAN OVERFLOW ON 64K SYSTEMS
|
||
MOV A,M
|
||
CMA
|
||
MOV M,A
|
||
CMP M
|
||
CMA
|
||
MOV M,A ;BITS INVERTED FOR RAM OPERATIONAL TEST
|
||
JZ FINDM
|
||
; BITS DIDN'T CHANGE, MUST BE END OF MEMORY
|
||
; ALIGN ON EVEN BOUNDARY
|
||
MSIZED: MOV A,H
|
||
ANI 1111$1100B ;EVEN 1K BOUNDARY
|
||
MOV H,A
|
||
SETASC: ;SET ASCII VALUE OF MEMORY SIZE
|
||
PUSH H ;SAVE FOR LATER
|
||
; **** SERIALIZATION ****
|
||
LHLD BDOS+1
|
||
SHLD SER1
|
||
; **** SERIALIZATION ****
|
||
POP H
|
||
PUSH H
|
||
MOV A,H
|
||
RRC
|
||
RRC
|
||
ANI 11$1111B ;FOR 1K COUNTS
|
||
JNZ NOT64 ;MAY BE 64 K MEM SIZE
|
||
MVI A,64 ;SET TO LITERAL IF SO
|
||
NOT64: MOV B,A ;READY FOR COUNT DOWN
|
||
LXI H,AMEM
|
||
MVI A,'0'
|
||
MOV M,A
|
||
INX H
|
||
MOV M,A ;BOTH ARE SET TO ASCII 0
|
||
ASC0: LXI H,AMEM+1 ;ADDRESS OF ASCII EQUIVALENT
|
||
INR M
|
||
MOV A,M
|
||
CPI '9'+1
|
||
JC ASC1
|
||
MVI M,'0'
|
||
DCX H
|
||
INR M
|
||
ASC1: DCR B ;COUNT DOWN BY KILOBYTES
|
||
JNZ ASC0
|
||
LXI D,MEMSG
|
||
CALL PRINT ;MEMORY SIZE MESSAGE
|
||
;
|
||
LXI H,MODSIZ
|
||
MOV C,M
|
||
INX H
|
||
MOV B,M ;B,C CONTAINS MODULE SIZE
|
||
PUSH B ;MODULE SIZE STACKED ON MEM SIZE
|
||
;
|
||
; TRY TO FIND THE ASCII STRING 'K CP/M VER X.X' TO SET SIZE
|
||
LXI H,MODULE
|
||
; B,C CONTAINS MODULE LENGTH
|
||
SLOOP: ;SEARCH LOOP
|
||
LXI D,AMSG
|
||
MOV A,B
|
||
ORA C
|
||
JZ ESEAR ;END OF SEARCH
|
||
DCX B ;COUNT SEARCH LENGTH DOWN
|
||
PUSH B
|
||
MVI C,LAMSG ;LENGTH OF SEARCH MESSAGE
|
||
PUSH H ;SAVE BASE ADDRESS OF SEARCH
|
||
CHLOOP: ;CHARACTER LOOP, MATCH ON CONTENTS OF D,E AND H,L
|
||
LDAX D
|
||
CMP M
|
||
JNZ NOMATCH
|
||
INX D ;TO NEXT SEARCH CHARACTER
|
||
INX H ;TO NEXT MATCH CHARACTER
|
||
DCR C ;COUNT LENGTH DOWN
|
||
JZ FSEAR ;FOUND SEARCH STRING
|
||
JMP CHLOOP
|
||
;
|
||
; **** SERIALIZATION ****
|
||
DB LXI ;CONFUSE DISASSEMBLER
|
||
BADSER: ;BAD SERIAL NUMBER, LOOP TO CONFUSE ICE-80
|
||
XRA A
|
||
BADSER0:
|
||
DCR A
|
||
JNZ BADSER0
|
||
;
|
||
LXI H,DI OR (HLT SHL 8)
|
||
SHLD PRHLT
|
||
LXI H,PRJMP
|
||
MVI M,CALL ;CHANGE JMP BDOS TO CALL
|
||
LXI D,SYNCMSG-5
|
||
LXI H,5
|
||
DAD D ;TO CONFUSE SEARCHES ON ADDRESSES
|
||
XCHG
|
||
JMP PRINT
|
||
; **** SERIALIZATION ****
|
||
;
|
||
NOMATCH:
|
||
;NOT FOUND AT THIS ADDRESS, LOOK AT NEXT ADDRESS
|
||
POP H
|
||
INX H
|
||
POP B ;RECALL MODULE LENGTH
|
||
JMP SLOOP
|
||
;
|
||
FSEAR:
|
||
;FOUND STRING, SET MEMORY SIZE
|
||
POP H ;START ADDRESS OF STRING BEING MATCHED
|
||
POP B ;CLEAR B,C WHICH WAS STACKED
|
||
DCX H
|
||
LXI D,AMEM+1
|
||
LDAX D
|
||
MOV M,A
|
||
DCX H
|
||
DCX D
|
||
LDAX D
|
||
MOV M,A
|
||
; END OF FILL
|
||
;
|
||
ESEAR: ;END OF SEARCH
|
||
; **** SERIALIZATION ****
|
||
; CHECK FOR LEAST SIGNIFICANT BYTE OF 06 IN SER1
|
||
LXI B,SER1
|
||
LDAX B
|
||
CPI 6
|
||
MVI A,0
|
||
JNZ SETJMP ;BAD SERIALIZATION IF NOT 06
|
||
STAX B ;STORE 00 TO LEAST SIGNIFICANT BYTE
|
||
; **** SERIALIZATION ****
|
||
POP B ;RECOVER MODULE LENGTH
|
||
POP H ;H,L CONTAINS END OF MEMORY
|
||
PUSH B ;SAVE LENGTH FOR RELOCATION BELOW
|
||
MOV A,B
|
||
ADI BIOSWK ;ADD BIOS WORK SPACE TO MODULE LENGTH
|
||
MOV B,A
|
||
MOV A,L
|
||
SUB C ;COMPUTE MEMTOP-MODULE SIZE
|
||
MOV L,A
|
||
MOV A,H
|
||
SBB B
|
||
MOV H,A
|
||
; H,L CONTAINS THE BASE OF THE RELOCATION AREA
|
||
SHLD RELBAS ;SAVE THE RELOCATION BASE
|
||
XCHG ;MODULE BASE TO D,E
|
||
LXI H,MODULE;READY FOR THE MOVE
|
||
POP B ;RECOVER ACTUAL MODULE LENGTH
|
||
PUSH B ;SAVE FOR RELOCATION
|
||
LDA FCB+17 ;CHECK FOR NO MOVE CONDITION
|
||
CPI ' '
|
||
JZ MOVE
|
||
; SECOND PARAMETER SPECIFIED, LEAVE THE DATA AT 'MODULE'
|
||
DAD B ;MOVE H,L TO BIT MAP POSITION
|
||
JMP RELOC
|
||
;
|
||
; **** SERIALIZATION ****
|
||
SETJMP: LXI H,BADSER ;BAD SERIALIZATION
|
||
SHLD JMPSER+1 ;FILL JUMP INSTRUCTION
|
||
JMP JMPSER ;EVENTUAL JUMP TO MESSAGE
|
||
; **** SERIALIZATION ****
|
||
;
|
||
MOVE:
|
||
MOV A,B ;BC=0?
|
||
ORA C
|
||
JZ RELOC
|
||
DCX B ;COUNT MODULE SIZE DOWN TO ZERO
|
||
MOV A,M ;GET NEXT ABSOLUTE LOCATION
|
||
STAX D ;PLACE IT INTO THE RELOC AREA
|
||
INX D
|
||
INX H
|
||
JMP MOVE
|
||
;
|
||
RELOC: ;STORAGE MOVED, READY FOR RELOCATION
|
||
; HL ADDRESSES BEGINNING OF THE BIT MAP FOR RELOCATION
|
||
POP B ;RECALL MODULE LENGTH
|
||
PUSH H ;SAVE BIT MAP BASE IN STACK
|
||
LHLD RELBAS
|
||
XCHG
|
||
LXI H,BOOTSIZ
|
||
DAD D ;TO FIND BIAS VALUE
|
||
; REGISTER H CONTAINS BIAS VALUE
|
||
;
|
||
; RELOCATE AT 'MODULE' IF SECOND PARAMETER GIVEN
|
||
LDA FCB+17
|
||
CPI ' '
|
||
JZ REL0
|
||
;
|
||
; IMAGE NOT MOVED, ADJUST VALUES AT 'MODULE'
|
||
LXI D,MODULE
|
||
REL0: MOV A,B ;BC=0?
|
||
ORA C
|
||
JZ ENDREL
|
||
; **** SERIALIZATION ****
|
||
JMP PASTSYNC
|
||
SYNCMSG:
|
||
DB CR,LF,'SYNCRONIZATION ERROR$'
|
||
PASTSYNC:
|
||
; **** SERIALIZATION ****
|
||
;
|
||
; NOT END OF THE RELOCATION, MAY BE INTO NEXT BYTE OF BIT MAP
|
||
DCX B ;COUNT LENGTH DOWN
|
||
MOV A,E
|
||
ANI 111B ;0 CAUSES FETCH OF NEXT BYTE
|
||
JNZ REL1
|
||
; FETCH BIT MAP FROM STACKED ADDRESS
|
||
XTHL
|
||
MOV A,M ;NEXT 8 BITS OF MAP
|
||
INX H
|
||
XTHL ;BASE ADDRESS GOES BACK TO STACK
|
||
MOV L,A ;L HOLDS THE MAP AS WE PROCESS 8 LOCATIONS
|
||
REL1: MOV A,L
|
||
RAL ;CY SET TO 1 IF RELOCATION NECESSARY
|
||
MOV L,A ;BACK TO L FOR NEXT TIME AROUND
|
||
JNC REL2 ;SKIP RELOCATION IF CY=0
|
||
;
|
||
; CURRENT ADDRESS REQUIRES RELOCATION
|
||
LDAX D
|
||
ADD H ;APPLY BIAS IN H
|
||
STAX D
|
||
JMP REL2
|
||
;
|
||
REL2: INX D ;TO NEXT ADDRESS
|
||
JMP REL0 ;FOR ANOTHER BYTE TO RELOCATE
|
||
;
|
||
ENDREL: ;END OF RELOCATION
|
||
POP D ;CLEAR STACKED ADDRESS
|
||
; **** SERIALIZATION ****
|
||
LXI D,MODULE+BDOSL+BOOTSIZ ;ADDRESSING NEW SERIAL NUMBER
|
||
LHLD SER1 ;ADDRESSING HOST SERIAL NUMBER
|
||
MVI C,6 ;LENGTH OF SERIAL NUMBER
|
||
CHKSER: LDAX D
|
||
CMP M
|
||
JNZ SETJMP
|
||
INX H
|
||
INX D
|
||
DCR C
|
||
JNZ CHKSER
|
||
; **** SERIALIZATION ****
|
||
;
|
||
LDA FCB+17
|
||
CPI ' '
|
||
JZ TRANSFER
|
||
; DON'T GO TO THE LOADED PROGRAM, LEAVE IN MEMORY
|
||
; MAY HAVE TO MOVE THE PROGRAM IMAGE DOWN 1/2 PAGE
|
||
MVI B,128 ;CHECK FOR 128 ZEROES
|
||
LXI H,MODULE
|
||
TR0: MOV A,M
|
||
ORA A
|
||
JNZ TREND
|
||
INX H
|
||
DCR B
|
||
JNZ TR0
|
||
;
|
||
; ALL ZERO FIRST 1/2 PAGE, MOVE DOWN 80H BYTES
|
||
XCHG ;NEXT TO GET IN D,E
|
||
LHLD MODSIZ
|
||
LXI B,-128
|
||
DAD B ;NUMBER OF BYTES TO MOVE IN H,L
|
||
MOV B,H
|
||
MOV C,L ;TRANSFERRED TO B,C
|
||
LXI H,MODULE;DESTINATION IN H,L
|
||
TRMOV: MOV A,B
|
||
ORA C ;ALL MOVED?
|
||
JZ TREND
|
||
DCX B
|
||
LDAX D
|
||
MOV M,A ;ONE BYTE TRANSFERRED
|
||
INX D
|
||
INX H
|
||
JMP TRMOV
|
||
;
|
||
;
|
||
; **** SERIALIZATION ****
|
||
DB LXI
|
||
JMPSER: JMP JMPSER ;ADDRESS FIELD FILLED-IN
|
||
; **** SERIALIZATION ****
|
||
;
|
||
TREND: ;SET ASCII MEMORY IMAGE SIZE
|
||
LXI H,MODSIZ
|
||
MOV C,M
|
||
INX H
|
||
MOV B,M
|
||
LXI H,MODULE;B,C MODULE SIZE, H,L BASE
|
||
DAD B
|
||
MOV B,H ;B CONTAINS NUMBER OF PAGES TO SAVE+1
|
||
LXI H,SAVMEM;ASCII MEMORY SIZE
|
||
MVI A,'0'
|
||
MOV M,A
|
||
INX H
|
||
MOV M,A
|
||
; '00' STORED INTO MESSAGE
|
||
TRCOMP:
|
||
DCR B
|
||
JZ TRC1
|
||
LXI H,SAVMEM+1 ;ADDRESSING LEAST DIGIT
|
||
INR M
|
||
MOV A,M
|
||
CPI '9'+1
|
||
JC TRCOMP
|
||
MVI M,'0'
|
||
DCX H
|
||
INR M
|
||
JMP TRCOMP
|
||
; FILL CPMXX.COM FROM SAVMEM
|
||
TRC1: LHLD AMEM
|
||
SHLD SAVM0
|
||
; MESSAGE SET, PRINT IT AND REBOOT
|
||
LXI D,RELOK
|
||
CALL PRINT
|
||
JMP BOOT
|
||
RELOK: DB CR,LF,'READY FOR "SYSGEN" OR'
|
||
DB CR,LF,'"SAVE '
|
||
SAVMEM: DB '00 CPM'
|
||
SAVM0: DB '00.COM"$'
|
||
;
|
||
TRANSFER:
|
||
; GO TO THE RELOCATED MEMORY IMAGE
|
||
LXI D,BOOTSIZ+BIOS ;MODULE
|
||
LHLD RELBAS ;RECALL BASE OF RELOC AREA
|
||
DAD D ;INDEX TO 'BOOT' ENTRY POINT
|
||
PCHL ;GO TO RELOCATED PROGRAM
|
||
;
|
||
; **** SERIALIZATION ****
|
||
PRINT:
|
||
MVI C,PRNT
|
||
PRJMP: JMP BDOS
|
||
PRHLT:
|
||
;
|
||
; DATA AREAS
|
||
SER1: DS 2 ;SERIAL NUMBER ADDRESS FOR HOST
|
||
RELBAS: DS 2 ;RELOCATION BASE
|
||
MEMSG: DB CR,LF,'CONSTRUCTING '
|
||
AMEM: DB '00'
|
||
AMSG: DB 'k CP/M vers '
|
||
DB VERSION/10+'0','.',VERSION MOD 10 +'0'
|
||
LAMSG EQU $-AMSG ;LENGTH OF MESSAGE
|
||
DB '$' ;TERMINATOR FOR MESSAGE
|
||
END
|
||
|