Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 2.X/CPM 2.2/CPM 2.2 SOURCE/CPMOVE.ASM
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

422 lines
8.1 KiB
NASM

TITLE 'CP/M VERSION 2.2 SYSTEM RELOCATOR - 2/80'
; 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 22 ;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