home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Emulators / Ersatz-2.0 / hd.mac < prev    next >
Encoding:
Text File  |  1998-10-30  |  9.9 KB  |  331 lines

  1.     .mcall    .modul
  2. .modul    hd,versio=1,commen=<Russian Hypothetical Disk Handler>,audit=yes
  3. ;++
  4. ;
  5. ; Ersatz-11 Hypothetical Disk device handler for RT-11 V5.X.
  6. ;
  7. ; The HD: device in Ersatz-11 is included for compatibility with boot images
  8. ; intended for the Russian PDP-11/03 emulator (I would credit the author but
  9. ; the read-me file seems to be in Russian, and is mostly non-ASCII).  I have
  10. ; extended the device to include interrupts and 18-bit addressing (for all I
  11. ; know the HD_SYS.EXE driver does this too, but if so they aren't used by the
  12. ; HD.SYS driver supplied with the emulator which is what I looked at).
  13. ;
  14. ; For the record, this driver is nothing to do with the code in the Russian
  15. ; HD.SYS handler (it actually looks more like the RK.SYS code since that's
  16. ; beautifully documented as an example handler in the V4 Software Support
  17. ; Manual).  Also, it uses the interrupts, and 18-bit addressing (when
  18. ; assembled with MMG$T set), and is thus incompatible with the Russian
  19. ; PDP-11/03 emulator.  However a new driver was necessary to support floppies
  20. ; (w/o stalling the system), and to work with XM.  This driver is intended to
  21. ; be used as a stopgap until MSCP emulation is added to Ersatz-11, to handle
  22. ; devices of arbitrary sizes.
  23. ;
  24. ; This driver is for RT-11 V5.X, but was written using the V4.X SSM, so there
  25. ; are a few things that RK.MAC has that I don't know what they're for.  I may
  26. ; get around to adding V4.X conditionals, although things would be a little
  27. ; ugly under V4.X since it didn't have the VARSZ$ bit, so presumably you have
  28. ; to patch DUP to make INIT bother to ask the driver for the size (with
  29. ; special function #373).
  30. ;
  31. ; By John Wilson.
  32. ;
  33. ; 16-Mar-1995    JMBW    Created.
  34. ; 31-Oct-1998    JMBW    Reduced unit number mask to 3 bits for TSX.
  35. ;
  36. ;--
  37.     .mcall    .drdef,.assume
  38. ;
  39. .readw=    emt!375
  40. .writw=    emt!375
  41. ;
  42. .if eq mmg$t
  43.     .drdef    hd,377,filst$!spfun$!varsz$,128.,177110,234,dma=no
  44. .iff
  45.     .drdef    hd,377,filst$!spfun$!varsz$,128.,177110,234,dma=yes
  46. .endc
  47. ;
  48. ; These are new since V4, no idea what they are:
  49.     .drptr
  50.     .drest    class=dvc.dk
  51. ;
  52. ; Device registers:
  53. ;
  54. hdcs=    hd$csr            ;777110 control/status register
  55. hdbc=    hdcs+2            ;777112 byte count register
  56. hdblk=    hdcs+4            ;777114 starting block register
  57. hdba=    hdcs+6            ;777116 bus address register
  58. hdatn=    hdcs+10            ;777120 drive attn register (disk change)
  59. hdst=    hdcs+12            ;777122 ctrlr error/drive status register
  60. hdblke=    hdcs+14            ;777124 starting block register extension
  61. hdbae=    hdcs+16            ;777126 bus address extension
  62. ;
  63. hdcnt=    8.            ;number of error retries
  64. hdnreg=    8.            ;number of regs to read for error log
  65. ;
  66. ; Bits in HDCS:
  67. ;
  68. cserr=    100000            ;error
  69. csunit=    17000            ;unit
  70. csrdy=    200            ;ready
  71. csie=    100            ;interrupt enable (not on original HD_SYS.EXE)
  72. csbae=    60            ;bus address extension (" " " ")
  73. csfun=    16            ;function code
  74. csgo=    1            ;go bit
  75. ;
  76. ; Function codes in CSFUN:
  77. ;
  78. fnack=    0*2            ;medium acknowledge
  79. fnread=    1*2            ;read block(s)
  80. fnwrit=    2*2            ;write block(s)
  81. fngtsz=    3*2            ;get volume size
  82. ;
  83.     .SBTTL    installation code
  84. ;
  85. ; This is new since V4...
  86. ;
  87.     .drins    hd        ;used to just be .=200
  88.     nop            ;same for system and non-system handler
  89.     nop            ;RK.SYS had this NOP too
  90.     clc            ;what, me worry?
  91.     rts    pc
  92. ;
  93.     .sbttl    SET options
  94. ;
  95.     .drset    csr,160000,o.csr,oct
  96.     .drset    vector,500,o.vec,oct
  97.     .drset    retry,127.,o.rtry,num
  98. .iif ne erl$g, .drset succes,-1,o.succ,no
  99. ;
  100. btcsr=    <hdend-hdstrt>+<botcsr-hdboot>+1000 ;loc in HD.SYS of BOTCSR
  101. o.csr:    ; SET HD: CSR=oooooo
  102.     cmp    r0,r3        ;in I/O page?
  103.     blo    o.bad        ;no, invalid
  104.     mov    r0,inscsr    ;save
  105.     mov    r0,discsr
  106.     mov    pc,r1        ;point at BAREA+4 with r1
  107.     add    #barea-.+4,r1
  108.     mov    pc,r2        ;and .+2+1000 with r2
  109.     add    #1000-.,r2
  110.     mov    r2,(r1)        ;fill in BUF field
  111.     mov    #btcsr/1000,-(r1) ;block containing BOTCSR
  112.     tst    -(r1)        ;skip function,,channel
  113.     mov    r0,r3        ;save their value
  114.     mov    r1,r0        ;point with R0
  115.     .readw            ;read the block
  116.     bcs    o.bad        ;failed
  117.     mov    r3,<btcsr&777>(r2) ;fill in CSR addr in boot driver
  118.     mov    r1,r0        ;point at EMT area again
  119.     incb    1(r0)        ;change function to .WRITW
  120.     .writw            ;write it back
  121.     bcs    o.bad        ;it's not our day
  122.     mov    r1,r0        ;point yet again
  123.     decb    1(r0)        ;back to .READW again
  124.     mov    #1,2(r0)    ;change to block 1
  125.     .readw            ;restore
  126.     bcs    o.bad
  127.     mov    r3,hdcsr    ;finally save it
  128. o.good:    tst    (pc)+        ;skip the SEC, C=0
  129. o.bad:    sec            ;unhappy
  130.     rts    pc
  131. o.vec:    ; SET HD: VECTOR=ooo
  132.     cmp    r0,r3        ;<=500 right?
  133.     bhis    o.bad        ;no, idiot
  134.     bit    #3,r0        ;mult of 4 right?
  135.     bne    o.bad        ;doofus
  136.     mov    r0,hdstrt    ;groovy, save it
  137.     br    o.good
  138. o.rtry:    ; SET HD: RETRY=ddd
  139.     cmp    r0,r3        ;in range?
  140.     bhi    o.bad        ;no
  141.     mov    r0,dretry    ;save it
  142.     bne    o.good        ;it's non-zero right?
  143.     br    o.bad        ;whoops
  144. .if ne erl$g
  145. o.succ:    ; SET HD: [NO]SUCCES
  146.     mov    #0,r3        ;set or clear
  147.     mov    r3,scsflg    ;save flag
  148.     br    o.good        ;can't screw this up
  149. .endc
  150. ;
  151. barea:    .byte    17,10        ;.READW, channel 17
  152.     .blkw            ;block #
  153.     .blkw            ;buf addr
  154.     .word    256.        ;the whole block
  155.     .word    0        ;no crtn
  156. .assume . le 1000,<;SET area overflow>
  157. ;
  158.     .sbttl    driver entry
  159. ;
  160.     .drbeg    hd
  161.     mov    (pc)+,(pc)+    ;init retry counter
  162. dretry:     .word    hdcnt
  163. .assume . le hdstrt+1000,<;SET object not in block 1>
  164. retry:     .word            ;retry count
  165. ; we won't bother to pre-compute the disk location for retries because there's
  166. ; no calculation to do.
  167. again:    mov    hdcqe,r5    ;get curr queue entry
  168.     mov    q$unit-1(r5),r3    ;unit # in MSB
  169.     bic    #^C<7*400>,r3    ;isolate 3-bit unit number in MSB
  170.     asl    r3        ;should start at bit 9
  171.     bis    #csie!fnread!csgo,r3 ;assume it's a read
  172.     mov    (pc)+,r4    ;pick up CSR addr
  173. hdcsr:     .word    hdcs
  174. .assume . le hdstrt+1000,<;SET object not in block 1>
  175.     mov    (r5),hdblk-hdcs(r4) ;set block number
  176.     clr    hdblke-hdcs(r4)    ;clear out block extension (32MB limit)
  177.     cmp    (r5)+,(r5)+    ;skip to Q.BUFF for $MPPHY
  178. .if ne mmg$t
  179.     ; XM, translate Q.BUFF virtual address into physical 18-bit address
  180.     call    @$mpptr        ;call $MPPHY
  181.     mov    (sp)+,hdba-hdcs(r4) ;get low 16 bits of real addr
  182.     bis    (sp)+,r3    ;OR high 2 bits into CSR value (bits 5:4)
  183. .iff    ; SJ or FB, addresses are all real and bits 17:16=00
  184.     mov    (r5)+,hdba-hdcs(r4) ;copy address
  185. .endc
  186.     movb    q$func-q$wcnt(r5),r2 ;get function code
  187.     bmi    20$        ;.SPFUN, skip
  188.     mov    (r5)+,r0    ;get word count
  189.     beq    30$        ;0, seek (no op with us)
  190.     bpl    10$        ;read, skip
  191.     neg    r0        ;take absolute value
  192.     add    #fnwrit-fnread,r3 ;change function code to write
  193. 10$:    asl    r0        ;WC*2=byte count
  194.     mov    r0,hdbc-hdcs(r4) ;write it out
  195.     mov    r3,(r4)        ;start transfer
  196.     rts    pc        ;back on interrupt
  197. 20$:    ; .SPFUN call
  198.     cmpb    r2,#373        ;cmd = get volume size?
  199.     bne    30$        ;skip if not
  200.     mov    #1,r0        ;word count=1 word
  201.     add    #fngtsz-fnread,r3 ;change function code to "get size"
  202.     br    10$        ;go do it
  203. 30$:    ; seek, no op
  204.     br    hdexit        ;there won't be any interrupt
  205. ;
  206. .if ne erl$g
  207. scsflg:    .word    0        ;success flag
  208. .assume . le hdstrt+1000,<;SET object not in block 1>
  209. .endc
  210. ;
  211.     .sbttl    interrupt entry point
  212. ;
  213.     .drast    hd,5        ;say hi to the scheduler, switch to prio 5
  214.     mov    hdcsr,r5    ;get CSR addr
  215.     tst    retry        ;are we in the middle of a retry?
  216.     bpl    normal        ;no
  217.     tst    (r5)        ;yes, did reset work?
  218.     bmi    normal        ;no, error
  219.     .fork    hdfblk        ;yes, drop to fork level for the retry
  220. hdretr:    clrb    retry+1        ;clear the "reset in progress" flag
  221.     br    again        ;retry the request
  222. ;
  223. normal:    tst    (r5)        ;any error?
  224.     bpl    done        ;no
  225.     .fork    hdfblk        ;drop to fork level to handle the error
  226. .if ne erl$g
  227.     mov    pc,r5        ;point at HDRBUF with r5
  228.     add    #hdrbuf-.,r5
  229.     mov    r5,r2        ;save a copy
  230.     mov    hdcsr,r3    ;get CSR
  231.     mov    #hdnreg,r4    ;# regs to read
  232. hdrreg:    mov    (r3)+,(r5)+    ;get a word
  233.     dec    r4        ;might as well be good and not use SOB
  234.     bne    rkrreg        ;in case emulating 11/04 etc.
  235.     mov    dretry,r3    ;get max # retry counts
  236.     swab    r3        ;in left half
  237.     add    #hdnreg,r3    ;# regs in right half
  238.     mov    hdcqe,r5    ;get curr queue element
  239.     movb    retry,r4    ;get actual # retries to go -1
  240.     dec    r4
  241.     call    @$elptr        ;log it
  242.     mov    hdcsr,r5    ;restore CSR ptr
  243. .endc
  244. hderr:    decb    retry        ;give up yet?
  245.     beq    herror        ;yep
  246.     bis    #100000,retry    ;set reset-in-progress bit
  247.     movb    #csie!fnack!csgo,(r5) ;reset drive (may not do anything)
  248.     rts    pc
  249. ;
  250. herror:    mov    hdcqe,r5    ;get qel
  251.     bis    #hderr$,@-(r5)    ;set hard error flag in CSW
  252.     ; log error if enabled
  253. .if ne erl$g
  254.     br    hdexit
  255. done:    .fork    hdfblk        ;continue at fork level
  256.     tst    scsflg
  257.     bne    hdexit
  258.     mov    (pc)+,r4    ;pick up our device code
  259.      .byte    377,hd$cod    ;(defined in .DRDEF at top)
  260.     mov    hdcqe,r5    ;get qel
  261.     call    @$elptr        ;log it
  262. .iff ; eq erl$g
  263. done:
  264. .endc
  265. hdexit:    clr    retry        ;not in error recovery
  266.     .drfin    hd        ;dive into RMON
  267. hdfblk:    .word    0,0,0,0        ;.FORK block used by error log code
  268. .if ne erl$g
  269. hdrbuf:    .blkw    hdnreg
  270. .endc
  271. ;
  272.     .sbttl    bootstrap driver
  273. ;+
  274. ;
  275. ; This stuff is scattered around the boot block.  For various reasons the boot
  276. ; code is entered by a NOP, two BRs and a JMP.  Once we get there we just load
  277. ; in the BSTRAP secondary loader using a simple polled I/O read routine, which
  278. ; BSTRAP then calls to look at the directory and load the monitor and the
  279. ; minimum device handlers (TT: and the system device).  Then it hooks up the
  280. ; real system device handler and we're on our way.
  281. ;
  282. ;-
  283.     .drbot    hd,boot1,read
  284. .=    hdboot+40
  285. boot1:    jmp    @#boot-hdboot    ;hop, skip, now jump, this is so dumb
  286. .=    hdboot+210
  287. ;+
  288. ;
  289. ; Bootstrap read routine.
  290. ;
  291. ; r0    starting block #
  292. ; r1    word count
  293. ; r2    bus address of buf
  294. ;
  295. ;-
  296. read:    mov    botcsr,r3    ;get CSR addr
  297.     mov    r0,hdblk-hdcs(r3) ;set block address
  298.     clr    hdblke-hdcs(r3)    ;(clear high word)
  299.     asl    r1        ;*2
  300.     mov    r1,hdbc-hdcs(r3) ;set byte count
  301.     mov    r2,hdba-hdcs(r3) ;set bus addr
  302.     movb    #fnread!csgo,(r3) ;read data, leave unit bits alone
  303. 10$:    tstb    (r3)        ;done?
  304.     bpl    10$        ;spin until so
  305.     tst    (r3)        ;error?  (C=0)
  306.     bmi    20$
  307.     rts    pc
  308. 20$:    jmp    bioerr        ;our READ routine is too short!  can't reach
  309. ;
  310. .=    hdboot+574
  311. boot:    ; load secondary bootstrap from blocks 2-5 of the volume, at 001000
  312.     mov    #10000,sp    ;set up stack
  313.     mov    @(pc)+,-(sp)    ;get boot unit # from CSR
  314. botcsr:     .word    hdcs        ;preassembled CSR addr
  315.     asr    (sp)        ;right a bit
  316.     swab    (sp)        ;right 8 more bits
  317.     bic    #^C<csunit/1000>,(sp) ;isolate unit #
  318.     mov    #2,r0        ;BSTRAP starts at block 2
  319.     mov    #<4*400>,r1    ;4 blocks
  320.     mov    #1000,r2    ;load at 001000
  321.     call    read        ;go do it (N.B. relative addressing)
  322.     ; set up BSTRAP entry conditions
  323.     mov    #read-hdboot,@#b$read ;set pointer to standalone read routine
  324.     mov    #b$dnam,@#b$devn ;set system device name
  325.     mov    (sp)+,@#b$devu    ;set boot unit number
  326.     jmp    @#b$boot    ;go for it
  327. ;
  328.     .drend    hd        ;that's it, give us BIOERR
  329. ;
  330.     .end
  331.