Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

422 lines
8.6 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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