home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / DRI-archive / manuals / archive / cpm22htm / axa.asm next >
Assembly Source File  |  2009-12-11  |  12KB  |  505 lines

  1. ;    MDS-800 I/O Drivers for CP/M 2.2
  2. ;    (four drive single density version)
  3. ;
  4. ;    Version 2.2 February, 1980
  5. ;
  6. vers    equ    22    ;version 2.2
  7. ;
  8. ;    Copyright (c) 1980
  9. ;    Digital Research
  10. ;    Box 579, Pacific Grove
  11. ;    California, 93950
  12. ;
  13. ;
  14. true    equ    0ffffh    ;value of "true"
  15. false    equ    not true    ;"false"
  16. test    equ    false    ;true if test bios
  17. ;
  18.     if    test
  19. bias    equ    03400h    ;base of CCP in test system
  20.     endif
  21.     if    not test
  22. bias    equ    0000h    ;generate relocatable cp/m system
  23.     endif
  24. ;
  25. patch    equ    1600h
  26. ;
  27.     org    patch
  28. cpmb    equ    $-patch    ;base of cpm console processor
  29. bdos    equ    806h+cpmb    ;basic dos (resident portion)
  30. cpml    equ    $-cpmb    ;length (in bytes) of cpm system
  31. nsects    equ    cpml/128    ;number of sectors to load
  32. offset    equ    2    ;number of disk tracks used by cp/m
  33. cdisk    equ    0004h    ;address of last logged disk on warm start
  34. buff    equ    0080h    ;default buffer address
  35. retry    equ    10    ;max retries on disk i/o before error
  36. ;
  37. ;    perform following functions
  38. ;    boot    cold start
  39. ;    wboot    warm start (save i/o byte)
  40. ;    (boot and wboot are the same for mds)
  41. ;    const    console status
  42. ;        reg-a = 00 if no character ready
  43. ;        reg-a = ff if character ready
  44. ;    conin    console character in (result in reg-a)
  45. ;    conout    console character out (char in reg-c)
  46. ;    list    list out (char in reg-c)
  47. ;    punch    punch out (char in reg-c)
  48. ;    reader    paper tape reader in (result to reg-a)
  49. ;    home    move to track 00
  50. ;
  51. ;    (the following calls set-up the io parameter block for the
  52. ;    mds, which is used to perform subsequent reads and writes)
  53. ;    seldsk    select disk given by reg-c (0,1,2...)
  54. ;    settrk    set track address (0,...76) for subsequent read/write
  55. ;    setsec    set sector address (1,...,26) for subsequent read/write
  56. ;    setdma    set subsequent dma address (initially 80h)
  57. ;
  58. ;    (read and write assume previous calls to set up the io parameters)
  59. ;    read    read track/sector to preset dma address
  60. ;    write    write track/sector from preset dma address
  61. ;
  62. ;    jump vector for indiviual routines
  63.     jmp    boot
  64. wboote:    jmp    wboot
  65.     jmp    const
  66.     jmp    conin
  67.     jmp    conout
  68.     jmp    list
  69.     jmp    punch
  70.     jmp    reader
  71.     jmp    home
  72.     jmp    seldsk
  73.     jmp    settrk
  74.     jmp    setsec
  75.     jmp    setdma
  76.     jmp    read
  77.     jmp    write
  78.     jmp    listst    ;list status
  79.     jmp    sectran
  80. ;
  81.     maclib    diskdef    ;load the disk definition library
  82.     disks    4    ;four disks
  83.     diskdef    0,1,26,6,1024,243,64,64,offset
  84.     diskdef    1,0
  85.     diskdef    2,0
  86.     diskdef    3,0
  87. ;    endef occurs at end of assembly
  88. ;
  89. ;    end of controller - independent code, the remaining subroutines
  90. ;    are tailored to the particular operating environment, and must
  91. ;    be altered for any system which differs from the intel mds.
  92. ;
  93. ;    the following code assumes the mds monitor exists at 0f800h
  94. ;    and uses the i/o subroutines within the monitor
  95. ;
  96. ;    we also assume the mds system has four disk drives
  97. revrt    equ    0fdh    ;interrupt revert port
  98. intc    equ    0fch    ;interrupt mask port
  99. icon    equ    0f3h    ;interrupt control port
  100. inte    equ    0111$1110b    ;enable rst 0(warm boot), rst 7 (monitor)
  101. ;
  102. ;    mds monitor equates
  103. mon80    equ    0f800h    ;mds monitor
  104. rmon80    equ    0ff0fh    ;restart mon80 (boot error)
  105. ci    equ    0f803h    ;console character to reg-a
  106. ri    equ    0f806h    ;reader in to reg-a
  107. co    equ    0f809h    ;console char from c to console out
  108. po    equ    0f80ch    ;punch char from c to punch device
  109. lo    equ    0f80fh    ;list from c to list device
  110. csts    equ    0f812h    ;console status 00/ff to register a
  111. ;
  112. ;    disk ports and commands
  113. base    equ    78h    ;base of disk command io ports
  114. dstat    equ    base    ;disk status (input)
  115. rtype    equ    base+1    ;result type (input)
  116. rbyte    equ    base+3    ;result byte (input)
  117. ;
  118. ilow    equ    base+1    ;iopb low address (output)
  119. ihigh    equ    base+2    ;iopb high address (output)
  120. ;
  121. readf    equ    4h    ;read function
  122. writf    equ    6h    ;write function
  123. recal    equ    3h    ;recalibrate drive
  124. iordy    equ    4h    ;i/o finished mask
  125. cr    equ    0dh    ;carriage return
  126. lf    equ    0ah    ;line feed
  127. ;
  128. signon:    ;signon message: xxk cp/m vers y.y
  129.     db    cr,lf,lf
  130.     if    test
  131.     db    '32'    ;32k example bios
  132.     endif
  133.     if    not test
  134.     db    '00'    ;memory size filled by relocator
  135.     endif
  136.     db    'k CP/M vers '
  137.     db    vers/10+'0','.',vers mod 10+'0'
  138.     db    cr,lf,0
  139. ;
  140. boot:    ;print signon message and go to ccp
  141. ;    (note: mds boot initialized iobyte at 0003h)
  142.     lxi    sp,buff+80h
  143.     lxi    h,signon
  144.     call    prmsg    ;print message
  145.     xra    a    ;clear accumulator
  146.     sta    cdisk    ;set initially to disk a
  147.     jmp    gocpm    ;go to cp/m
  148. ;
  149. ;
  150. wboot:;    loader on track 0, sector 1, which will be skipped for warm 
  151. ;    read cp/m from disk - assuming there is a 128 byte cold start
  152. ;    start.
  153. ;
  154.     lxi    sp,buff    ;using dma - thus 80 thru ff available for stack
  155. ;
  156.     mvi    c,retry    ;max retries
  157.     push    b
  158. wboot0:    ;enter here on error retries
  159.     lxi    b,cpmb    ;set dma address to start of disk system
  160.     call    setdma
  161.     mvi    c,0    ;boot from drive 0
  162.     call    seldsk
  163.     mvi    c,0
  164.     call    settrk    ;start with track 0
  165.     mvi    c,2    ;start reading sector 2
  166.     call    setsec
  167. ;
  168. ;    read sectors, count nsects to zero
  169.     pop    b    ;10-error count
  170.     mvi    b,nsects
  171. rdsec:    ;read next sector
  172.     push    b    ;save sector count
  173.     call    read
  174.     jnz    booterr    ;retry if errors occur
  175.     lhld    iod    ;increment dma address
  176.     lxi    d,128    ;sector size
  177.     dad    d    ;incremented dma address in hl
  178.     mov    b,h
  179.     mov    c,l    ;ready for call to set dma
  180.     call    setdma
  181.     lda    ios    ;sector number just read
  182.     cpi    26    ;read last sector?
  183.     jc    rd1
  184. ;    must be sector 26, zero and go to next track
  185.     lda    iot    ;get track to register a
  186.     inr    a
  187.     mov    c,a    ;ready for call
  188.     call    settrk
  189.     xra    a    ;clear sector number
  190. rd1:    inr    a    ;to next sector
  191.     mov    c,a    ;ready for call
  192.     call    setsec
  193.     pop    b    ;recall sector count
  194.     dcr    b    ;done?
  195.     jnz    rdsec
  196. ;
  197. ;    done with the load, reset default buffer address
  198. gocpm:    ;(enter here from cold start boot)
  199. ;    enable rst0 and rst7
  200.     di
  201.     mvi    a,12h    ;initialize command
  202.     out    revrt
  203.     xra    a
  204.     out    intc    ;cleared
  205.     mvi    a,inte    ;rst0 and rst7 bits on
  206.     out    intc
  207.     xra    a
  208.     out    icon    ;interrupt control
  209. ;
  210. ;    set default buffer address to 80h
  211.     lxi    b,buff
  212.     call    setdma
  213. ;
  214. ;    reset monitor entry points
  215.     mvi    a,jmp
  216.     sta    0
  217.     lxi    h,wboote
  218.     shld    1    ;jmp wboot at location 00
  219.     sta    5
  220.     lxi    h,bdos
  221.     shld    6    ;jmp bdos at location 5
  222.     if    not test
  223.     sta    7*8    ;jmp to mon80 (may have been changed by ddt)
  224.     lxi    h,mon80
  225.     shld    7*8+1
  226.     endif
  227. ;    leave iobyte set
  228. ;    previously selected disk was b, send parameter to cpm
  229.     lda    cdisk    ;last logged disk number
  230.     mov    c,a    ;send to ccp to log it in
  231.     ei
  232.     jmp    cpmb
  233. ;
  234. ;    error condition occurred, print message and retry
  235. booterr:
  236.     pop    b    ;recall counts
  237.     dcr    c
  238.     jz    booter0
  239. ;    try again
  240.     push    b
  241.     jmp    wboot0
  242. ;
  243. booter0:
  244. ;    otherwise too many retries
  245.     lxi    h,bootmsg
  246.     call    prmsg
  247.     jmp    rmon80    ;mds hardware monitor
  248. ;
  249. bootmsg:
  250.     db    '?boot',0
  251. ;
  252. ;
  253. const:    ;console status to reg-a
  254. ;    (exactly the same as mds call)
  255.     jmp    csts
  256. ;
  257. conin:    ;console character to reg-a
  258.     call    ci
  259.     ani    7fh    ;remove parity bit
  260.     ret
  261. ;
  262. conout:    ;console character from c to console out
  263.     jmp    co
  264. ;
  265. list:    ;list device out
  266. ;    (exactly the same as mds call)
  267.     jmp    lo
  268. ;
  269. listst:
  270.     ;return list status
  271.     xra    a
  272.     ret        ;always not ready
  273. ;
  274. punch:    ;punch device out
  275. ;    (exactly the same as mds call)
  276.     jmp    po
  277. ;
  278. reader:    ;reader character in to reg-a
  279. ;    (exactly the same as mds call)
  280.     jmp    ri
  281. ;
  282. home:    ;move to home position
  283. ;    treat as track 00 seek
  284.     mvi    c,0
  285.     jmp    settrk
  286. ;
  287. seldsk:    ;select disk given by register c
  288.     lxi    h,0000h    ;return 0000 if error
  289.     mov    a,c
  290.     cpi    ndisks    ;too large?
  291.     rnc        ;leave HL = 0000
  292. ;
  293.     ani    10b    ;00 00 for drive 0,1 and 10 10 for drive 2,3
  294.     sta    dbank    ;to select drive bank
  295.     mov    a,c    ;00, 01, 10, 11
  296.     ani    1b    ;mds has 0,1 at 78, 2,3 at 88
  297.     ora    a    ;result 00?
  298.     jz    setdrive
  299.     mvi    a,00110000b    ;selects drive 1 in bank
  300. setdrive:
  301.     mov    b,a    ;save the function
  302.     lxi    h,iof    ;io function
  303.     mov    a,m
  304.     ani    11001111b    ;mask out disk number
  305.     ora    b    ;mask in new disk number
  306.     mov    m,a    ;save it in iopb
  307.     mov    l,c
  308.     mvi    h,0    ;HL=disk number
  309.     dad    h    ;*2
  310.     dad    h    ;*4
  311.     dad    h    ;*8
  312.     dad    h    ;*16
  313.     lxi    d,dpbase
  314.     dad    d    ;HL=disk header table address
  315.     ret
  316. ;
  317. ;
  318. settrk:    ;set track address given by c
  319.     lxi    h,iot
  320.     mov    m,c
  321.     ret
  322. ;
  323. setsec:    ;set sector number given by c
  324.     lxi    h,ios
  325.     mov    m,c
  326.     ret
  327. sectran:
  328.         ;translate sector bc using table at de
  329.     mvi    b,0    ;double precision sector number in BC
  330.     xchg        ;translate table address to HL
  331.     dad    b    ;translate(sector) address
  332.     mov    a,m    ;translated sector number to A
  333.     sta    ios
  334.     mov    l,a    ;return sector number in L
  335.     ret
  336. ;
  337. setdma:    ;set dma address given by regs b,c
  338.     mov    l,c
  339.     mov    h,b
  340.     shld    iod
  341.     ret
  342. ;
  343. read:    ;read next disk record (assuming disk/trk/sec/dma set)
  344.     mvi    c,readf    ;set to read function
  345.     call    setfunc
  346.     call    waitio    ;perform read function
  347.     ret        ;may have error set in reg-a
  348. ;
  349. ;
  350. write:    ;disk write function
  351.     mvi    c,writf
  352.     call    setfunc    ;set to write function
  353.     call    waitio
  354.     ret        ;may have error set
  355. ;
  356. ;
  357. ;    utility subroutines
  358. prmsg:    ;print message at h,l to 0
  359.     mov    a,m
  360.     ora    a    ;zero?
  361.     rz
  362. ;    more to print
  363.     push    h
  364.     mov    c,a
  365.     call    conout
  366.     pop    h
  367.     inx    h
  368.     jmp    prmsg
  369. ;
  370. setfunc:
  371. ;    set function for next i/o (command in reg-c)
  372.     lxi    h,iof    ;io function address
  373.     mov    a,m    ;get it to accumulator for masking
  374.     ani    11111000b    ;remove previous command
  375.     ora    c    ;set to new command
  376.     mov    m,a    ;replaced in iopb
  377. ;    the mds-800 controller requires disk bank bit in sector byte
  378. ;    mask the bit from the current i/o function
  379.     ani    00100000b    ;mask the disk select bit
  380.     lxi    h,ios        ;address the sector select byte
  381.     ora    m        ;select proper disk bank
  382.     mov    m,a        ;set disk select bit on/off
  383.     ret
  384. ;
  385. waitio:
  386.     mvi    c,retry    ;max retries before perm error
  387. rewait:
  388. ;    start the i/o function and wait for completion
  389.     call    intype    ;in rtype
  390.     call    inbyte    ;clears the controller
  391. ;
  392.     lda    dbank        ;set bank flags
  393.     ora    a        ;zero if drive 0,1 and nz if 2,3
  394.     mvi    a,iopb and 0ffh    ;low address for iopb
  395.     mvi    b,iopb shr 8    ;high address for iopb
  396.     jnz    iodr1    ;drive bank 1?
  397.     out    ilow        ;low address to controller
  398.     mov    a,b
  399.     out    ihigh    ;high address
  400.     jmp    wait0        ;to wait for complete
  401. ;
  402. iodr1:    ;drive bank 1
  403.     out    ilow+10h    ;88 for drive bank 10
  404.     mov    a,b
  405.     out    ihigh+10h
  406. ;
  407. wait0:    call    instat        ;wait for completion
  408.     ani    iordy        ;ready?
  409.     jz    wait0
  410. ;
  411. ;    check io completion ok
  412.     call    intype        ;must be io complete (00) unlinked
  413. ;    00 unlinked i/o complete,    01 linked i/o complete (not used)
  414. ;    10 disk status changed       11 (not used)
  415.     cpi    10b        ;ready status change?
  416.     jz    wready
  417. ;
  418. ;    must be 00 in the accumulator
  419.     ora    a
  420.     jnz    werror        ;some other condition, retry
  421. ;
  422. ;    check i/o error bits
  423.     call    inbyte
  424.     ral
  425.     jc    wready        ;unit not ready
  426.     rar
  427.     ani    11111110b    ;any other errors?  (deleted data ok)
  428.     jnz    werror
  429. ;
  430. ;    read or write is ok, accumulator contains zero
  431.     ret
  432. ;
  433. wready:    ;not ready, treat as error for now
  434.     call    inbyte        ;clear result byte
  435.     jmp    trycount
  436. ;
  437. werror:    ;return hardware malfunction (crc, track, seek, etc.)
  438. ;    the mds controller has returned a bit in each position
  439. ;    of the accumulator, corresponding to the conditions:
  440. ;    0    - deleted data (accepted as ok above)
  441. ;    1    - crc error
  442. ;    2    - seek error
  443. ;    3    - address error (hardware malfunction)
  444. ;    4    - data over/under flow (hardware malfunction)
  445. ;    5    - write protect (treated as not ready)
  446. ;    6    - write error (hardware malfunction)
  447. ;    7    - not ready
  448. ;    (accumulator bits are numbered 7 6 5 4 3 2 1 0)
  449. ;
  450. ;    it may be useful to filter out the various conditions,
  451. ;    but we will get a permanent error message if it is not
  452. ;    recoverable.  in any case, the not ready condition is
  453. ;    treated as a separate condition for later improvement
  454. trycount:
  455. ;    register c contains retry count, decrement 'til zero
  456.     dcr    c
  457.     jnz    rewait    ;for another try
  458. ;
  459. ;    cannot recover from error
  460.     mvi    a,1    ;error code
  461.     ret
  462. ;
  463. ;    intype, inbyte, instat read drive bank 00 or 10
  464. intype:    lda    dbank
  465.     ora    a
  466.     jnz    intyp1    ;skip to bank 10
  467.     in    rtype
  468.     ret
  469. intyp1:    in    rtype+10h    ;78 for 0,1  88 for 2,3
  470.     ret
  471. ;
  472. inbyte:    lda    dbank
  473.     ora    a
  474.     jnz    inbyt1
  475.     in    rbyte
  476.     ret
  477. inbyt1:    in    rbyte+10h
  478.     ret
  479. ;
  480. instat:    lda    dbank
  481.     ora    a
  482.     jnz    insta1
  483.     in    dstat
  484.     ret
  485. insta1:    in    dstat+10h
  486.     ret
  487. ;
  488. ;
  489. ;
  490. ;    data areas (must be in ram)
  491. dbank:    db    0    ;disk bank 00 if drive 0,1
  492.             ;       10 if drive 2,3
  493. iopb:    ;io parameter block
  494.     db    80h    ;normal i/o operation
  495. iof:    db    readf    ;io function, initial read
  496. ion:    db    1    ;number of sectors to read
  497. iot:    db    offset    ;track number
  498. ios:    db    1    ;sector number
  499. iod:    dw    buff    ;io address
  500. ;
  501. ;
  502. ;    define ram areas for bdos operation
  503.     endef
  504.     end
  505.