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

578 lines
14 KiB
NASM
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.

; 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