 14
                   1. Coae paepa cpoca.

   paep cpoca  o  ceaa  popaa,  oopa  pae
oeo c epep cpoco,  a  a  pep    co
aoe. oco apaep x epepx cpoc ec o
pooe  pooe,  o pa ooae popa oe
opeoac  a  pax pae- po,  o o o paoa a
eec  eo oopoa.  eec 4 cocoa  e  paepo
cpoc  popa:
   1. Moo  oec  o    cex  paepo  po    popa.
Hapep,  o oepa pae pep, oo coa a
pax oceoaeoce  ca  e 㦭  o  a  pa
oa  o  opeec.  o  oxo  pa oo a  oe 
ocaoo ee.
   2. Coa  p  paepo cpoc  opeoa,  o popaa
apaa eoxo  aece oepe (.e.  oea eo   oac
popa, ceao ocae  o e.
   3. Coa  paep  cpoca  a  oe  popa,  oopa
aaec    oao  ae,  oeo  p  ap㧪e  cce.
popaa acaec  caaae paep cpoca a  popa
opao⪨  pepa.  oce oo popaa aepaec,  o ocaec
peeo   a.
   4. Coa ooe paep cpoca, oop e apac
p cape c oo aa CONFIG.SYS.  MS DOS oepae  ao  ⨯
paepo  cpoc    oa  ape o oe cooa ce
oooc oa DOS,  a poep o訡o.  Ceaa  oaa
IOCTL   (Kopo   oa/oa)  ooe  popae  㧭a  cac
paepa  oca  e  pa  cpo,  oo  ooo  ooa
ax.
   epe p  cpae  eo  peac  c   oo   opa樨,
peeo     ocax  acx  ao  .  Ho  caaaee
paep cpoc oe co. ao oa o ec, o o oe oe.
B  o  cae  ccea  e  paoa  c cpoco ac- oo e
eco,  a c aapo  co  aoee.  cpoc  oe
   pcoeo   ,  apep,  SERIALPR    oc-  eoaeoo
pepa,   ae o cpoco oe   opo    oca  
oo  a.  B  ece  oepaop OPEN "SE- RIALPR" FOR OUTPUT AS #2
ooo oceoae pep  oa.  B e acceepa  B
coee  o  oc   pep a c oo eoa paeo
oa aa,  a  c oo eoa ecpopa aa,  a  oe
o 㭪 IOCTL. p o ooae ee oooc oca 
cpoc a poe oepaoo cce  oe poco ec oa
COPY  A:MY-  FILE  SERIALPR:,  o  copoa  coepoe  aa a
pep.
   caaaee paep  cpoc  o    aca oo a
e acceepa.  O o oc㦨a a ⨯a cpoc: coe
   oe.      ea   oca   e,  oop묨  cpoco
opaaae ae.  Oo  paep  ox  cpoc  oc㦨a
coe aoe,  a paep cox - ce ocaoe, a稭a o
oceoaex pepo   oa  pooa-  .  oe  cpoca
oeac oa ax, oo o aac aoee ax.
Coe cpoca oeac a묨 oao,  oo o e
oxo  pax cpoc,  a ae  cpoc,  oope e
o oece co  copoc  oea  a묨.  paep  ox
cpoc oe co  ec e ocaoo eca, o oc x
cpp. Oe peo o peec aca ao paep. Texec-
oe  pooco o MS DOS peocae c eoxo opa-  
coep o pep paepa  paoo  ca    oepa-  ⨢o

                                     - 2 -
a.  B  oee  pocope   opa oce oo a e
oc㦤ee paepo cox cpoc, peeoe ec.
   caaaee paep  cpoc  ecoa   popacc- 
o訡a.  oco paep aoaec apac cce-  o  p
ap㧪e,  o  eooo  cooa  oa稪  e p稭
eoao. oo e peeo ae p x aca.
   popaa paepa  cpoca  paaec a p ac,  aa 
oopx oc㦤aec oeo  cex paeax.  o  (1)  aooo
paepa, oop ee cpoco  coep op- a o oca-
x  acx  paepa,  (2)  cpae  paepa,  oo-   pa   xpa
opa  o  oac ax,  coaaeo MS DOS,  oopa aae
aooo apoca,   (3) opao稪 pepa cpoca,  oop 
coep o, pa騩 cpoco.

                    2. Coae aooa paepa.

   paep cpoc o coaac  e COM ao.  Oao o
e c aco騬 popaa, oco  x occe pe䨪c
popaoo  ceea.  o oc oo e ao a oepaop
ORG 100H  aae popa,  a o eaec    COM  ao.  o
ae  ORG  0,  o  ooe  eo e e.  paep oe 
oca a  aea  (far)  poepa,  a      o  popae.  B
epeeo  pepe pee aa o  paepa cpoca
c ee DEVICE12.  Oo aee caapoe  cpoco  AUX,  co-
eoe  MS DOS,  pa o 㭪樨 4 pepa 21H.  Bec paep
cpoca coco  oa oo paea ece c oo,  peeo 
ce-  x x paeax;  oece x op o a p㣨,  o
o o popa.
   paep cpoca oe a稭ac c aooa paepa.  O ee
 18 ao,  paeex a  5  oe.  epoe  oe  (DD)  cea
coep aee -1 (FFFFFFFFH),   oa MS DOS apae paep, o
oo aeec a capo apec ceeo pae- pa. Ta opao,
ccea  oe  ca  ce騩  paep  o  eoe.    oceeo
apeoo paepa  o oe ocaec aee -1.
   Bopoe oe o a apo paepa. e aee oo
7 o oo coa:

 15   1 = cooe cpoco, 0 = ooe cpoco
    14   1 = oepae IOCTL, 0 = e oepae IOCTL
    13   1 = opa oo IBM, 0 = po opa oo
     3   1 = ac, 0 = e ac
     2   1 = eoe cpoco, 0 = e eoe cpoco
     1   1 = cpoco caapoo oa, 0 = e
     0   1 = cpoco caapoo oa, 0 = e

   Oo caoe oo  15,    15  14,  ec cpoco
oepae  IOCTL.    13  ca-  aaec  oo    ox
cpoc.  Ocae  coc  ae  cpoc,  co-
ex  MS  DOS  o oa (cpoca caapoo oa  oa
c aapa  eoce;  cpoco aco  oee  ac
peaoo  pee  c  aca pee co BIOS;  a eoe cpoco
(NULL) - o ceocpoco, coeoe  ecox ee).
   Tpee  eepoe o coepa cee  poep cpae-
  opao⪨ pepa, oope  paccope  cex
paeax.  Haoe, oceee oe coep  cpoca.   
oe coepa o  8  coo    oo  oo  paeo o
eo pa c aepa騬 poea.   ae cecx  
DOS cpoc, ax a  LPT1    COM1,  coe o e 
cpoca, a  ao pepe.

                                     - 3 -

   H poe.

   B ao pepe coaec paep  oceoaeoo cpoca.
"DEVICE12" -  aa, oop oe  aa  ae o䨣pa樨
cce, o o paep  ape. B ae apo caoe
oo  15,  aa o o cooe cpoco    o  oo  e
oepae  IOCTL.  DEV_STRATEGY    DEV_INTERRUPT  - ea poep,
oc㦤aex  cex pae- ax. cpoco aao AUX, c e o
ae  ooe cpoco MS DOS c ⨬ ee.  o ooe oe
poco  opa-  ac    o  cpoc,  oco  ccea  ee
peopeee   oep   aa      opae     cpoc  AUX
(oceoaeo- ).  B pep e aa  o    paepa,
opee騩 eo a COM popa.

CSEG      SEGMENT PUBLIC 'CODE'   'caaae oo cee
          ORG 0                   'a cpoa eoaea
          ASSUME CS:CSEG,DS:CSEG,ES:CSEG
DEVICE12  PROC FAR         'paep o aea poepa
          DD   0FFFFFFFFH  'apec ceeo paepa
          DW   8000H       'a apo
          DW   DEV_STATEGY 'apec poep cpae
          DW   DEV_INTERRUPT  'apec poep pepa
          DB   'AUX     ' ' cpoco (ooeoe poea)

   3. Coae cpae cpoca.

   poepa cpae  cpoca  pee  oo   cpo.  Koa
ccea apae cpoco,  o oa coae o  ax,  aae
aooo apoca.  O ee e 㭪樨. Bo-epx o c㦨 oac
ax  pex oepa権 cce.  oee ao o,  o aooo
apoca  c㦨  oac,  epe  oop pocxo oe opae
e paepo  ae eo popao.  Hapep,  oa  paep
o  ae,  o  e  aec apec ax epe aooo apoca.
Koa e paep aepae co pao, o o caaae  aooe
apoca a caca,  oop oce ae popae, e ca
aa oooc e 㧭a o o訡e.
   MS DOS  coae  aooo apoca p caoe paepa cpoca
(oa ccea apaec). poepa cpae cpoca oec
oo  o  pa    o  oe.  p  o ES:BX aa a o
coa aooo apoca  poepe 㦭o  poco  copoa  x,
o  ocec⢨  o  o    oape p opae  paep.
Apeca cee  ceea aooa oeac    e  epeee.  B
cee paee B 㢨e,  o p opae  paep, epoe o
o eae - occaaae ae ES:BX,  o oo o  o
opa  aooa apoca.
   Paep aooa apoca  oe  ec,    acoc  o  ⨯a
ceaoo  apoca  paep (ap.  aa,  o ax 
opa caca).  Oao epe 13 a aooa cea o  e e.
x opa ao:

1. a aooa apoca (DB).
2. Ko cpoca (DB). Opeee oep  ox cpoc.
3.   Ko oa (DB).  ec xpac oep ocee  ocao
paep oa.  o epece  [7.2.3].
4. Cac (DW).   Cac  caaaec  a  pa p oe
paepa. Ec caoe  15, o  ax oc쬨 ax axo-
c o o訡. Ko o訡o epece  [7.2.3].
5. Peepa oac (8 ao). coec MS DOS.

                                     - 4 -
6. ae eoxoe  pao paepa (epeeo ).

   H poe.

   Bo 5  cpo  poep  cpae  cpoca.  Oeae,  o  e
coe epeee,  xpae ae ES  BX,  ce a cpe
RET, a  ooeo  opae COM.

DEV_STRATEGY:   MOV  CS:KEEP_ES,ES
                MOV  CS:KEEP_BX,BX
                RET
KEEP_CS         DW ?
KEEP_BX         DW ?

   7.2.3 Coae opao稪a pepa cpoca.

   paep cpoca  a稭aec  c  x  op権 oa,  peex 
pex paeax. a  oa ceoa cooeca poepa
opao⪨   pepa.  Ha  cao  ee,  o  eepo,  aa  
poep poepo opao⪨ pepa,  a a oa oce e oc-
ae pepae  aepaec oo cpe RET.
   eec 13 ⨯o 㭪権,  oope oe  o  caaae
paep cpoca. Koa paep aec 㭪e DOS (cae 㭪-
e  3FH  pepa  21H,  oopa  ae  ae      aa   
cpoca), o 㭪 oeae oo oep o 1 o 13  ooaoe
oe o cee 2  aooe apoca ( oa - oo  oep  5).
ae  paee  epeaec  poepe opao⪨ pepa paepa,
aoec oopo opeeec p pocope  aooa  paepa  [7.2.1].
a  poepa  ep oepe occaaae ES:BX,  c e o o
aa a ao- oo apoca, a ae ae oo oep oa.
o o o poepa opao⪨ pepa ae 㦭 poep,
oopa  o  pee  㭪.  poepa  ec   c   oo
13-coo a,  coepae cee  13 ⨯o 㭪権.  㭪樨
cea epecc  cee op浪e:

   1. INITIALIZE (aa)
   2. CHECK_MEDIA (poepa oce)
   3. MAKE_BPB
   4. IOCTL_IN
   5. INPUT_DATA (o ax)
   6. NONDESTRUCT_IN
   7. INPUT_STATUS (cac oa)
   8. CLEAR_INPUT (oca oa)
   9. OUTPUT_DATA (o ax)
  10. OUTPUT_VERIFY (poepa oa)
  11. OUTPUT_STATUS (cac oa)
  12. CLEAR_OUTPUT (oca oa)
  13. IOCTL_OUT

   oce aepe   poep,   poepa    opao⪨    pepa
aepaec  cpe  RET    paee  opaaec  a
popa.  paep cpoca oe a o  opao⪨  oo
eoopx  㭪権,    acoc o cpoca  pe- eo cee
opo o訡o  pae cpoco.  Hoepa 㭪権,   oopx
e  aca  poep,  o  aepac  xoo   paepa e
oe  eo-o.  B  o  cae  ao  oo   epe   xoo
cao  15,  8,  1  0  aooe apoca, o oppoa
a aa,  o a apeo- aa ececa 㭪  (
15 pe o訡,  8 oaae, o paep paoae opao,

                                     - 5 -
a  0    1  a  o  o訡  3,  o  cooece  "eeco
oae").
   Ho oa 㭪 oa pccoa o cex paepax cpoc, 
o  㭪  oep  1  -  aa.  a  㭪 ao- aec
oec p ap㧪e paepa,  a ae e.  Oa  ax aa,
oea o poepo,  coco caoe apeca oa paepa 
epex aax,  a稭axc co cee 14    aooe  apoca.  B
epeeo pepe oe popa oee eo eop:. Kpoe o
aa,  poepa aa樨 oa ae o c eoxo
  aoo cpoca aa.
   Kae   ocaxc  12-  㭪権     e      paep
cpoca ac o oo, o paep oe ea. Heoope, ae
a CHECK_MEDIA  MAKE_BPB, oocc oo  o cpoca (o
caaa  ⨯  ca,  paep  ceopo    ..).   cox
cpoc  aoee  a묨  c  e   㭪樨:   INPUT_DATA   
OUTPUT_DATA  (oe⨬,  o    ea ecece - aa o 
ae 㭪権,  oopa eea). B oox cax aooo apoca
ee ce cpp:

13 ao    caap opa aooa apoca
 1 a      a oca cpe (oo  ox cpoc)
 4 aa     ceee/cee epa oea ax
 2 aa     co ao, oopoe ao epea
 2 aa     capo oep ceopa (oo  ox)

  B epeeo  pepe  coec  㭪 oa.  poepa,
oa o oae  aooa apoca apec epa,  oopo
axoc  oe  ae  (ceee 14).  Oa ae cae co
ao,  oopoe ao ec (ceee 18).  Koa poepa  aep
o  ax,  o  oa  cao  coo  caca   aooe apoca
(ceee 3)  opa paee.  Ec oe- pa cea,  o ao
cao    8  coa  caca.  p㣨e oooc  oc㦤e
oee.

   H poe.

   B ao  pepe  peea   oa   opa   poep   opao⪨
pepa, e a peaoo oa, paeo cpoco.

;---aa opao稪a pepa cpoca
DEV_INTERRUPT:  PUSH ES     ;coxpae pecp
                PUSH DS
                PUSH AX
                PUSH BX
                PUSH CX
                PUSH DX
                PUSH SI
                PUSH DI
                PUSH BP
   MOV  AX,CS:KEEP_ES    ;ES:BX aa a aooo apoca
   MOV  ES,AX            ;
   MOV  BX,CS:KEEP_BX    ;
   MOV  AL,ES:[BX]+2     ;oae o oa  aooa
   SHL  AL,1             ;㬭oae a 2 (.. aa coa)
   SUB  AH,AH            ;oe AH
   LEA  DI,FUNCTIONS     ;DI aae a ceee o a
   ADD  DI,AX            ;oae ceee  ae
   JMP  WORD PTR [DI]    ;epexo a apec  a


                                     - 6 -
FUNCTIONS       LABEL  WORD  ;o aa 㭪権
   DW   INITIALIZE
   DW   CHECK_MEDIA
   DW   MAKE_BPB
   DW   IOCTL_IN
   DW   INPUT_DATA
   DW   NONDESTRUCT_IN

   DW   INPUT_STATUS
   DW   CLEAR_INPUT
   DW   OUTPUT_DATA
   DW   OUTPUT_VERIFY
   DW   OUTPUT_STATUS
   DW   CLEAR_OUTPUT
   DW   IOCTL_OUT

;---xo  paepa, ec 㭪 e oepaec
CHECK_MEDIA:
MAKE_BPB:
IOCTL_IN:
INPUT_DATA:
NONDESTRUCT_IN:
INPUT_STATUS:
CLEAR_INPUT:
OUTPUT_VERIFY:
OUTPUT_STATUS:
CLEAR_OUTPUT:
IOCTL_OUT:
   OR   ES:WORD PTR [BX]+3,8103H   ;ope cac
   JMP  QUIT

;---poep  x oepaex oo
INITIALIZE:   LEA  AX,E_O_P      ;ceee oa popa  AX
   MOV  ES:WORD PTR [BX]+14,AX   ;oeae eo  aooo
   MOV  ES:WORD PTR [BX]+16,CS   ;
    .
   (ec e aa cpoca)
    .
   JMP  QUIT

OUTPUT_DATA:  MOV  CL,ES:[BX]+18 ;oae co coo
   CBW  CX                       ;CX coe a ce稪
   MOV  AX,ES:[BX]+16            ;oae apec epa ax
   MOV  DS,AX                    ;
   MOV  DX,ES:[BX]+14            ;
    .
   (ec  oepa樨 o o)
    .
   JMP  QUIT

;---xo, op a caca  aooe apoca
QUIT:   OR   ES:WORD PTR [BX]+3,100H  ;caaae  8
   POP BP                    ;occaaae pecp
   POP DI                    ;
   POP SI                    ;
   POP DX                    ;
   POP CX                    ;
   POP BX                    ;
   POP AX                    ;

                                     - 7 -
   POP DS                    ;
   POP ES                    ;
   RET
E_O_P:              ;ea oa popa
DEVICE12     ENDP
CSEG         ENDS
             END    DEVICE12

   epe opao paep  caaae  coo  caca    aooe
apoca.  B ao pepe o eaec  x ecax,  acoc o
oo aac 㭪 oece稢aea paepo   e.    cpo
룫 a: OR ES:WORD PTR [BX]+3,XXXXH. ae- e o XXXX ce-
ee:

    0-7   o o訡 (ec  15 = 1)
       8   caaaec  1, oa 㭪 aepea
       9   caaaec  1, oa paep a
  10-14   apeeppoa MS DOS
      15   caaaec p ooe o訡

Ma訩 a oo  coa  coep  cee  o o訡o, ec
caoe  15, p騩 o訡:

   0    oa ac a aeoe o ac cpoco
   1    eecoe cpoco
   2    cpoco e ooo
   3    eeca oaa
   4    o訡a poep o opoo c㬬e
   5    eepa a apoca  cpoc
   6    o訡a oca
   7    eec oce
   8    ceop e ae
   9    e a  pepe
   A    o訡a ac
   B    o訡a e
   C    oa o訡a

                    4 oc  paep cpoca.

   paep cpoca  caaaec  e e e oo- o
popa  a o䨣pa樨 cce.   cao poo popa
oece    a  CONFIG.SYS  cpo  DEVICE = DEVI- CE12.COM.  ae
epeap㧨e cce  cao  paepa.  Ec  a設a  e  e
apac,  o  copee  ceo  eec  o訡a    oe aa樨
paepa.
   oce oo  a  paep caoe,   oca  e oec
o묨  㭪ﬨ  MS  DOS  pepa  21H.  Kae   㭪樨   oo
cooa  ac  o  oo,  aee    cpoco  caapoe
cpoco DOS (a  peeo  pepe)    oo  oaec  a
coepeo ooe cpoco.   ae caapoo oceoaeoo
cpoca,  aoe paep AUX,  oce eo 㭪樨 3 pepa 21H
   ocec⢫  cooeceo  o    o.  Ec  cpoco
apaeoe,  o aoe eo PRN, oce eo 㭪 5 e o
ae  a pep.  po oooc ec cooae 㭪樨
3FH  oa   oa.  B o cae coe oep aa 3  -
  oceoaeoo cpoca  4 -  apaeoo.  Haoae,
o  p   cooa   peope-   eex   oepo   aa   e
eoxooc opa cpoco.
   Ec cpoco e aee oo   caapx  cpoc  MS  DOS

                                     - 8 -
(.e. ec oo e aao o  peepx co, a a PRN, AUX 
..),  o B oee op cpoco c oo oo  㭪権  
op  aa.  B  oee  cooa  a eo oca c oo
paeo oa aa, a  eo ecpopa aa, xo oce
peoeee.  o   epe,  o B o o訡e e opoee
co a,  oece oep aa   BX,  0  -    AL,  oce  eo
oe  㭪  44H pepa 21H.  o 㭪 IOCTL  ec  7
ae,  opaaeoo    DL  caoe,  o   paep   cpoca
ape.
   IOCTL pee, o  ae apo paepa a cooeca
caoa  o    o o pae epe oco poe- p opao⪨
IOCTL ec   poepe  opao稪a  pepa  paepa.  㭪
IOCTL  ee  8  o㭪権,  poepoax  o  0  o  7,  p  o
cooec騩 oo oep oeaec  AL p oe 㭪樨:

   0    Bopa opa o cpoce  DX
   1    cao opa o cpoce, co DL (DH=0)
   2    Ca CX ao o paepa cpoca epe pa-
        騩 aa  oec x a稭a c DS:DX
   3    aca CX ao  paep cpoca epe pa騩
        aa,  x a稭a c DS:DX
   4    To e, o  2, o cooa oep aoe  BL,
        e 0 = aoe o oa, 1 = A  ..
   5    To e, o  3, o cooa oep aoe a  5
   6    o cac oa
   7    o cac oa

   B oe opaaec paa opa,   acoc  o  oo,
aa 㭪 맢aa.   o㭪権 0  1 aee o pecpa DX
ceee (p co, o  7 = 1, o oaae, o oc oe
 cpoc, a e  a):

   0    1 = cpoco ocooo oa
   1    1 = cpoco ocooo oa
   2    1 = eoe cpoco
   3    1 = cpoco ac
   4    peep
   5    1 = e poep a Ctrl-Z, 0 = ec poepa a Ctrl-Z
   6    1 = e oe aa, 0 = oe aa
   7    1 = cpoco, 0 = co a
8-13    peep
  14    1 = ec oo cooa o㭪樨 2  3, 0 = e
  15    peep

   o㭪樨 2-5   oo   popae     cpoc  oeac
poo묨 pa騬 cpoa. o ooe epeaa pa-
e  cooe  oeo  o  ocooo ooa ax,  o ceceo
poae eo. p opae AX e coepa co epeax ao.
o㭪樨 6-7 oo popae poep,  ooo  cpoco 
oa  oa.   cpoc  AL opaaec FF,  ec cpoco
ooo  0, ec e. p c- ooa c op ao ( 7 = 0)
 AL opaaec FF o ex op, oa e e oc⣭ oe aa.

               5 Oapee  aa o訡o cpoca.

   cpoca o o訡ac o oo  pex p稭. cpoco oe
 䨧ec opeeo  axoc e  o cocoﭨ. Moe 
ox popaoe oeceee,  paee cpoco.  ,  aoe,
popaa  oe  oca  cpoc  eoc- ⨬ apoc (apep,

                                     - 9 -
oa ca a aoe,  e axo- c  cea  aea  o
ac).  MS  DOS oap㦨ae  aape o設co ax o訡o 
oece稢ae oooc  occaoe.

   H poe.

   oa paep  cpoc  coepa  ae  cepee  o訡,  o
popaa  poco e oe pooac,  oa o e  cpae.
Koa  ae  o訡  pocxo,  o   ccea   ae   opao稪
pecx  o訡o.  O  oe ca  ec⢨e a  caapx
cpoc,  a   caoex paepo.  oo- ae aoee
aco caaec c , oa aec poec co oepa c
cooo,    oopoo  opa  epa.  B  o  cae  oec
cooee: "Not ready error reading drive A - Abort, Retry, Ignore?"
   Opao稪 pecx o訡o oe  epeca,  o o  e
opaaa   cpoca,      oopx  B  coa  caaaee
paep.  Beop pepa 24H aae a caap poep  MS
DOS,  o B oee epeapa eop a co po- ep. p oe
o poep cap訩  AH  coep  0  ec  o訡a  pooa  a
oo  cpoce    1,  ec  a  coo.  BP:SI  aa  a
aooo  paepa  ooo  cpoca,  oo-   p   oe   a
ooe  opa.  Boce  ao,  a稭a  co cee AH 
aooe coepa    cpoca,  a  opao稪  pex  o訡o
oeae  o  o訡  o  coo  DI.  Bo ooe oepa (o e
peca ox o権):

   Ko           poea

    0      oa ca a c, ae o ac
    1      eecoe cpoco
    2      aoe e oo
    3      eeca oaa
    4      o訡a oea a묨
    5      eepa a apoca
    6      o訡a oca

    7      eec ⨯ oce
    8      ceop e ae
    9      e a  pepe
    A      o訡a p ac
    B      o訡a p e
    C      oa o訡a

  B cae  coo  o訡  AL coep oep aoe,  a oopo
pooa o訡a (0 = A,  1 = B  ..),  a  2-0 AH p  ⨯
o訡.   0 caaaec, ec o訡a pooa o pe oepa樨
ac,    cpacaec  -  ec  p  e.    2-1  co-  epa
opa o o,   ao ece ca pooa o訡a, aa 00 - 
aax ceopo DOS,  01 -  FAT,  10 -  aaoa   11  -  
ceo ocaoo ca.
   eec p cocoa,  oop묨 popaa oe occaoc  oce
peco o訡:

  1. Moo  opoc  ooae cpa p稭 o訡 (apep,
ap ep aoe),  oce eo ccea peoca  cpoc
oooc oop oepa.
  2. paee oe  opaeo cp樨, cee a INT 21H,
oopa  ceaa  o  opac   paep.  3.  popaa oe
aepc  ep paee ccee.

                                     - 10 -
   Baa poepa  opao⪨ o訡o oe occao ca,  a
cp  IRET,  oce  oo,  a  oa  oec⨫a  0    AL,   o
oppoa o訡, 1 - o oop oepa  2 - o aep
popa.  Ec B xoe, o Baa poepa poea occaoee
caa,  o  oa  oa  occao  pecp oeo popa 
cea,  a ae a co cea ce,  poe ocex pex co. oce
oo cp IRET opa paee popae, xo caa ccea
ocaec  ecao cocoﭨ o ex  op,  oa  oa  e  ceae
o  㭪樨  c  oepo  o訬,  e  12.  Bo  o䨣pa cea
(a稭a  cepx  o  a)  oa  aec  opao稪  pecx
o訡o:

Apec opaa opao稪a o訡o:  IP, CS, a

ooaece pecp aa,   AX, BX, CX, DX, SI, DI, BP,
 oopo  맢a paep:      DS, ES, IP, CS, a

   MS DOS  opaaae  ae  oe   epece   o訡.   Ca
ac o o訡o,  oope o opaac  pecpax,  oa
aac 㭪 DOS.   o oc㦤ac    ao  e    ex
ecax,    oopx ocac cooece 㭪樨.  Oao ee
,  o a稭a c epc 3.0 MS  DOS  opaae  pacpee  o
o訡o  㭪権,  cox FCB  ecpop ao. Koa p
oe oo  x 㭪権 ca- aaec a epeoca,  o 
AX  opaaec  o  o  o訡.  ooe pacpe o
oce epe pepae 59H,  ec   BX  oec  0.  a  㭪
cooae  ae  o pecx o訡ax  oa oe  cooaa 
opao稪a pecx o訡o, aeoo epe pepae 24H.
   㭪 oeae  AX o o訡,   ooo cca aox
oo o訡o (apep,  "eocaoo a")  o  ox oo
(apep,  "opaee oca"  oooo- aeco cce).
BH opaae o acca o訡, aa aoo ⨯a o訡a pooa.
Hapep,  o  1 aae,  o cepa pecpc,  .e.  o a,
aoe epa   o-o  ee  pacxooao.  p㣨e  acc  o
aa a popae o訡, poe c oceﬨ, opapoae
 ..  BL coep o,  peoaa騩 ec⢨e    occaoe,
aoe  a  "oop",  "pepa"   "apoc  ooae".
Haoe, CH opaae co, opeeee eco e o poe:
a oo cpoce, a coo,  a?
   ae  x oo o訡o eca op. o opa o x
c.   Texeco pooce o MS DOS 3.0. oco peoaaec,
o MS DOS 3.0 e e cooac a a設ax,  oee  pax,  e
AT,  o  cooae  x  oo  opa稢ae  coec⨬oc  Bax
popa.  Te e eee,  aop poep, peaae oo  MS
DOS  3.0 oe ooc oepx ox poep opao⪨ o訡o.
   Haoe, ee , o poecc oe epeaa o aep- e
맢ae eo poecc. Tep poecc oocc  ao- ec騬
popaa. Hapep, oa oa popaa apae  acae p
c oo 㭪樨 EXEC, o acaea popaa aaec ooo, a
acaa  popaa  -  poee.  Poe   oe   opeoac
opa  o  o,  a  aep訫c  ooo.  o  cooa 
oooc, oece eae o aepe  AL  oe 㭪
4CH  pepa  21H   aepe popa.  Koa paee e
opaeo poe,  o o o 㭪 4DH  pepa  21H  (e
xox  pecpo)   AL e oe o aepe,  oop oe
ae  poaapoa. Kpoe oo, AH e coepa opa o
o,  a  aep訫c ooo:  0 -  opaoo aepe,  1 - o
Ctrl-Break,  2 - o peco o訡e cpoca  3 - c oo 㭪-
樨 31H, ocae aa peeo.

                                     - 11 -
   Ec popaa aep訫ac c oo o 㭪樨 (a e 20H ), o MS
DOS  oae  o xoa  o oe  e  opao oa
ao c oo oo- a IF.  a  ooaa  ooe  cooe
cee    p㣨x   oa      oaoo   aa.   Ko   xoa
paccapaec a oep ERRORLEVEL  coe oepa樨 oc  
acoc o oo,  oe o  e opeeeoo ca.  C oo
o oooc oae a o pepaa opao   o
cooee o ooe o訡  oo  aex popa. oee
opoa opa peea  paee "Koa aeo opa- o⪨"
pooca o oepaoo ccee.

         6. cooae ceax cpoc oa/oa.

   eec opooe  oeco  cpoc oa/oa,  oope o
 pcoee  IBM PC,  a , oc⨪, pao- ocpoe
  ..  B  ao  paee  oc㦤ac oo e cpoca,  oope
ceao  oepac  oopoae  IBM   PC.   Ca   oocc
accee aoo, ceooe epo  p㣨e cpoca, oope o
 pcoee epe poo  op.  Apeca  opo,  oocec  
p㣨   cpoca,   oc㦤ac     p㣨x  paeax  o  ,
oocxc eo  a cpoca. Pacpeeee apeco opo 
ocoo oo  o e  cex ⨯o IBM PC:

Apec opa        㭪

  00-0F      pocxea DMA 8237
  20-2F      pocxea pepa 8259 (AT opoep #1: 20-3F)
  40-4F      pocxea aepa 8253/8254
  60-6F      pocxea PPI 8255 (AT coe oo apeca
             aap
  70-7F      ac peaoo pee (oo AT)
  A0-BF      pocxea pepa #2 (oo AT)
  F0-FF      PCjr - opoep HM, AT - paee aeae-
             c copoeccopo
1F0-1F8      䨪cpoa c AT
200-20F      poo aaep
278-27F      AT o㭨ao op #2
2F8-2FF      o㭨ao op COM2 (
320-32F      䨪cpoa c XT
378-37F      aaep apaeoo pepa  PC, XT, AT
3B0-3BF      ooxpo/apae aaep
3D0-3DF      eo paec aaep
3F0-3F7      opoep HM

 ;****************************************************
 ;*                    PROLOG                        *
 ;* THIS IS AN INSTALLABLE DEVICE DRIVER FOR AN      *
 ;* IN STORAgE DISKETTE (VIRTUAL) WITH 180K CAPACITY *
 ;****************************************************
 CSEG     SEGMENT PARA PUBLIC 'CODE'
 ;
 ;       M A C R O ( S )
 ;
 STATUS      MACRO    STATE,ERR,RC
 IFIDN   <STATE>,<DONE>
         OR      ES:WORD PtR SRH_STA_FLD[BX],0100H
 ENDIF
 IFIDN   <STATE>,<BUSY>
         OR      ES:WORD PTR SRH_STA_FLD[BX],0200H

                                     - 12 -
 ENDIF
 IFIDN   <ERR>,<ERROR>
         OR      ES:WORD PTR SRH_STA_FLD[BX],1000H
 INDIF
 IFNB    <RC>
         OR      ES:WORD PTR SRH_STA_FLD[BX],RC
 ENDIF
 ENDM
 ;
 ;       E Q U A T E S
 ;
 ; READ/WRITE
 ;
 SRH            EQU    0     ;STATIC REQUEST HEADER START
 SRH_LEN        EQU    13    ;   "      "      "   length
 Srh_LEN_FLD    EQU    SRH   ;   "      "      "    "    FIELD
 SRH_UCD_FLD    EQU    SRH+1 ;   "      "      "   unit code field
 srh_CCD_FLD    EQU    SRH+2 ;   "      "      "   command code field
 srh_STA_FLD    EQU    SRH+3 ;   "      "      "   STATUS FIELD
 SRH_RES_FLD    EQU    SRH+5 ;   "      "      "   reserved area field
 ;
 MD             EQU    SRH+SRH_LEN   ;MEDIA DESCRIPTOR BYTE
 MD_LEN         EQU    1             ;  "      "      "   lenGth
 dta            equ    md+MD_LEN     ;DISK TRANSFER ADDRESS
 DTA_LEN        EQU    4             ; DTA LENGTH
 COUNT          EQU    DTA+DTA_LEN   ;BYTE/SECTOR COUNT
 COUNT_LEN      EQU    2             ;    "          "   LENGTH
 SSN            EQU    COUNT+COUNT_LEN;STARTIND SECTOR nuMBER
 SSN_LEN        EQU    2             ;   "       "      "   length
 ;
 ; MEDIA CHECK
 ;
 RET_BYTE       EQU    MD+MD_LEN  ;BYTE RETURNED FROM DRIVER
 ;
 ; BUILD BPB
 ;
 BPBA_PTR       EQU    DTA+DTA_LEN   ;POINTER TO BPB

 BPBA_PTR_LEN   EQU    4             ;   "     "  "   LENGTH
 ;
 ; INIT
 ;
 UNITS          EQU    SRH+SRH_LEN
 UNITS_LEN      EQU    1
 BR_ADDR_0      EQU    UNITS+UNITS_LEN
 BR_ADDR_1      EQU    BR_ADDR_0+2
 BR_ADDR_LEN    EQU    4
 BPB_PTR_OFF    EQU    BR_ADDR_0+BR_ADDR_LEN
 BPB_PTR_SEG    EQU    BPB_PTR_OFF+2
  ;
  ;
  VDSK           PROC   FAR
                 ASSUME    CS:CSEG,ES:CSEG,DS:CSEG
  BEGIN:
  START          EQU    $
  ;     S P E C I A L   D E V I C E   H E A D E R
 NEXT_DEV        DD     -1           ;POINTER TO NEXT DEVICE
 ATTRIBUTE       DW     2000H        ;BLOCK DEVICE (non-ibm fORmat)
 STRATEGY        DW     DEV_STRATEGY ;POINTER TO DEVICE STRATEGY

                                     - 13 -
 INTERRUPT       DW     DEV_INT      ;POINTER TO DEVICE INTERRUPT HANDLER
 DEV_NAME        DB     1            ;NUMBER OF BLOCK DEVICES
                 DB     7 DUP(?)     ;7 BYTES OF FILLER


 RH_OFF          DW     ?   ;REQUEST HEADER OFFSET
 RH_SEG          DW     ?   ;REQUEST HEADER SEGMENT
 ; BIOS PARAMETER BLOCK
 BPB             EQU     $
                 DW      512   ;SECTOR SIZE
                 DB      1     ;SECTORS/ALLOCATION UNIT
                 DW      1     ;NUMBER OF RESERVED SECTORS
                 DB      2     ;NUMBER OF FATS
                 DW      64    ;NUMBER OF DERECTORY ENTRIES
                 DW      360   ;TOTAL NUMBER OF SECTORS
                 DB      0FCH  ;MEDIA DESCRIPTOR
                 DW      2     ;NUMBER OF SECTORS OCCUPIED BY FAT
      ;
 BPB_PTR         DW  BPB  ;BIOS PARAMETER BLOCK POINTER ARRAY (1 ENTRY)
 ; CURRENT VIRTUAL DISK INFORMATION
 TOTAL           DW  ? ;TOTAL SEKTORS TO TRANSFER
 VERIFY          DB  0 ;VERIFY 1=YES,   0=NO
 START_SEC       DW  0 ;STARTING SECTOR NUMBER
 VDISK_PTR       DW  0  ;STARTING SEGMENT OF VIRTRUAL DISK
 USER_DTA        DD  ?  ;POINTER TO CALLERS DISK TRANSFER ADDRESS
 BOOT_REC        EQU $ ;DUMMY DOS BOOT RECORD
                 DB  3 DUP(0) ;3 BYTE JuMP TO BOOT CODE (NOT BOOTABLE)




 db    'IBM  2.0' ;VENDOR IDENTIFICATION

 DW    512       ;NUMBER OF BYTES IN A SECTOR
 DB    1         ;1 SECTOR PER ALLOCATION UNIT
 DW    1         ;1 RESERVED SECTOR
 DB    2         ;2 FATS
 DW    64        ;NUMBER OF DIRECTORY ENTRIES
 DW    360       ;360 TOTAL SECTORS IN IMAGE
 DB    0FCH      ;TELLS DOS THIS IS A SINGLE SIDED 9 SECTOR DISK
 DW    2         ;NUMBER OF SECTORS IN FAT
      ;
      ;    FUNCTION TABLE
      ;
      FUNTAB   LABEL   BYTE
 DW   INIT            ;INITIALIZATION
 DW   MEDIA_CHECK     ;MEDIA CHECK (BLOCK ONLY)
 DW   BUILD_BPB       ;BUILD BPB   "   "
 DW   IOCTL_IN        ;IOCTL INPUT
 DW   INPUT           ;INPUT (READ)
 DW   ND_INPUT        ;NON_DESTRUCTIVE INPUT NO WAIT (CHER ONLY)
 DW   IN_STAT         ;INPUT STATUS   "   "
 DW   IN_FLUSH        ;INPUT FLUSH  "   "
 dw   output          ;OUTPUT (WRITE)
 DW   OUT_VERIFY      ;OUTPUT (WRITE)WITH VERIFY   "   "
 DW   OUT_STAT        ;OUTPUT STATUS    "   "
 DW   OUT_FLUSH       ;OUTPUT FLUSH
 DW   IOCTL_OUT       ;IOCTL OUTPUT
     ;

                                     - 14 -
     ; L O C A L   P R O C E D U R E S
     ;
     IN_SAVE   PROC  NEAR
   MOV    AX,ES:WORD PTR DTA[BX]   ;SAVE CALLERS DTA
   MOV    CS:USER_DTA,AX
   MOV    AX,ES:WORD PTR DTA+2[BX]
   MOV    CS:USER_DTA+2,AX
   MOV    AX,ES:WORD PTR COUNT[BX] ;SET NUMBER OF SECTORS TO READ
   XOR    AH,AH
   MOV    CS:TOTAL,AX              ;MOVE NUMBER OF SECTORS TO TOTAL
   RET
      IN_SAVE        ENDP
      ;
      CALC_ADDR PROC NEAR
   MOV    AX,CS:START_SEC  ;GET STARTING SECTOR NUMBER
   MOV    CX,20H           ;MOV 512 TO CX SEGMENT STYLE
   MUL    CX               ;MULTIPLY TO GET ACTUAL SECTOR
   MOV    DX,CS:VDISK_PTR  ;GET SEGMENT OF VIRTUAL DISK
   ADD    DX,AX            ;ADD THET SEGMENT TO INITIAL SEGMENT
   MOV    DS,DX            ;SAVE THAT AS TNE ACTUAL SEGMENT
   XOR    SI,SI            ;IT,S ON A PARAGRAPH BOUNDERY
   MOV    AX,CS:TOTAL      ;TOTAL NUMBER OF SECTORS TO READ
   MOV    CX,512           ;BYTES PER SECTOR
   MUL    CX               ;MULTIPLY TO GET COPY LENGTH
   OR     AX,AX            ;CHECK FOR GREATER THEN 64K
   JNZ    MOVE_IT
   MOV    AX,0FFFFH        ;MOVE IN FOR 64K
      MOVE_IT:
   XCHG   CX,AX            ;MOVE LENGTH TO CX
   RET
      CALC_ADDR ENDP
      ;
      SECTOR_READ PROC NEAR
   CALL    CALC_ADDR        ;CALCULATE THE STARTING "SECTOR"
   MOV     ES,CS:USER_DTA+2 ;SET DESTINATION <ES:DI> TO POINT
   MOV     DI,CS:USER_DTA   ;TO CALLERS DTA
      ;
      ; CHECK FOR DTA WRAP IN CASE WE CEME THROUGH UIA VERIFY
      ;
   MOV    AX,DI          ;GET OFFSET OF DTA
   ADD    AX,CX          ;ADD COPY LENGTH TO IT
   JNC    READ_COPY      ;CARRY FLAG = 0, NO WRAP
   MOV    AX,0FFFFH      ;MAX LENGTH
   SUB    AX,DI          ;SUBTRACT DTA OFFSET FROM MAX
   MOV    CX,AX          ;USE THET AS COPY LENGTH TO AVDID WRAP
      READ_COPY:
   REP    MOVSB          ;DO THE "READ"
   RET
      SECTOR_READ ENDP
      ;
      SECTOR_WRITE PROC NEAR
   CALL      CALC_ADDR        ;CALCULATE STARTING "SECTOR"
   PUSH      DS
   POP       ES               ;ESATABLISH ADDRESSABILITY
   MOV       DI,SI            ; ES:DI POINT TO "DISK"
   MOV       DS,CS:USER_DTA+2 ; DS:SI POINT TO CALLERS DTA
   MOV       SI,CS:USER_DTA
      ;
      ; CHECK FOR DTA WRAP

                                     - 15 -
      ;
   MOV    AX,SI           ;MOVE DTA OFFSET TO AX
   ADD    AX,CX           ;ADD COPY LENGTH TO OFFSET
   JNC    WRITE_COPY      ;CARRY FLAG = 0, NO SEGMENT WRAP
   MOV    AX,0FFFFH       ;MOVE IN MAX COPY LENGTH
   SUB    AX,SI           ;SUBTRACT DTA OFFSET FROM MAX
   MOV    CX,AX           ;USE AS NEW COPY LENGTH TO AVOID WRAP
      WRITE_COPY:
   REP    MOVSB           ;DO THE "WRITE"
   RET
      SECTOR_WRITE ENDP


   PAGE
      ;
      ;  D E V I C E    S T R A T E G Y
      ;
      DEV_STRATEGY:
   MOV     CS:RH_SEG,ES     ;SAVE SEGMENT OF REQUEST HEADER POINTER
   MOV     CS:RH_OFF,BX     ;SAVE OFFSET  OF     "     "      "
   RET
      ;
      ;  D  E V I C E    I N T E R R U P T   H A N D L E R
      ;
      DEV_INT:
      ; PRESERVE MACHINE STATE ENTRY
   CLD
   PUSH     DS
   PUSH     ES
   PUSH     AX
   PUSH     BX
   PUSH     CX
   PUSH     DX
   PUSH     DI
   PUSH     SI
      ;
      ; DO THE BRANCH ACCORDING TO THE FUNCTION PASSED
      ;
   MOV      AL,ES:[BX]+2   ;GET FUNCTION BYTE
   ROL      AL,1           ;GET OFFSET INTO TABLE
   LEA      DI,FUNTAB      ;GET ADDRESS OF FUNCTION TABLE
   XOR      AH,AH
   ADD      DI,AX
   JMP      WORD PTR[DI]
      ;
      ;    INIT
      ;
      INIT:
   PUSH   CS
   POP    DX               ;CURRENT CS TO DX
   LEA    AX,CS:VDISK      ;GET ADDRESS OF VIRTUAL DISK
   MOV    CL,4
   ROR    AX,CL            ;DIVIDE BY 16 (PARAGRAPH FORM)
   ADD    DX,AX            ;ADD TO CURRENT CS VALUE
   MOV    CS:VDISK_PTR,DX  ;SAVE AS STARTING SEGMENT OF VIRTUAL DISK
   MOV    AX,2D00H         ; ADD 2D00H PARAGRAPHS TO STARTING
   ADD    DX,AX            ;  SEGMENT OF VIRTUAL DISK
   MOV    ES:WORD PTR BR_ADDR_0[BX],0
   MOV    ES:BR_ADDR_1[BX],DX     ;MAKE THET THE BREAK ADDRESS

                                     - 16 -
   MOV    ES:BYTE PTR UNITS[BX],1 ;NUMBER OF DISKETTE UNITS
   LEA    DX,BPB_PTR              ;GET ADDRESS OF BPB POINTER ARRAY
   MOV    ES:BPB_PTR_OFF[BX],DX   ;SAVE OFFSET IN DATA PACKET
   MOV    ES:BPB_PTR_SEG[bx],cs   ;SAVE SEGMENT IN DATA PACKET
   MOV    ES,CS:VDISK_PTR     ;GET STARTING SECTOR OF VIRTUAL DISK
   XOR    DI,DI               ;ZERO OUT DI (BOOT RECORD)
   LEA    SI,BOOT_REC         ;ADDRESS OF BOOT RECORD
   MOV    CX,24               ;
   REP    MOVSB               ;COPY 24 BYTES OF BOOT RECORD
   MOV    CS:WORD PTR START_SEC,1
   MOV    CS:WORD PTR TOTAL,2
   CALL   CALC_ADDR           ;CALCULATE ADDRESS OF LOGICAL SECTOR 1
   PUSH   DS
   POP    ES
   MOV    DI,SI                    ;MOVE THET ADDRESS TO ES DI
   XOR    AL,AL
   REP    STOSB                    ;ZERO OUT FAT AREA
   MOV    DS:BYTE PTR [SI],0FCH    ;SET THE FIRST FAT ENTRY
   MOV    DS:BYTE PTR 1[SI],0FFH
   MOV    DS:BYTE PTR 2[SI],0FFH
   PUSH   DS                  ;SAVE POINTER TO FAT
   PUSH   SI                  ;ON THE STACK
   MOV    CS:WORD PTR START_SEC,3
   MOV    CS:WORD PTR TOTAL,2
   CALL   CALC_ADDR           ;CALCULATE ADDRESS OF LOGICAL SECTOR 3
   PUSH   DS
   POP    ES
   MOV    DI,SI               ;MOVE THET ADDRESS TO ES:DI
   POP    SI
   POP    DS                  ;RESTORE ADDRESS TO FIRST FAT
   REP    MOVSB               ;COPY FIRST FAT TO SECOND FAT
   MOV    CS:WORD PTR START_SEC,5
   MOV    CS:WORD PTR TOTAL,4
   CALL   CALC_ADDR           ;CALCULATE ADDR OF L.5. 5 (START OF DIR)
   XOR    AL,AL
   PUSH   DS
   POP    ES                  ;SET UP ES.DI TO POINT TO IT
   XOR    DI,DI
   REP    STOSB               ;ZERO OUT DIRECTORY
   MOV    ES,CS:RH_SEG        ;RESTORE ES:BX TO REQUEST HEADER
   MOV    BX,CS:RH_OFF
     ;     STATUS    DONE,NOERROR,0  ;SET STATUS WORD (DONE, NOERROR)


   JMP            EXIT
      ;
      ; MEDIA CHECK
      ;
     MEDIA_CHECK:                     ;MEDIA CHECK (BLOCK ONLY)
      ;
      ; SET MEDIA NOT CHENGED
      ;
          MOV            ES:BYTE PTR RET_BYTE[BX],1           ;STORE IN RETURN BYTE
     ;           STATUS    DONE,NOERROR,0  ;TURN ON THE DONE BIT
          JMP            EXIT
      ;
      ; BUILD BIOS PARAMETER BLOCK
      ;
      BUILD_BPB:

                                     - 17 -
          PUSH             ES              ;SAVE SRH SEGMENT
          PUSH             BX              ;SAVE SRH OFFSET
          MOV            CS:WORD PTR START_SEC,0
          MOV            CS:WORD PTR TOTAL,1
          CALL             CALC_ADDR             ;CALCULATE ADDRESS OF FIRST SECTOR
          PUSH             CS
          POP            ES
          LEA            DI,BPB             ;ADDRESS OF BIOS PARAMETER BLOCK
          ADD            SI,11             ;ADD 11 TO SI
          MOV            CX,13             ;LENGTH OF BPB
     REP     MOVSB
          POP            BX                     ;RESTORE OFFSET
