Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

View File

@@ -0,0 +1,992 @@
M EQU Byte Ptr 0[BX]
; title 'Serialization Program for MP/M-86 09/14/81'
version EQU 20 ;version 2.0
system EQU 1 ;MP/M 86 system
; Serialization Program for MP/M 86 diskettes
; Note **********************************************************
; This program contains Digital Research proprietary information,
; and must not be reproduced, copied, or transcribed in any form
; whatsoever
; ***************************************************************
; Copyright (C) 1979, 1980, 1981
; Digital Research
; Box 579 Pacific Grove
; California, 93950
; Revised:
; 14 Sept 81 by Thomas Rolander (MP/M II 8080)
; 18 Sept 81 by Danny Horovitz (MP/M-8086)
; '$' signs taken out of identifiers and labels for
; ASM86 compatibility, names of serialized
; programs changed, only one disk to be serialized
tpa EQU 100h ;transient program area
ORG tpa
JMP start
L@1 EQU $
DSEG
ORG Offset L@1
Copyright RS 0
DB 'COPYRIGHT (C) 1981,'
DB ' DIGITAL RESEARCH '
L@2 EQU $
CSEG
ORG Offset L@2
L@3:
CoNmLen EQU (Offset $)-(Offset Copyright)
;
; global equates
boot EQU 0000h
bdos EQU 0005h
;
; BDOS equates
conin EQU 1 ;read console device
conout EQU 2 ;write console device
pbuff EQU 9 ;print buffer
rdbuff EQU 10 ;read buffer
resetds EQU 13 ;reset disk system
selectd EQU 14 ;select disk
openf EQU 15 ;open file
rdseqf EQU 20 ;read sequential file
wrseqf EQU 21 ;write sequential file
stdmadr EQU 26 ;set DMA address
dirbios EQU 50 ;direct BIOS call-CP/M-86
; Hardware dependent equates
begtrk EQU 0 ;beginning track #
dirtrk EQU 2 ;directory track #
maxtrk EQU 76 ;maximum track #
sectrk EQU 26 ;sectors per track
srcdsk EQU 2 ;source disk
dstdsk EQU 3 ;destination disk
secsiz EQU 128 ;sector size in # bytes
nsrlsec EQU 4 ;# of sectors to search serial #
cr EQU 0dh
lf EQU 0ah
;
readtrk EQU (Offset $)
writtrk EQU (Offset $)+3
reread EQU (Offset $)+6
; track read/write routines, filled in later
JMPS readdisk
L@4:
JMPS writedisk
L@5:
JMPS rereaddisk
L@6 EQU $
DSEG
ORG Offset L@6
track RS 1 ;set to track to read/write
buffa RS 2 ;set to buffer address to read/write
iof RS 1 ;io function 0 = read, 1 = write
L@7 EQU $
CSEG
ORG Offset L@7
;
readdisk:
;read disk drive a, from track 'track'
;into the address given by 'buffa'
MOV cl,srcdsk
CALL sel ;select src drive
JMPS readd
;
;
writedisk:
;write to disk drive b, to track 'track'
;from the address given by 'buffa'
MOV AL,1
MOV Byte Ptr iof,AL ;set iofunction to write
MOV cl,dstdsk
CALL sel ;select dst drive
JMPS rwdisk
;
rereaddisk:
;read from dstdsk, from track 'track'
;to the address given by 'buffa'
MOV cl,dstdsk
CALL sel ;dst drive selected
readd: XOR AL,AL
MOV Byte Ptr iof,AL ;set to read function
rwdisk: ;read or write disk
MOV BX,(Offset track)
MOV CL,M ;get track number
CALL trk ;track selected
MOV BX,Word Ptr buffa ;get dma address
MOV DX,sectrk ;d = 0, e = sectors per track
rwloop: ;read/write loop
INC DH ;to next sector
PUSH DX
PUSH BX
MOV CL,DH
MOV CH,0
MOV BX,(Offset skewtbl)
MOV AL,M
OR AL,AL
JZ noskew ;jump if no skew table
DEC CL
LAHF
ADD BX,CX
SAHF
MOV CL,M
noskew:
CALL sec ;sector set
POP CX
PUSH CX ;get dma address
CALL dma ;dma address set
;perform io function
MOV AL,Byte Ptr iof
OR AL,AL ;0=read, 1=write
JNZ writefunc
;read disk
CALL dread
JMPS rwcomplete
writefunc:
;write disk
CALL dwrite
rwcomplete: ;function complete
POP BX ;recall dma address
MOV DX,secsiz
ADD BX,DX ;to nxt dma
POP DX ;recall sector and count
; check error conditions
OR AL,AL
JZ L@8
RET ;rtn with non zero flag set
L@8:
DEC DL ;count = count - 1
JNZ rwloop ;for another sector
RET ;with zero flag set for io complete
;
;
; utility subroutines for direct disk io
seldsk EQU 9 ;select disk
settrk EQU 10 ;set track
setsec EQU 11 ;set sector
setdma EQU 12 ;set dma address
readf EQU 13 ;read disk
writef EQU 14 ;write disk
;
sel: ;select drive given by register cl
MOV al,seldsk
jmps bios
;
trk: ;set track given by cl
mov al,settrk
jmps bios
;
sec: ;set sector given by cl
mov al,setsec
jmps bios
;
dma: ;set dma address to value of cx
mov al,setdma
jmps bios
;
dread: ;perform read operation
mov al,readf
jmps bios
;
dwrite: ;perform write operation
mov al,writef
jmps bios
;definition of direct BIOS parameter block
bpb_func equ 0
bpb_CX equ 1
bpb_DX equ 3
bios:
mov bx,offset bpb ;bios parameter block
mov bpb_func[bx],al
mov bpb_cx[bx],cx
mov bpb_dx[bx],dx
mov cl,dirbios
mov dx,bx
int 224
ret
;
start:
MOV SP,(Offset stack)
CALL signonmsg ;display sign on message
CALL sysdskmsg
CALL ci ;system disk serialize ?
AND AL,0dfh
CMP AL,'Y'
MOV AL,dirtrk
JNZ sd1
MOV BX,(Offset sysdsk)
INC M
MOV AL,begtrk
sd1: MOV Byte Ptr strtrk,AL
CALL dskslctmsg
CALL read ;select 1/2, 2/2, or 1/2 & 2/2
MOV BX,(Offset disk)
MOV M,CL
CALL orgmsg
CALL read ;origin prompt
MOV BX,(Offset origin)
MOV M,CL ;saved the origin number
INC BX
MOV M,CH ;high order origin number byte
MOV BX,(Offset comlen)
MOV CH,M
INC BX
XCHG BX,DX
MOV BX,(Offset aorigin) ;ascii version of the origin
org2: MOV SI,DX
MOV AL,[SI]
OR AL,AL
JZ org3
INC DX
MOV M,AL
INC BX
DEC CH
JNZ org2
;ascii version moved to buffer, pad it
org3: MOV M,'-'
INC BX
MOV M,'$' ;ready for printing
;
; now read the serial number
CALL sermsg
CALL read
MOV BX,(Offset bserial)
MOV M,CL
INC BX
MOV M,CH ;binary copied
MOV BX,(Offset comlen)
MOV AL,5
SUB AL,M ;difference in reg-a
MOV BX,(Offset aserial)
JZ pad1 ;pad high order positions with 0
pad0: MOV M,'0'
INC BX
DEC AL
JNZ pad0
pad1: MOV DX,(Offset cbuff) ;addressing buffer
pad2: MOV SI,DX
MOV AL,[SI]
OR AL,AL
JZ pad3 ;looking for binary 0
MOV M,AL
INC BX
INC DX
JMPS pad2 ;another char
pad3: ;end of ascii fill (right adjusted in aserial)
;
rddsk: ;read disk and copy
MOV SP,(Offset stack) ;reset stack pointer (entry from errors)
CALL insmsg
CALL ci ;wait for response
;
nextdisk:
CALL curmsg
CALL asermsg
CALL newmsg
CALL ci
;new disk is ready, try the copy operation
MOV AL,Byte Ptr strtrk ;get start track
MOV BX,(Offset track)
MOV M,AL ;initialize the track number
MOV BX,(Offset trcount)
MOV M,'0'
LAHF
INC BX
SAHF
MOV M,'0'
;
rdtrk: ;read the next source track, compare with 0e5h for end
MOV BX,(Offset ibuff)
MOV Word Ptr buffa,BX
CALL L@3
JZ readok
CALL read0msg
JMPS rddsk
readok:
;track is in memory, track 0?
MOV AL,Byte Ptr track
OR AL,AL
;if track 0, do MPMLDR serialization
JNZ L@9
CALL serialize
L@9:
;
;track in memory, check for last track
MOV BX,(Offset ibuff)
MOV CX,trlen
trcomp: MOV AL,0e5h
CMP AL,M
JNZ wrtrk
INC BX
DEC CX
MOV AL,CL
OR AL,CH
JNZ trcomp
;end of copy, all 0e5h's
endcopy:
;write serial # into files in FCB table
MOV AL,Byte Ptr sysdsk
OR AL,AL
MOV BX,(Offset FCBtabledisk1)
JZ nonsysdsk
MOV BX,(Offset FCBtablesysdisk1)
nonsysdsk:
;write serial # into disk1
MOV AL,Byte Ptr disk
AND AL,01h
JZ L@10
CALL srlfile
L@10:
;write serial # into disk2
MOV BX,(Offset FCBtabledisk2)
MOV AL,Byte Ptr disk
AND AL,02h
JZ L@11
CALL srlfile
L@11:
MOV DX,(Offset trmsg)
CALL prmsg
CALL incserial
JMP nextdisk
;
;not end of copy, write track to disk from ibuff
wrtrk: CALL L@4
JZ wrok
CALL write0msg
JMP nextdisk
wrok:
;written to disk, now read it back and compare
MOV BX,(Offset obuff)
MOV Word Ptr buffa,BX
CALL L@5
JZ read1ok
CALL read1msg
JMP nextdisk
read1ok:
MOV BX,(Offset ibuff)
MOV DX,(Offset obuff)
MOV CX,trlen
wrcomp: MOV SI,DX
MOV AL,[SI]
CMP AL,M
JNZ wrerr
INC BX
INC DX
DEC CX
MOV AL,CL
OR AL,CH
JNZ wrcomp
;compare ok, increment track count and cycle
MOV BX,(Offset track)
INC M
MOV AL,maxtrk+1
CMP AL,M
;jump if last track on disk copied
JNZ L@12
JMP endcopy
L@12:
MOV BX,(Offset trcount)+1
INC M
MOV AL,M
CMP AL,'9'+1
JNB L@13
JMP rdtrk ;overflow to high order track number
L@13:
MOV M,'0'
LAHF
DEC BX
SAHF
INC M
JMP rdtrk
;
wrerr: ;verify error
CALL vererr
JMP nextdisk
;
;
; utility subroutines
ci: MOV CL,conin
INT 224 ;read a character
RET
;
prmsg: MOV CL,pbuff
INT 224 ;print a buffer
RET
;
rderr: CALL invalid
;
read: ;read constant value to b,c
MOV DX,(Offset maxlen)
MOV CL,rdbuff
INT 224 ;buffer filled
MOV BX,(Offset comlen)
MOV AL,M
OR AL,AL
JZ rderr ;non zero length
INC BX
MOV DL,AL
MOV DH,0
ADD BX,DX ;h,l address last pos+1
MOV M,0 ;cleared for end of scan
MOV BX,(Offset cbuff)
MOV CX,0
conv: MOV AL,M
OR AL,AL
JNZ L@14
RET ;return if end of convert
L@14:
SUB AL,'0'
CMP AL,10
JNB rderr
PUSH BX
PUSH CX
POP BX ;b,c copied to h,l
SHL BX,1
SHL BX,1
SHL BX,1
ADD BX,CX
ADD BX,CX
PUSH BX
POP CX
POP BX ;bc=bc*10
INC BX
ADD AL,CL
MOV CL,AL
MOV AL,0
ADC AL,CH
MOV CH,AL
JNB L@15
JMP rderr
L@15:
JMPS conv ;tested for overflow
;
incserial:
;increment the serial number
MOV BX,Word Ptr bserial
INC BX
MOV Word Ptr bserial,BX ;test for overflow
MOV AL,BL
OR AL,BH
JZ serover
;
MOV BX,(Offset aserial)+4
MOV CH,5 ;length of serial number
inc0: INC M
MOV AL,M
CMP AL,'9'+1
JNB L@16
RET ;return if carry
L@16:
MOV M,'0' ;clear the number
DEC BX
DEC CH
JNZ inc0
;
serover:
;overflow in serial number
CALL overmsg
MOV CL,0
MOV DL,0
INT 224
;
serialize:
;match ' DIGITAL RESEARCH ' and update serial #
MOV BX,(Offset ibuff)
MOV CX,nsrlsec*secsiz
search: PUSH BX
PUSH CX
MOV DX,(Offset Copyright)
MOV CL,(Offset CoNmLen)
comp0: MOV SI,DX
MOV AL,[SI]
CMP AL,M
JNZ nomatch
LAHF
INC BX
SAHF
LAHF
INC DX
SAHF
DEC CL
JNZ comp0
;match complete, we've found the serial number
POP CX
POP DX ;clears stack
XCHG BX,DX
MOV BX,Word Ptr origin
XCHG BX,DX
MOV M,DL ;low byte origin
LAHF
INC BX
SAHF
MOV M,version ;version number in binary
LAHF
INC BX
SAHF
MOV M,system ;system number in binary
LAHF
INC BX
SAHF
MOV M,DH ;high byte origin number
LAHF ;get the serial number
INC BX
SAHF
XCHG BX,DX
MOV BX,Word Ptr bserial
XCHG BX,DX
MOV M,DH
LAHF
INC BX
SAHF
MOV M,DL
;MPMLDR serial number is copied
RET
;
nomatch: ;try for next match
POP CX
POP BX
INC BX
DEC CX
MOV AL,CL
OR AL,CH
JNZ search
;not found
CALL noserial
JMP rddsk
;
rdwrsrlfl:
MOV Byte Ptr iof,AL ;save rdseqf / wrseqf func code
PUSH DX
PUSH BX
MOV DX,32
LAHF
ADD BX,DX
RCR SI,1
SAHF
RCL SI,1
MOV M,0 ;set nr = 0
POP BX
POP DX
MOV CH,nsrlsec ;count = 4 sectors
flrdwr:
PUSH CX
PUSH DX
PUSH BX
MOV CL,stdmadr
INT 224
POP DX
PUSH DX
MOV AL,Byte Ptr iof
MOV CL,AL
INT 224
POP BX
POP DX
POP CX
INC AL
JZ srlflerr
DEC CH
JNZ L@17
RET
L@17:
PUSH BX
MOV BX,secsiz
LAHF
ADD BX,DX
RCR SI,1
SAHF
RCL SI,1
XCHG BX,DX
POP BX
JMPS flrdwr
srlflerr:
CALL badMPM
JMP rddsk
;
srlfile:
;update serial # in all files in the FCB table
;HL = FCBTable address
MOV Word Ptr FCBtableadr,BX
;reset disk system
PUSH BX
MOV CL,resetds
INT 224
POP BX
srlflopn:
MOV AL,M
OR AL,AL
JZ srlflrdwrvr
PUSH BX
XCHG BX,DX
MOV CL,openf
INT 224 ;open next file from FCB Table
POP BX
INC AL
JZ srlflerr
MOV DX,33
ADD BX,DX
JMPS srlflopn
srlflrdwrvr:
MOV BX,Word Ptr FCBtableadr
flrdwrvr:
MOV AL,M
OR AL,AL
JNZ L@18
RET
L@18:
PUSH BX
srlflrd:
MOV DX,(Offset ibuff) ;dma buffer is ibuff
MOV AL,rdseqf
CALL rdwrsrlfl
srlflwr:
CALL serialize ;patch in serial #
POP BX
PUSH BX
MOV DX,(Offset ibuff) ;dma buffer is ibuff
MOV AL,wrseqf
CALL rdwrsrlfl
srlflvr:
POP BX
PUSH BX
MOV DX,(Offset obuff) ;dma buffer is obuff
MOV AL,rdseqf
CALL rdwrsrlfl
MOV BX,(Offset ibuff)
MOV DX,(Offset obuff)
MOV CX,nsrlsec*secsiz
flvr:
MOV SI,DX
MOV AL,[SI]
CMP AL,M
JZ L@19
JMP srlflerr
L@19:
INC BX
INC DX
DEC CX
MOV AL,CH
OR AL,CL
JNZ flvr
POP BX
MOV DX,33
ADD BX,DX
JMPS flrdwrvr
L@20 EQU $
DSEG
ORG Offset L@20
;
FCBtablesysdisk1 RS 0
;
; MPM.SYS
DB dstdsk+1 ;drive code
DB 'MPM ' ;file name
DB 'SYS' ;file type
DB 0 ;extent
RS 2
DB 0 ;record count
RS 16 ;allocation map
DB 0 ;next record
FCBtabledisk1 RS 0
; SUP.MPM
DB dstdsk+1 ;drive code
DB 'SUP ' ;file name
DB 'MPM' ;file type
DB 0 ;extent
RS 2
DB 0 ;record count
RS 16 ;allocation map
DB 0 ;next record
;
; RTM.MPM
DB dstdsk+1 ;drive code
DB 'RTM ' ;file name
DB 'MPM' ;file type
DB 0 ;extent
RS 2
DB 0 ;record count
RS 16 ;allocation map
DB 0 ;next record
;
; MEM.MPM
DB dstdsk+1 ;drive code
DB 'MEM ' ;file name
DB 'MPM' ;file type
DB 0 ;extent
RS 2
DB 0 ;record count
RS 16 ;allocation map
DB 0 ;next record
; CIO.MPM
DB dstdsk+1 ;drive code
DB 'CIO ' ;file name
DB 'MPM' ;file type
DB 0 ;extent
RS 2
DB 0 ;record count
RS 16 ;allocation map
DB 0 ;next record
;
; BDOS.MPM
DB dstdsk+1 ;drive code
DB 'BDOS ' ;file name
DB 'MPM' ;file type
DB 0 ;extent
RS 2
DB 0 ;record count
RS 16 ;allocation map
DB 0 ;next record
;
; GENSYS.CMD
DB dstdsk+1 ;drive code
DB 'GENSYS ' ;file name
DB 'CMD' ;file type
DB 0 ;extent
RS 2
DB 0 ;record count
RS 16 ;allocation map
DB 0 ;next record
;
; MPMLDR.CMD
DB dstdsk+1 ;drive code
DB 'MPMLDR ' ;file name
DB 'CMD' ;file type
DB 0 ;extent
RS 2
DB 0 ;record count
RS 16 ;allocation map
DB 0 ;next record
;
DB 0 ;end of FCB Table
;
;
FCBtabledisk2 RS 0
; if files on second disk are to be serialized
; put their FCBs here
DB 0 ;end of FCB Table
L@21 EQU $
CSEG
ORG Offset L@21
; print strings
insmsg:
MOV DX,(Offset $)+6
JMP prmsg
L@22 EQU $
DSEG
ORG Offset L@22
DB cr,lf,'Insert control diskette in '
DB 'A'+srcdsk
DB ':, type return$'
L@23 EQU $
CSEG
ORG Offset L@23
;
signonmsg:
MOV DX,(Offset $)+6
JMP prmsg
L@24 EQU $
DSEG
ORG Offset L@24
DB cr,lf,'MP/M-86 V'
DB version/10+'0','.',version mod 10 +'0'
DB ' Serialization',cr,lf,'$'
L@25 EQU $
CSEG
ORG Offset L@25
;
sysdskmsg:
MOV DX,(Offset $)+6
JMP prmsg
L@26 EQU $
DSEG
ORG Offset L@26
DB cr,lf,'System disk (Y/N)? $'
L@27 EQU $
CSEG
ORG Offset L@27
;
dskslctmsg:
MOV DX,(Offset $)+6
JMP prmsg
L@28 EQU $
DSEG
ORG Offset L@28
DB cr,lf,'Select type of disk serialization:'
DB cr,lf,' 1 = Disk 1/2'
DB cr,lf,' 2 = Disk 2/2'
DB cr,lf,' 3 = Disk 1/2 & 2/2'
DB cr,lf,'?$'
L@29 EQU $
CSEG
ORG Offset L@29
;
orgmsg:
MOV DX,(Offset $)+6
JMP prmsg
L@30 EQU $
DSEG
ORG Offset L@30
DB cr,lf,'Origin number? $'
L@31 EQU $
CSEG
ORG Offset L@31
;
sermsg:
MOV DX,(Offset $)+6
JMP prmsg
L@32 EQU $
DSEG
ORG Offset L@32
DB cr,lf,'Starting serial number? $'
L@33 EQU $
CSEG
ORG Offset L@33
;
invalid:
MOV DX,(Offset $)+6
JMP prmsg
L@34 EQU $
DSEG
ORG Offset L@34
DB cr,lf,'Invalid number, try again $'
L@35 EQU $
CSEG
ORG Offset L@35
;
curmsg:
MOV DX,(Offset $)+6
JMP prmsg
L@36 EQU $
DSEG
ORG Offset L@36
DB cr,lf,'Serializing disk $'
L@37 EQU $
CSEG
ORG Offset L@37
;
asermsg:
MOV DX,(Offset aorigin)
CALL prmsg
MOV DX,(Offset aserial)
JMP prmsg
;
newmsg:
MOV DX,(Offset $)+6
JMP prmsg
L@38 EQU $
DSEG
ORG Offset L@38
DB cr,lf,'Insert new diskette in '
DB 'A'+dstdsk
DB ':, type return$'
L@39 EQU $
CSEG
ORG Offset L@39
;
noserial:
MOV DX,(Offset $)+6
JMP prmsg
L@40 EQU $
DSEG
ORG Offset L@40
DB cr,lf,'Non MP/M-86 diskette, cannot serialize$'
L@41 EQU $
CSEG
ORG Offset L@41
;
badMPM:
MOV DX,(Offset $)+6
JMP prmsg
L@42 EQU $
DSEG
ORG Offset L@42
DB cr,lf,'Bad MP/M-86 files on disk$'
L@43 EQU $
CSEG
ORG Offset L@43
;
vererr:
MOV DX,(Offset $)+6
JMP prmsg
L@44 EQU $
DSEG
ORG Offset L@44
DB cr,lf,'Verification error, bad disk$'
L@45 EQU $
CSEG
ORG Offset L@45
;
overmsg:
MOV DX,(Offset $)+6
JMP prmsg
L@46 EQU $
DSEG
ORG Offset L@46
DB cr,lf,'Serial number overflow$'
L@47 EQU $
CSEG
ORG Offset L@47
read0msg:
MOV DX,(Offset $)+6
JMP prmsg
L@48 EQU $
DSEG
ORG Offset L@48
DB cr,lf,'Error on source disk, replace$'
L@49 EQU $
CSEG
ORG Offset L@49
;
write0msg:
MOV DX,(Offset $)+6
JMP prmsg
L@50 EQU $
DSEG
ORG Offset L@50
DB cr,lf,'Cannot write new disk, replace$'
L@51 EQU $
CSEG
ORG Offset L@51
;
read1msg:
MOV DX,(Offset $)+6
JMP prmsg
L@52 EQU $
DSEG
ORG Offset L@52
DB cr,lf,'Cannot re-read new disk, replace$'
;
;
; miscellaneous data areas
;
bpb rb 5 ;direct bios param block
disk RS 1 ;1=1/2, 2=2/2, 3=1/2 & 2/2
sysdsk DB 0 ;0ffh="system disk"
strtrk RS 1 ;start track, begtrk or dirtrk
FCBtableadr RS 2 ;FCB table address
origin RS 2 ;binary origin
aorig DB cr,lf
aorigin RS 0
DB '00000-$'
trmsg DB cr,lf
trcount RS 0
DB '00 tracks verified$'
bserial RS 0
RS 2 ;binary serial number
aserial RS 0
DB '00000$'
; skew table (first byte 0 if no skewing)
skewtbl RS 0
DB 0 ;no skew table for MDS-800
; input buffer
maxlen DB 7
comlen RS 1
cbuff RS 8
;
RS 32 ;stack
stack RS 0
trlen EQU sectrk*secsiz ;buffer size
ibuff RS trlen
obuff RS trlen
DB 1 ;force hex generation
END

View File

@@ -0,0 +1,578 @@
; title 'Serialization Program for MP/M-86 09/14/81'
version equ 20 ;version 2.0
system equ 1 ;MP/M 86 system
; Serialization Program for MP/M 86 diskettes
; Note **********************************************************
; This program contains Digital Research proprietary information,
; and must not be reproduced, copied, or transcribed in any form
; whatsoever
; ***************************************************************
; Copyright (C) 1979, 1980, 1981
; Digital Research
; Box 579 Pacific Grove
; California, 93950
; Revised:
; 14 Sept 81 by Thomas Rolander (MP/M II 8080)
; 18 Sept 81 by Danny Horovitz (MP/M-8086)
; '$' signs taken out of identifiers and labels for
; ASM86 compatibility, names of serialized
; programs changed, only one disk to be serialized
tpa equ 100h ;transient program area
org tpa
jmp start
Copyright:
db 'COPYRIGHT (C) 1981,'
db ' DIGITAL RESEARCH '
CoNmLen equ $-Copyright
;
; global equates
boot equ 0000h
bdos equ 0005h
;
; BDOS equates
conin equ 1 ;read console device
conout equ 2 ;write console device
pbuff equ 9 ;print buffer
rdbuff equ 10 ;read buffer
resetds equ 13 ;reset disk system
selectd equ 14 ;select disk
openf equ 15 ;open file
rdseqf equ 20 ;read sequential file
wrseqf equ 21 ;write sequential file
stdmadr equ 26 ;set DMA address
; Hardware dependent equates
begtrk equ 0 ;beginning track #
dirtrk equ 2 ;directory track #
maxtrk equ 76 ;maximum track #
sectrk equ 26 ;sectors per track
srcdsk equ 2 ;source disk
dstdsk equ 3 ;destination disk
secsiz equ 128 ;sector size in # bytes
nsrlsec equ 4 ;# of sectors to search serial #
cr equ 0dh
lf equ 0ah
;
readtrk equ $
writtrk equ $+3
reread equ $+6
; track read/write routines, filled in later
jmp readdisk
jmp writedisk
jmp rereaddisk
track: ds 1 ;set to track to read/write
buffa: ds 2 ;set to buffer address to read/write
iof: ds 1 ;io function 0 = read, 1 = write
;
readdisk:
;read disk drive a, from track 'track'
;into the address given by 'buffa'
mvi a,srcdsk! call sel ;select src drive
jmp readd
;
;
writedisk:
;write to disk drive b, to track 'track'
;from the address given by 'buffa'
mvi a,1! sta iof ;set iofunction to write
mvi a,dstdsk! call sel ;select dst drive
jmp rwdisk
;
rereaddisk:
;read from dstdsk, from track 'track'
;to the address given by 'buffa'
mvi a,dstdsk! call sel ;dst drive selected
readd: xra a! sta iof ;set to read function
rwdisk: ;read or write disk
lxi h,track! mov c,m ;get track number
call trk ;track selected
lhld buffa ;get dma address
lxi d,sectrk ;d = 0, e = sectors per track
rwloop: ;read/write loop
inr d ;to next sector
push d! push h! mov c,d! mvi b,0
lxi h,skewtbl! mov a,m! ora a
jz noskew ;jump if no skew table
dcr c! dad b! mov c,m
noskew:
call sec ;sector set
pop b! push b ;get dma address
call dma ;dma address set
;perform io function
lda iof! ora a ;0=read, 1=write
jnz writefunc
;read disk
call dread
jmp rwcomplete
writefunc:
;write disk
call dwrite
rwcomplete: ;function complete
pop h ;recall dma address
lxi d,secsiz! dad d ;to nxt dma
pop d ;recall sector and count
; check error conditions
ora a! rnz ;rtn with non zero flag set
dcr e ;count = count - 1
jnz rwloop ;for another sector
ret ;with zero flag set for io complete
;
;
; utility subroutines for direct disk io
wboot equ 1 ;warm boot address
seldsk equ 24 ;select disk
settrk equ 27 ;set track
setsec equ 30 ;set sector
setdma equ 33 ;set dma address
readf equ 36 ;read disk
writf equ 39 ;write disk
;
sel: ;select drive given by register a
mov c,a! lhld wboot! lxi d,seldsk! dad d! pchl
;
trk: ;set track given by c
lhld wboot! lxi d,settrk! dad d! pchl
;
sec: ;set sector given by c
lhld wboot! lxi d,setsec! dad d! pchl
;
dma: ;set dma address to value of b,c
lhld wboot! lxi d,setdma! dad d! pchl
;
dread: ;perform read operation
lhld wboot! lxi d,readf! dad d! pchl
;
dwrite: ;perform write operation
lhld wboot! lxi d,writf! dad d! pchl
;
start:
lxi sp,stack
call signonmsg ;display sign on message
call sysdskmsg! call ci ;system disk serialize ?
ani 0dfh! cpi 'Y'! mvi a,dirtrk
jnz sd1
lxi h,sysdsk! inr m! mvi a,begtrk
sd1: sta strtrk
call dskslctmsg! call read ;select 1/2, 2/2, or 1/2 & 2/2
lxi h,disk! mov m,c
call orgmsg! call read ;origin prompt
lxi h,origin! mov m,c ;saved the origin number
inx h! mov m,b ;high order origin number byte
lxi h,comlen! mov b,m! inx h! xchg
lxi h,aorigin ;ascii version of the origin
org2: ldax d! ora a! jz org3
inx d! mov m,a! inx h! dcr b! jnz org2
;ascii version moved to buffer, pad it
org3: mvi m,'-'! inx h! mvi m,'$' ;ready for printing
;
; now read the serial number
call sermsg! call read
lxi h,bserial! mov m,c! inx h! mov m,b ;binary copied
lxi h,comlen! mvi a,5! sub m ;difference in reg-a
lxi h,aserial! jz pad1 ;pad high order positions with 0
pad0: mvi m,'0'! inx h! dcr a! jnz pad0
pad1: lxi d,cbuff ;addressing buffer
pad2: ldax d! ora a! jz pad3 ;looking for binary 0
mov m,a! inx h! inx d! jmp pad2 ;another char
pad3: ;end of ascii fill (right adjusted in aserial)
;
rddsk: ;read disk and copy
lxi sp,stack ;reset stack pointer (entry from errors)
call insmsg! call ci ;wait for response
;
nextdisk:
call curmsg! call asermsg! call newmsg! call ci
;new disk is ready, try the copy operation
lda strtrk ;get start track
lxi h,track! mov m,a ;initialize the track number
lxi h,trcount! mvi m,'0'! inx h! mvi m,'0'
;
rdtrk: ;read the next source track, compare with 0e5h for end
lxi h,ibuff! shld buffa! call readtrk
jz readok! call read0msg! jmp rddsk
readok:
;track is in memory, track 0?
lda track! ora a
;if track 0, do MPMLDR serialization
cz serialize
;
;track in memory, check for last track
lxi h,ibuff! lxi b,trlen
trcomp: mvi a,0e5h! cmp m! jnz wrtrk
inx h! dcx b! mov a,c! ora b
jnz trcomp
;end of copy, all 0e5h's
endcopy:
;write serial # into files in FCB table
lda sysdsk! ora a! lxi h,FCBtabledisk1
jz nonsysdsk! lxi h,FCBtablesysdisk1
nonsysdsk:
;write serial # into disk1
lda disk! ani 01h! cnz srlfile
;write serial # into disk2
lxi h,FCBtabledisk2
lda disk! ani 02h! cnz srlfile
lxi d,trmsg! call prmsg
call incserial! jmp nextdisk
;
;not end of copy, write track to disk from ibuff
wrtrk: call writtrk
jz wrok! call write0msg! jmp nextdisk
wrok:
;written to disk, now read it back and compare
lxi h,obuff! shld buffa! call reread
jz read1ok! call read1msg! jmp nextdisk
read1ok:
lxi h,ibuff! lxi d,obuff! lxi b,trlen
wrcomp: ldax d! cmp m! jnz wrerr
inx h! inx d! dcx b! mov a,c! ora b
jnz wrcomp
;compare ok, increment track count and cycle
lxi h,track! inr m
mvi a,maxtrk+1! cmp m
;jump if last track on disk copied
jz endcopy
lxi h,trcount+1! inr m! mov a,m! cpi '9'+1
jc rdtrk ;overflow to high order track number
mvi m,'0'! dcx h! inr m! jmp rdtrk
;
wrerr: ;verify error
call vererr! jmp nextdisk
;
;
; utility subroutines
ci: mvi c,conin! jmp bdos ;read a character
;
prmsg: mvi c,pbuff! jmp bdos ;print a buffer
;
rderr: call invalid
;
read: ;read constant value to b,c
lxi d,maxlen! mvi c,rdbuff! call bdos ;buffer filled
lxi h,comlen! mov a,m! ora a! jz rderr ;non zero length
inx h! mov e,a! mvi d,0! dad d ;h,l address last pos+1
mvi m,0 ;cleared for end of scan
lxi h,cbuff! lxi b,0
conv: mov a,m! ora a! rz ;return if end of convert
sui '0'! cpi 10! jnc rderr
push h! push b! pop h ;b,c copied to h,l
dad h! dad h! dad h! dad b! dad b
push h! pop b! pop h ;bc=bc*10
inx h! add c! mov c,a! mvi a,0! adc b! mov b,a
jc rderr! jmp conv ;tested for overflow
;
incserial:
;increment the serial number
lhld bserial! inx h! shld bserial ;test for overflow
mov a,l! ora h! jz serover
;
lxi h,aserial+4! mvi b,5 ;length of serial number
inc0: inr m! mov a,m! cpi '9'+1! rc ;return if carry
mvi m,'0' ;clear the number
dcx h! dcr b! jnz inc0
;
serover:
;overflow in serial number
call overmsg
jmp boot
;
serialize:
;match ' DIGITAL RESEARCH ' and update serial #
lxi h,ibuff! lxi b,nsrlsec*secsiz
search: push h! push b
lxi d,Copyright! mvi c,CoNmLen
comp0: ldax d! cmp m
jnz nomatch
inx h! inx d! dcr c! jnz comp0
;match complete, we've found the serial number
pop b! pop d ;clears stack
xchg! lhld origin! xchg! mov m,e ;low byte origin
inx h! mvi m,version ;version number in binary
inx h! mvi m,system ;system number in binary
inx h! mov m,d ;high byte origin number
inx h ;get the serial number
xchg! lhld bserial! xchg
mov m,d! inx h! mov m,e
;MPMLDR serial number is copied
ret
;
nomatch: ;try for next match
pop b! pop h! inx h! dcx b! mov a,c! ora b
jnz search
;not found
call noserial! jmp rddsk
;
rdwrsrlfl:
sta iof ;save rdseqf / wrseqf func code
push d! push h
lxi d,32! dad d! mvi m,0 ;set nr = 0
pop h! pop d! mvi b,nsrlsec ;count = 4 sectors
flrdwr:
push b! push d! push h
mvi c,stdmadr! call bdos
pop d! push d
lda iof! mov c,a! call bdos
pop h! pop d! pop b
inr a! jz srlflerr
dcr b! rz
push h! lxi h,secsiz! dad d
xchg! pop h
jmp flrdwr
srlflerr:
call badMPM! jmp rddsk
;
srlfile:
;update serial # in all files in the FCB table
;HL = FCBTable address
shld FCBtableadr
;reset disk system
push h!mvi c,resetds! call bdos! pop h
srlflopn:
mov a,m! ora a! jz srlflrdwrvr
push h! xchg! mvi c,openf
call bdos ;open next file from FCB Table
pop h! inr a! jz srlflerr
lxi d,33! dad d! jmp srlflopn
srlflrdwrvr:
lhld FCBtableadr
flrdwrvr:
mov a,m! ora a! rz
push h
srlflrd:
lxi d,ibuff ;dma buffer is ibuff
mvi a,rdseqf! call rdwrsrlfl
srlflwr:
call serialize ;patch in serial #
pop h! push h
lxi d,ibuff ;dma buffer is ibuff
mvi a,wrseqf! call rdwrsrlfl
srlflvr:
pop h! push h
lxi d,obuff ;dma buffer is obuff
mvi a,rdseqf! call rdwrsrlfl
lxi h,ibuff! lxi d,obuff! lxi b,nsrlsec*secsiz
flvr:
ldax d! cmp m
jnz srlflerr
inx h! inx d! dcx b
mov a,b! ora c
jnz flvr
pop h! lxi d,33! dad d
jmp flrdwrvr
;
FCBtablesysdisk1:
;
; MPM.SYS
db dstdsk+1 ;drive code
db 'MPM ' ;file name
db 'SYS' ;file type
db 0 ;extent
ds 2
db 0 ;record count
ds 16 ;allocation map
db 0 ;next record
FCBtabledisk1:
; SUP.MPM
db dstdsk+1 ;drive code
db 'SUP ' ;file name
db 'MPM' ;file type
db 0 ;extent
ds 2
db 0 ;record count
ds 16 ;allocation map
db 0 ;next record
;
; RTM.MPM
db dstdsk+1 ;drive code
db 'RTM ' ;file name
db 'MPM' ;file type
db 0 ;extent
ds 2
db 0 ;record count
ds 16 ;allocation map
db 0 ;next record
;
; MEM.MPM
db dstdsk+1 ;drive code
db 'MEM ' ;file name
db 'MPM' ;file type
db 0 ;extent
ds 2
db 0 ;record count
ds 16 ;allocation map
db 0 ;next record
; CIO.MPM
db dstdsk+1 ;drive code
db 'CIO ' ;file name
db 'MPM' ;file type
db 0 ;extent
ds 2
db 0 ;record count
ds 16 ;allocation map
db 0 ;next record
;
; BDOS.MPM
db dstdsk+1 ;drive code
db 'BDOS ' ;file name
db 'MPM' ;file type
db 0 ;extent
ds 2
db 0 ;record count
ds 16 ;allocation map
db 0 ;next record
;
; GENSYS.CMD
db dstdsk+1 ;drive code
db 'GENSYS ' ;file name
db 'CMD' ;file type
db 0 ;extent
ds 2
db 0 ;record count
ds 16 ;allocation map
db 0 ;next record
;
; MPMLDR.CMD
db dstdsk+1 ;drive code
db 'MPMLDR ' ;file name
db 'CMD' ;file type
db 0 ;extent
ds 2
db 0 ;record count
ds 16 ;allocation map
db 0 ;next record
;
db 0 ;end of FCB Table
;
;
FCBtabledisk2:
; if files on second disk are to be serialized
; put their FCBs here
db 0 ;end of FCB Table
; print strings
insmsg:
lxi d,$+6! jmp prmsg
db cr,lf,'Insert control diskette in '
db 'A'+srcdsk
db ':, type return$'
;
signonmsg:
lxi d,$+6! jmp prmsg
db cr,lf,'MP/M-86 V'
db version/10+'0','.',version mod 10 +'0'
db ' Serialization',cr,lf,'$'
;
sysdskmsg:
lxi d,$+6! jmp prmsg
db cr,lf,'System disk (Y/N)? $'
;
dskslctmsg:
lxi d,$+6! jmp prmsg
db cr,lf,'Select type of disk serialization:'
db cr,lf,' 1 = Disk 1/2'
db cr,lf,' 2 = Disk 2/2'
db cr,lf,' 3 = Disk 1/2 & 2/2'
db cr,lf,'?$'
;
orgmsg:
lxi d,$+6! jmp prmsg
db cr,lf,'Origin number? $'
;
sermsg:
lxi d,$+6! jmp prmsg
db cr,lf,'Starting serial number? $'
;
invalid:
lxi d,$+6! jmp prmsg
db cr,lf,'Invalid number, try again $'
;
curmsg:
lxi d,$+6! jmp prmsg
db cr,lf,'Serializing disk $'
;
asermsg:
lxi d,aorigin! call prmsg
lxi d,aserial! jmp prmsg
;
newmsg:
lxi d,$+6! jmp prmsg
db cr,lf,'Insert new diskette in '
db 'A'+dstdsk
db ':, type return$'
;
noserial:
lxi d,$+6! jmp prmsg
db cr,lf,'Non MP/M-86 diskette, cannot serialize$'
;
badMPM:
lxi d,$+6! jmp prmsg
db cr,lf,'Bad MP/M-86 files on disk$'
;
vererr:
lxi d,$+6! jmp prmsg
db cr,lf,'Verification error, bad disk$'
;
overmsg:
lxi d,$+6! jmp prmsg
db cr,lf,'Serial number overflow$'
read0msg:
lxi d,$+6! jmp prmsg
db cr,lf,'Error on source disk, replace$'
;
write0msg:
lxi d,$+6! jmp prmsg
db cr,lf,'Cannot write new disk, replace$'
;
read1msg:
lxi d,$+6! jmp prmsg
db cr,lf,'Cannot re-read new disk, replace$'
;
;
; miscellaneous data areas
;
disk: ds 1 ;1=1/2, 2=2/2, 3=1/2 & 2/2
sysdsk: db 0 ;0ffh="system disk"
strtrk: ds 1 ;start track, begtrk or dirtrk
FCBtableadr: ds 2 ;FCB table address
origin: ds 2 ;binary origin
aorig: db cr,lf
aorigin:
db '00000-$'
trmsg: db cr,lf
trcount:
db '00 tracks verified$'
bserial:
ds 2 ;binary serial number
aserial:
db '00000$'
; skew table (first byte 0 if no skewing)
skewtbl:
db 0 ;no skew table for MDS-800
; input buffer
maxlen: db 7
comlen: ds 1
cbuff: ds 8
;
ds 32 ;stack
stack:
trlen equ sectrk*secsiz ;buffer size
ibuff: ds trlen
obuff: ds trlen
db 1 ;force hex generation
end