Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM-86/MISC DRI DISKS/15/MPM86SRL.A86
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

992 lines
17 KiB
Plaintext
Raw 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.

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