home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
compress
/
nulu152.lbr
/
NULU152.IZF
/
NULU152.INF
Wrap
Text File
|
1990-11-03
|
22KB
|
503 lines
Additional Information for NULU version 1.52
15 July 1987
by
Mick Waters
Thi≤á documen⌠á detail≤ addition≤ anΣ change≤ t∩ NUL╒ version≤á 1.╡á anΣ ì
1.5▒á t∩á makσá versioε 1.52¼á particularl∙ t∩ use≥ modificatioεá anΣá ß ì
history of the changes.
NUL╒ i≤ copyrigh⌠ (c⌐ 1984¼ 198╡ anΣ 198╖ b∙ Martiε Murray« Thσ author≤ ì
origina∞á copyright≤ remaiε intac⌠ despitσ thesσ change≤ oµ minσ anΣ hi≤ ì
terms of use still apply.
History since 1985
------------------
NUL╒ versioε 1.╡ wa≤ releaseΣ iε 198╡ anΣ wa≤ haileΣ a≤ onσ oµ thσá mos⌠ ì
usefu∞á utilit∙á program≤ oµ it≤ time¼á faste≥ thaε thσ origina∞ L╒á anΣ ì
added filesweep facilities comparable to Dave Rands NSWP.
Somσá timσ afte≥ release¼á user≤ noticeΣ problem≤ wheεá extractinτá datß ì
froφá ß librar∙ oε onσ drivσ t∩ file≤ oε another«á Thi≤ wa≤ founΣ t∩á bσ ì
duσá t∩ ß buτ iε thσ CP/═ 2.▓ BDO╙ associateΣ (i⌠ wa≤ thought⌐ witΦ BDO╙ ì
functioεá 3╖á (Rese⌠ Drive)«á ┴ temporar∙ fi° wa≤ issueΣ b∙á Martiεá (a≤ ì
versioεá 1.51⌐ whicΦ effectivel∙ preventinτ user≤ froφ extractinτá file≤ ì
t∩ drive≤ othe≥ thaε thσ default«á Note¼ howeve≥ tha⌠ thi≤ probleφ doe≤ ì
no⌠ occu≥ wheε runninτ unde≥ CP/═ Plus« Subsequently¼ ╔ discovereΣ ß buτ ì
iε thσ KruncΦ routinσ whicΦ ╔ though⌠ a⌠ thσ timσ would¼á unde≥á certaiε ì
circumstances¼á causσ ß gooΣ librar∙ t∩ bσ corrupted« Sincσ NUL╒ wa≤ to∩ ì
gooΣ t∩ thro≈ awa∙ and¼ sincσ ß ne≈ releasσ haΣ no⌠ appeareΣ t∩ overcomσ ì
thσ BDO╙ functioε 3╖ bug¼ ╔ voweΣ t∩ makσ thσ necessar∙ changes.
Now¼á somσ tw∩ o≥ threσ month≤ later¼á afte≥ disassemblinτ NUL╒á versioε ì
1.╡á anΣ missinτ ou⌠ oε severa∞ night≤ sleep¼á ╔ offe≥ versioε 1.5▓á in-ì
lie⌡ oµ an∙ officia∞ upgradσ b∙ Martin.
Problems encountered
--------------------
A≤ promiseΣ iε m∙ origina∞ buτ report¼á ╔ includσ ß (deliberatel∙ vague⌐ ì
lis⌠á oµ thσ problem≤ founΣ anΣ thσ change≤ made«á Iε tha⌠ repor⌠ ╔ als∩ ì
promiseΣá t∩ adΣ aε uncrunchinτ routinσ - I'φ afraiΣ thi≤ wil∞á havσá t∩ ì
wait until I get time.
Thσá KruncΦá problem¼á a≤ i⌠ turneΣ out¼á wasn'⌠ a≤ seriou≤ a≤á ╔á firs⌠ ì
predicted« Oncσ ╔ go⌠ int∩ Martin≤ code¼ ╔ discovereΣ tha⌠ althougΦ NUL╒ ì
would¼á unde≥á thσ circumstance≤ ╔ described¼á fai∞ t∩ KruncΦ ßá librar∙ ì
correctly¼á i⌠á woulΣá discove≥ thσ erro≥ (a≤ ß CR├ error⌐ anΣá n∩á harφ ì
would be done.
Iε wha⌠ follows¼ m∙ reference≤ t∩ interna∞ NUL╒ routine≤ arσ necessaril∙ ì
vaguσá sincσ withou⌠ thσ origina∞ source¼á ╔ canno⌠ refe≥ t∩á meaningfu∞ ì
labe∞ names« M∙ disassembler¼ oµ course¼ gavσ labe∞ name≤ likσ L012│ anΣ ì
J123┤á - prett∙ meaningles≤ t∩ Martiε ╔ imagine«á However¼á armeΣ witΦ ß ì
disassebler, he should be able to see the changes that I have made.è
Thσá fi°á fo≥ thσ KruncΦ buτ relate≤ t∩ thσ callinτ oµ ßá routinσá whicΦ ì
read≤á ß disδ filσ witΦ CR├ calculatioε (origina∞ addres≤á 1BBAH)«á Thi≤ ì
routinσá i≤á calleΣ witΦ A=▒ iµ aε initia∞ seeδ i≤ requireΣ t∩ finΣá thσ ì
star⌠á oµ thσ wanteΣ membe≥ file«á Thσ changσ involveΣ savinτ thi≤ a≤á ß ì
flaτ and¼ iµ 1BBA╚ returneΣ aε erro≥ tha⌠ involveΣ ß subsequen⌠ writσ t∩ ì
disδ (buffe≥ ful∞ condition)¼á thσ flaτ wa≤ rese⌠ t∩ it≤ origina∞á statσ ì
(▒ o≥ 0⌐ a≤ appropriate« Iµ an∙ datß wa≤ read¼ thσ flaτ shoulΣ bσ se⌠ t∩ ì
zer∩ t∩ avoiΣ multiplσ seeks«á ┴ sectioε oµ thσ codσ follows¼á thσ labe∞ ì
names used are my own but, I expect that Martin will recognise it:
LD A,1 ; Set flag for an initial seek
LD (SEEKF),A Added
J1438: CALL SWPFCB ; Swap over the FCBs
; PUSH AF Removed
LD A,0 ; Saved user number for current library
L143D EQU $-1
CALL SUSRIR ; Set user if not already there
; POP AF Removed
LD A,0 Added ; Restore the seek flag
SEEKF EQU $-1 Added
CALL RDFCRC ; Read file with CRC
CALL SWPFCB ; Swap over the FCBs
JP Z,J1460 ; Jump if any errors
LD A,L ; Test records still to read
OR H
LD HL,(L1425) ; Get current record count
ADD HL,DE ; Add on records just read
LD (L1425),HL ; Save latest position in library
LD HL,(L146A) ; Get records to write
ADD HL,DE ; Add on records just read
LD (L146A),HL ; Save new number of records to write
JP Z,J13A6 ; Jump if nothing left to read
SUB A Added
LD (SEEKF),A Added ; Clear seek flag for next read
LD A,77 ; Error 77: Insufficient memory -
; Interpret as meaning buffer full
J1460: OR A
JP Z,J13A6 ; Jump if end of member file reached
CP 77
JP NZ,J1495 ; Jump if not an out of memory error
;
; The input buffer is now full, we
; need to write it out to 'WORK-LBR.$$$'.
;
LD DE,0 ; Get number of records to write out
L146A EQU $-2
LD HL,(DIRLEN) ; Length of library directory in bytes
LD B,H ; Offset from start of buffer to BC
LD C,L
LD HL,0 ; Get output random record position
L1472 EQU $-2
PUSH HL ; Save it
ADD HL,DE ; Produce next random record positionè LD (L1472),HL ; Save updated random record position
POP HL ; Get back current random record
LD A,(CFUSER) ; Get current file user number
CALL SUSRIR ; Set user if not already there
LD A,1 ; Set seek switch
CALL WRDECF ; Write DE records to the library
JP Z,J1495 ; Jump if any errors
LD HL,(DIRLEN) ; Length of library directory in bytes
LD (FDBFOF),HL ; Offset to first file in buffer
CALL J1549 ; Clear records to write
LD A,(SEEKF) Added ; Set if an initial seek required
OR A Added
JP Z,J1438 Added ; Jump if no initial seek required
CALL GMBINF Added ; Get current member parameters
PUSH HL Added
LD HL,(FDBFOF) Added ; New buffer offset to BC
LD B,H Added
LD C,L Added
POP HL Added
; SUB A Removed
JP J1438 ; Read the file with initial seek
-----------------------------
Thσá othe≥á probleφá - tha⌠á oµá overcominτá thσá BDO╙á erro≥á i≤áá morσ ì
complicated«á Thσá simples⌠á wa∙á woulΣ bσ t∩ fi° thσ BDO╙á anΣá ╔á havσ ì
includeΣ ß patcΦ t∩ thσ Digita∞ ResearcΦ BDO╙ fo≥ thosσ wh∩ wisΦ t∩ makσ ì
thσ change« Therσ arσ danger≤ inheren⌠ witΦ fixinτ thσ BDO╙ however¼ anΣ ì
╔ woulΣ strongl∙ recommenΣ leavinτ thing≤ thσ wa∙ the∙ are«á M∙ argumen⌠ ì
for leaving things is as follows:
Thσá CP/═ 2.▓ BDO╙ i≤ ß stablσ produc⌠ anΣ caε bσ guaranteeΣ t∩á perforφ ì
iε exactl∙ thσ samσ wa∙ fo≥ ever∙ user«á Knowinτ it≤ limitations¼á i⌠ i≤ ì
possiblσ t∩ overcomσ thσ problem≤ causeΣ b∙ thσ bug(s)«á Iµ al∞ user≤ oµ ì
NUL╒ werσ t∩ patcΦ thei≥ BDOSes¼á the∙ ma∙ onσ da∙ comσ acros≤ ß prograφ ì
whicΦá work≤á BECAUS┼á oµá thσ buτ anΣ hencσ woulΣá no⌠á worδá oεá thei≥ ì
systems«á Similarly¼á an∙ softwarσ developeΣ oε ß 'fixedº BDO╙ canno⌠ bσ ì
guaranteeΣ t∩ worδ oε aε unfixeΣ BDOS«á However¼ ╔ includσ thσ patcΦ anΣ ì
leave it up the users to decide. Freedom of choice is everyones right.
Thσá BDO╙ buτ althougΦ relateΣ t∩ functioε 3╖ i≤ not¼á iε fact¼á iε tha⌠ ì
functioεá bu⌠ iε thσ Selec⌠ Disδ functioε (functioε 14)«á Problem≤á wil∞ ì
only be caused under the following circumstances:
1. The default drive has been reset, AND
2. Data has been written to the default drive since the disk reset, AND
3. Some sort of disk activity is requested on a different drive.
Thσá BDO╙á keep≤á ß 1╢ bi⌠ variablσ (thσ login vector⌐ whicΦá show≤á thσ ì
login statσ fo≥ eacΦ oµ drive≤ A-P«á Iε thσ vector¼á eacΦ bi⌠ represent≤ ì
onσ drivσ anΣ i≤ se⌠ iµ thσ drivσ i≤ loggeΣ in«á A≤ record≤ arσá writteε ìèt∩ disk¼á thσ allocatioε vecto≥ iε thσ BIO╙ i≤ useΣ t∩ maintaiε ß recorΣ ì
oµá thosσá disδ block≤ allocateΣ t∩ thσ file«á Thσ allocatioε vecto≥á i≤ ì
updateΣá a≤ block≤ arσ writteε t∩ disδ bu⌠ i≤ initiall∙ se⌠ u≡ froφá thσ ì
disδá director∙á wheε thσ drivσ i≤ firs⌠ loggeΣá in«á BDO╙á functioεá 3╖ ì
simpl∙á reset≤á thσ appropriatσ bit(s⌐ iε thσ login vecto≥ whicΦá shoulΣ ì
cause the drive to be relogged on the next access.
Unfortunately¼á Digita∞á ResearcΦá maintaiεá aεá interna∞á variablσá fo≥ ì
holdinτá thσ las⌠ drivσ accesseΣ anΣ checδ i⌠ beforσ logginτ iε ßá disk« ì
Iµá thσ requesteΣ drivσ i≤ thσ samσ a≤ thσ last¼á theε thσ BDO╙á assume≤ ì
tha⌠á i⌠á i≤ alread∙ loggeΣ iε anΣ i⌠ doesn'⌠ checδ thσ logiε vecto≥á a⌠ ì
all«á Iµá wσ havσ rese⌠ thσ defaul⌠ drive¼á thσ interna∞á variablσá wil∞ ì
stil∞á sa∙ tha⌠ i≤ i≤ loggeΣ in¼á eveε thougΦ thσ logiε vecto≥ bi⌠á wil∞ ì
havσá beeεá reset«á Disδ write≤ ma∙ stil∞ bσ madσ t∩ thi≤ drivσ anΣá thσ ì
allocatioε vecto≥ wil∞ stil∞ bσ updated«
Iµ wσ werσ no≈ t∩ temporaril∙ switcΦ drive≤ t∩ d∩ ß read¼á fo≥á example« ì
Thσá interna∞á variablσá wil∞ reflec⌠ thi≤ anΣ NEX╘ timσ wσá acces≤á thσ ì
defaul⌠ drive¼á thσ BDOS'≤ checδ wil∞ no≈ sa∙ "Ah¼á ß differen⌠ drivσá - ì
checδ thσ logiε vector"«á Wheε thi≤ happens¼ oµ course¼ i⌠ wil∞ finΣ thσ ì
bi⌠á fo≥á thi≤á drivσ i≤ rese⌠ anΣ wil∞ re-reaΣ thσá disδá director∙á t∩ ì
updatσ thσ allocatioε vector.
Thσá disδá director∙ i≤ onl∙ updateΣ wheε eithe≥ aε exten⌠á boundar∙á i≤ ì
passeΣ (ever∙ 16k⌐ o≥ wheε thσ filσ i≤ closed«á Consequently¼á unles≤ wσ ì
arσ lucky¼á thσ disδ director∙ wil∞ no⌠ sho≈ thσ las⌠ fe≈ disδ write≤ wσ ì
havσá madσ anΣ thosσ bit≤ wil∞ bσ rese⌠ iε thσ allocatioεá vector«á Thi≤ ì
mean≤á tha⌠ a≤ fa≥ a≤ thσ BDO╙ i≤ concerned¼á thosσ block≤ arσ freσá fo≥ ì
usσá anΣá i⌠ wil∞ usσ theφ agaiε - eveε iµ i⌠ mean≤ allocatinτ thσá samσ ì
block(s) twice to the same file.
Iε contex⌠ oµ NULU¼á assumσ tha⌠ ß library¼ residen⌠ oε drivσ A¼ i≤ opeε ì
anΣá tha⌠á wσá arσ currentl∙ loggeΣ int∩ drivσ ┬ (ie║á drivσá ┬á i≤á thσ ì
defaul⌠á drive)«á Assumσá tha⌠ wσ wisΦ t∩ extrac⌠ ß 100δ membe≥ filσá t∩ ì
drivσá B«á NUL╒á create≤ ß buffe≥ wheε thσ librar∙ i≤ openeΣá anΣá ßá 2δ ì
buffe≥ fo≥ thσ filσ t∩ bσ extracted«á Thσ buffe≥ fo≥ thσ librar∙ wil∞ bσ ì
ßá largσ percentagσ oµ thσ remaininτ TP┴ sizσ bu⌠ sufficσ t∩ sa∙ tha⌠ i⌠ ì
wil∞á bσ smalle≥ thaε ou≥ membe≥ file«á Wσ theε fil∞ thσ librar∙á buffe≥ ì
witΦá thσá firs⌠ par⌠ oµ thσ membe≥ filσ anΣ rese⌠ drivσ ┬ iεá casσá thσ ì
disδá ha≤á beeε changeΣ - conditioε ▒ i≤ theε satisfied«á Wσá no≈á star⌠ ì
writinτá ou⌠ thσ membe≥ filσ (conditioε 2⌐ unti∞ thσ librar∙á buffe≥á i≤ ì
exhausted«á Wσá theεá neeΣá t∩ reaΣ morσ oµ thσ librar∙ froφ drivσá ┴á - ì
condition 3.
Thσápossibles answe≥s to this problem are:
1«á T∩á eithe≥ makσ al∞ disδ write≤ iε multiple≤ oµ 16δ (no⌠ necessaril∙ ì
convenient), OR
2«á T∩á notσ wheε thσ defaul⌠ drivσ ha≤ beeε rese⌠ anΣ als∩ iµá i⌠á ha≤ ì
beeεá writteεá t∩ sincσ thσ reset«á Iµ an∙ BDO╙ cal∞ i≤ theε madσá whicΦ ì
wil∞á causσá disδá activit∙á oε anothe≥ drivσá (drivσá ┴á iεá thσá abovσ ì
example)¼ al∞ file≤ oε thσ defaul⌠ drivσ shoulΣ bσ closeΣ (t∩ updatσ thσ ì
disδá directory⌐á anΣá theε reopened«á Fortunately¼á Martiε ha≤á ßá nicσ ì
routinσ t∩ d∩ this.è
Thi≤ seconΣ examplσ i≤ mess∙ bu⌠ wil∞ worδ witΦ al∞ permutation≤ oµ disδ ì
reads and writes and was chosen by me for use within NULU.
Thσá fi° fo≥ thi≤ probleφ involve≤ thσ origina∞ routinσ (addres≤á 2B46H⌐ ì
iε NUL╒ whicΦ update≤ ß disδ prio≥ t∩ ß possiblσ changσ b∙ closinτá theε ì
reopeninτ al∞ oµ thσ file≤ oε thσ affecteΣ drive«á Thσ firs⌠ thinτ t∩ d∩ ì
i≤ t∩ removσ thσ fina∞ jum≡ t∩ thσ 'rese⌠ driveº routinσ (addres≤ 32B9H⌐ ì
anΣ changσ al∞ call≤ t∩ 2B46╚ t∩ adΣ ß cal∞ t∩ thσ 'rese⌠ driveº routinσ ì
afterwards« ie:
CAL╠áDSKUP─á ╗ Updatσ thσ disδ prio≥ t∩á ß change
CALL RESDSK ; Reset the drive
Oε anothe≥ subjec⌠ altogether¼á thσ addition≤ oµ codσ t∩ savσ anΣ resorσ ì
thσ S▓ bytσ arσ t∩ d∩ witΦ file≤ large≥ thaε 512k« I⌠ ma∙ bσ oµ interes⌠ ì
t∩á notσ tha⌠ Digita∞ ResearcΦ 'forgotº t∩ documen⌠ tha⌠ thσ S▓ bytσá i≤ ì
aε overflo≈ exten⌠ byte«á Anyonσ wh∩ ha≤ trieΣ t∩ edi⌠ ß tex⌠ filσ unde≥ ì
Wordsta≥á wil∞á probabl∙ havσ founΣ tha⌠ i⌠ goe≤ banana≤ wheεá thσá filσ ì
sizσá exceed≤á 512k«á Wordsta≥ i≤ no⌠ alonσ iε this¼á therσ arσá severa∞ ì
othe≥á commercia∞á anΣ P─ program≤ tha⌠ suffe≥ badl∙ wheεá dealinτá witΦ ì
files greater than 512k.
Digita∞á ResearcΦá sa∙ tha⌠ CP/═ 2.▓ caε handlσ file≤ oµ u≡ t∩á 8MΓá anΣ ì
CP/═á Plu≤ caε handlσ file≤ u≡ t∩ 32Mb«á The∙ als∩ sa∙ tha⌠á thσá exten⌠ ì
bytσá (unde≥ 2.▓ anΣ Plus⌐ caε var∙ betweeε ░ anΣ 3▒ iε usσ - unde≥ CP/═ ì
1.┤á thi≤ wa≤ ░ t∩ 15«á No≈ 3▓ time≤ 16δ i≤ nowherσ nea≥ 8MΓá le⌠á alonσ ì
32Mb¼á iε fac⌠ i⌠ come≤ t∩ tha⌠ magiπ figurσ oµ 512δ - thi≤ i≤ wherσ thσ ì
S▓á bytσá come≤ in«á Thσ S▓ bytσ count≤ thσ multiple≤ oµ 512δ useΣ iεá ß ì
filσá anΣ ma∙ rangσ froφ ░ t∩ 1╡ unde≥ CP/═ 2.▓ (bit≤ 0-3⌐ anΣ ░á t∩á 6│ ì
unde≥ CP/═ Plu≤ (bit≤ 0-6)«á Bi⌠ ╖ oµ thσ S▓ bytσ i≤ useΣ b∙ thσ BDO╙ a≤ ì
aε interna∞ 'archiveº bit«á Wheε ß filσ i≤ opened¼ aε examinatioε oµ thσ ì
S▓ bytσ wil∞ sho≈ ß valuσ oµ 80H«á Iµ an∙ writσ i≤ performeΣ t∩ thσ filσ ì
iε question¼á thi≤ bi⌠ wil∞ bσ cleared«á Wheε thσ closσ filσ functioε i≤ ì
called¼á iµá thσ bi⌠ i≤ se⌠ theε n∩ actioε i≤ required«á Iµ i⌠ i≤ clear¼ ì
thσá disδá director∙ i≤ updated«á No≈ yo⌡ seσ thσ reasoε fo≥á thσá addeΣ ì
code.
Example≤á oµ thσ change≤ madσ follow«á Again¼á thσ label≤ useΣ arσ mine« ì
Thσá addresse≤á giveε arσ thσ thosσ froφ thσá origina∞á unmodifieΣá NUL╒ ì
versioε 1.5.
;
; This routine prepares for a disk change
; by making sure that all file activity
; up to now is accurately recorded on disk.
; This achieved by closing the files and
; reopening them. Original address is 2B46H.
;
DSKUPD: CALL SAVALL
CALL GETUSR ; Get current user number
PUSH AF
LD A,(FTBIDX) ; Current file table index
PUSH AF
LD A,(DE) ; Get drive to be resetè LD (L2B76),A
SUB A Added ; Clear flags to prevent infinite loop
LD (RESFLG),A Added ; Clear default drive reset flag
LD (WRTFLG),A Added ; Clear default drive written flag
;
; Go through file table flushing
; the file buffers by closing the
; files (on the affected drive) and
; reopening them.
;
LD C,0 ; Start with the first file
J2B57: INC C
LD A,(MAXFIL) ; Max no of files that may be open
CP C ; All files flushed
JP NC,J2B6A ; Continue if not
POP AF ; Restore file table index
CALL SNEWCF ; Select new current file
POP AF ; Restore current user
; CALL SUSRIR Removed
; JP RESDSK Removed
JP SUSRIR ; Set user if not already there
J2B6A: LD A,C ; Get file table index
CALL SNEWCF ; Select new current file
JP Z,J2B57 ; Jump if no file entry for this index
LD HL,(FFCBPT) ; Point to the current file FCB
LD A,(HL) ; Get drive
CP 0 ; Same drive?
L2B76 EQU $-1
JP NZ,J2B57 ; Jump if not
EX DE,HL
LD HL,12 ; Point to extent
ADD HL,DE
LD A,(HL) ; Get extent
PUSH AF
PUSH HL
INC HL ; Point to the S2 byte
INC HL
LD A,(HL) Added ; Get the S2 byte
PUSH AF Added
PUSH HL Added
INC HL ; Point to the record count
LD A,(HL) ; Get record count
PUSH AF
PUSH HL
CALL CLOSEF ; Close the file (forces disk update)
CALL OPENF ; ...and reopen it
POP HL
POP AF
LD (HL),A ; Renew record count
POP HL Added
POP AF Added
OR 80H Added ; Flag no file update (yet!)
LD (HL),A Added ; Renew the S2 byteè POP HL
POP AF
LD (HL),A ; Renew extent
JP J2B57
Next¼ adΣ codσ t∩ thσ 'writσ B├ record≤ t∩ fileº routinσ (addres≤ 2CB8H⌐ ì
whicΦá check≤á thσ firs⌠ bytσ oµ thσ FC┬ agains⌠ thσ defaul⌠á drivσá anΣ ì
set≤ ß flaτ iµ i⌠ i≤ thσ same«á Oncσ thi≤ flaτ ha≤ beeε set¼á thi≤ checδ ì
neeΣ no⌠ bσ repeated«
;
; Write BC records to disk
; DMA address is passed in HL
; Original address 2CB8H
;
WRFILE: CALL SETDMA ; Set initial DMA address
LD HL,WRTFLG Added ; Point at the default drive write flag
LD A,(HL) Added
OR A Added
JP NZ,WRF1 Added ; Skip if flag already set
CALL GETDSK Added ; Get default drive
EX DE,HL Added ; FCB address to HL
CP (HL) Added ; Compare with wanted drive
EX DE,HL Added
JP NZ,WRF1 Added ; Jump if not writing to default drive
LD (HL),A Added ; Set the flag accordingly
WRF1: LD HL,0 Label Added ; Initialise count of records written
CALL RSUBEX ; Set up multiple calls to WRSEQ etc.
DEFW RTRUE ; Return true status when done
;
; The following code is executed BC times
;
CALL WRSEQ ; Write one record to disk
JP Z,INC6SP ; Throw away stack if any errors
INC HL ; Bump number if records written
PUSH HL
CALL UPDDMA ; Add 128 to current DMA address
POP HL
RET
AdΣ codσ int∩ thσ 'rese⌠ driveº routinσ whicΦ set≤ ß flaτ iµ thσ defaul⌠ ì
drivσá i≤ reset«á ╔ diΣ thi≤ b∙ placinτ thσ defaul⌠ drivσ numbe≥ iεá thσ ì
flag¼á iµ required¼á otherwisσ leavinτ i⌠ clear«
;
; Reset indicated drive
; Original address 32B9H
;
RESDSK: CALL SAVALL
CALL GETUSR
PUSH AF ; Save current user
CALL GETDSK Added ; Get the current driveè EX DE,HL Added
CP (HL) Added ; Resetting default drive?
EX DE,HL Added
JP NZ,RSD1 Added ; Jump if not
LD (RESFLG),A Added ; Set flag if default drive is reset
RSD1: LD A,(DE) Label added ; Get drive to be reset
LD DE,L0001 ; Assume drive A initially
DEC A ; Make range 0-15 for drives A-P
CALL NZ,SLDEXA ; Convert drive code to bit position
LD C,25H
CALL GOCPM ; Reset the drive
SUB A Added
LD (WRTFLG),A Added ; Reset written since reset flag
POP AF ; Restore current user
JP SETUSR
Al∞á routine≤á whicΦá arσ likel∙ t∩ causσ disδ activit∙ shoulΣá theεá bσ ì
redirecteΣ froφ thei≥ existinτ cal∞ t∩ CP/═ t∩ ß ne≈ routinσ whicΦá wil∞ ì
checδ thσ flag≤ anΣ ac⌠ accordingly« Thσ entr∙ poin⌠ fo≥ norma∞ routine≤ ì
tha⌠á pas≤á ß FC┬ addres≤ iε D┼ i≤ t∩ BUGCH╦ whilσá thσá SELDS╦á routinσ ì
whicΦá passe≤á ß drivσ codσ iε ┼ call≤ BUGTST«á Example≤ oµ routine≤á t∩ ì
patcΦ arσ 'Opeε file'¼á 'Closσ file'¼á 'ReaΣ Sequential/Random'¼á 'Writσ ì
Sequential/Random/Randoφá witΦ Zer∩á Fill'¼á 'Se⌠á attributes'¼á 'SearcΦ ì
First/Next'¼á 'Renamσá file'¼á 'Deletσá file'¼á 'Makσ fileº anΣá 'Selec⌠ ì
disk'.
;
; Select disk for use
; Original address 32D1H
;
SELDSK: CALL SAVXAF
LD E,A
LD A,(MAXDSK) ; Maximum permitted drive number
CP E
LD A,14 ; Error 14: Bad drive
JP C,RFALSE
DEC E
LD C,0EH
; CALL GOCPM Removed
CALL BUGTST Added ; Call BDOS via the bug check routine
INC A
LD C,14 ; Error 14: Bad drive
JP Z,CPMERR ; Handle the returned BDOS error code
RET
;
; This routine has no equivalent in NULU 1.5
;
; This routine overcomes the problems
; introduced by the bug in BDOS function
; 14. It does this by closing and reopening
; all files on the default drive IF the drive
; has been reset via function 37 AND the drive
; has been written to since it was reset ANDè; this BDOS access is for a different drive.
;
BUGCHK: LD A,(CPMVER) ; Get CP/M version number
CP 30H ; Test whether CP/M Plus
JP NC,GOCPM ; CP/M Plus doesn't have the bug
CALL GETDSK ; Return current disk
EX DE,HL ; Point to the wanted drive
CP (HL) ; Same drive?
EX DE,HL
JP Z,GOCPM ; No action if same drive
BCHK: LD A,(RESFLG) ; Set if default drive was reset
OR A
JP Z,GOCPM ; No action if not
LD A,(WRTFLG) ; Set if default drive has been written
; to since the reset
OR A
JP Z,GOCPM ; No action if not
PUSH DE ; Save FCB address
LD DE,RESFLG ; Point to the drive to be updated
CALL DSKUPD ; Ensure disk directory is up to date
POP DE ; Restore FCB address
JP GOCPM ; Process the BDOS call normally
;
; This entry point is for the select
; disk function since its parameters
; are not passed in an FCB.
;
BUGTST: LD A,(CPMVER) ; Get CP/M version number
CP 30H ; Is it CP/M Plus
JP NC,GOCPM ; No action if so (bug not in CP/M+)
CALL GETDSK
DEC A
CP E ; Same drive?
JP Z,GOCPM ; No action if same drive
JP BCHK
Therσ shoulΣ bσ enougΦ informatioε herσ t∩ allo≈ Martiε t∩ recreatσ wha⌠ ì
╔ havσ donσ (iµ hσ wishes)«á Fo≥ thosσ user≤ wh∩ wisΦ t∩ patcΦ thei≥ DR╔ ì
BDO╙á t∩ removσ thσ bug¼á proceeΣ a≤ follow≤ bu⌠ bσ warneΣ tha⌠ yo⌡á ma∙ ì
stop software from running.
The DRI BDOS fix
----------------
Zer∩á ou⌠ thσ followinτ location≤ iε thσ DR╔ BDOS¼á notσ tha⌠á thσá BDO╙ ì
start≤á ╢á byte≤ beforσ thσ addres≤ a⌠ locatioε 0006╚ anΣ tha⌠á ZSID/DD╘ ì
etc«á wil∞ no⌠ givσ thσ truσ address« Usσ somethinτ likσ Z3LO├ o≥ STATU╙ ì
t∩á determinσ you≥ BDO╙ address«á Thσ byte≤ a⌠ thosσ location≤ anΣá wha⌠ ì
they do are given so that you can patch away with confidence.
Location to patch Byte at that location (Hex)
(xx = depends upon BDOS address)
èBDO╙á½ 0C45╚ 3┴ LD┴ xxD6╚á ╗áGe⌠áwanteΣ drive
BDOS + 0C46H D6
BDOS + 0C47H xx
BDO╙á½á0C48╚ 2▒ LX╔ H,xx42╚á ╗áGe⌠álas⌠ drive
BDOS + 0C49H 42
BDOS + 0C4AH xx
BDOS + 0C4BH BE CMP M ; Same drive?
BDO╙ ½ 0C4C╚ C╕ R┌ ╗áReturε iµ i⌠ is
Thi≤ patcΦ prevent≤ thσ BDO╙ froφ usinτ it≤ interna∞ saveΣ recorΣ oµ thσ ì
las⌠á drivσá accesseΣá anΣ force≤ i⌠ t∩ checδ thσ logiε vecto≥á bit≤á t∩ ì
determine whether or not to relog a drive.
The patch above works but on your own head be it!