home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / S / UZI.ARK / DEVWD.C < prev    next >
Text File  |  1988-11-30  |  7KB  |  331 lines

  1. /**************************************************
  2. UZI (Unix Z80 Implementation) Kernel:  devwd.c
  3. ***************************************************/
  4.  
  5.  
  6. #include "unix.h"
  7. #include "extern.h"
  8.  
  9. #define LUN 1
  10. #define RDCMD 0x28
  11. #define WRCMD 0x2a
  12.  
  13. static char cmdblk[10] = { 0, LUN<<5, 0, 0, 0, 0, 0, 0, 0, 0 }; 
  14.  
  15. extern char *dptr;
  16. extern int dlen;
  17. extern char *cptr;
  18. extern int busid;
  19. extern scsiop();
  20.  
  21. wd_read(minor, rawflag)
  22. unsigned minor;
  23. int rawflag;
  24. {
  25.     cmdblk[0] = RDCMD;
  26.     if (setup(minor, rawflag))
  27.         return(0);
  28.  
  29.     chkstat(scsiop(),1);
  30.  
  31.     return(cmdblk[8] << 9);
  32. }
  33.  
  34. wd_write(minor, rawflag)
  35. unsigned minor;
  36. int rawflag;
  37. {
  38.     cmdblk[0] = WRCMD;
  39.     if (setup(minor, rawflag))
  40.         return(0);
  41.  
  42.     chkstat(scsiop(),0);
  43.     return(cmdblk[8] << 9);
  44. }
  45.  
  46.  
  47. static
  48. setup(minor, rawflag)
  49. unsigned minor;
  50. int rawflag;
  51. {
  52.     register blkno_t block;
  53.  
  54.     cptr = cmdblk;
  55.     busid = 1;
  56.  
  57.     if (rawflag)
  58.     {
  59.         if (rawflag == 2)
  60.         {
  61.             cmdblk[8] = swapcnt >> 9;
  62.             dlen = swapcnt;
  63.             dptr = swapbase;
  64.             block = swapblk;
  65.         }
  66.         else
  67.         {
  68.             cmdblk[8] = udata.u_count >> 9;
  69.             dlen = udata.u_count;
  70.             dptr = udata.u_base;
  71.             block = udata.u_offset.o_blkno;
  72.         }       
  73.     }
  74.     else
  75.     {
  76.         cmdblk[8] = 1;
  77.         dlen = 512;
  78.         dptr = udata.u_buf->bf_data;
  79.         block = udata.u_buf->bf_blk;
  80.     }
  81.  
  82.     block += (minor & 0xff00);
  83.     if (block > (minor << 9))
  84.     {
  85.         if (cmdblk[0] == WRCMD)
  86.             udata.u_error = ENXIO;
  87.         return (1);
  88.     }
  89.  
  90.     cmdblk[5] = block;
  91.     cmdblk[4] = block >> 8;
  92.     return(0);
  93. }
  94.  
  95.  
  96. static
  97. chkstat(stat, rdflag)
  98. int stat;
  99. int rdflag;
  100. {
  101.     if (stat)
  102.     {
  103.         kprintf("wd %s failure stat %x", rdflag ? "read": "write", stat);
  104.         panic("");
  105.     }
  106. }
  107.  
  108.  
  109. wd_open(minor)
  110. int minor;
  111. {
  112.     return(0);
  113. }
  114.  
  115.  
  116. /* The following is generic SCSI driver code, also used by devmt.c */
  117.  
  118. char *dptr;
  119. int dlen;
  120. char *cptr;
  121. int busid;
  122.  
  123. scsiop()
  124. {
  125.  
  126. #asm 8080
  127. ;
  128. ;
  129. OUTIR   MACRO
  130. DB      0EDH
  131. DB      0B3H
  132. ENDM
  133. ;
  134. OUTI    MACRO
  135. DB      0EDH
  136. DB      0A3H
  137. ENDM
  138. ;
  139. SDATA   EQU     0D8H
  140. SCMD    EQU     0D9H
  141. ;
  142. DMAPORT EQU 78H
  143. ;
  144. ;ENTRY POINT:
  145. ;
  146.         PUSH    B
  147. ;
  148. LOOP1:  CALL    SWAIT
  149.         JZ      HUNG    ;ABORT IF PENDING TRANSACTION
  150.  
  151.         LDA     busid?  ;OUTPUT SCSI BUS ADDRESS
  152.         OUT     SDATA
  153.         MVI     A,1     ;SELECT CONTROLLER
  154.         OUT     SCMD    ;ASSERT SELECT
  155. ..A2:   IN      SCMD    ;WAIT FOR BSY TO BE ASSERTED
  156.         ANI     01
  157.         JNZ     ..A2
  158.         XRA     A
  159.         OUT     SCMD    ;DEASSERT IT
  160. ;
  161.         LHLD    cptr?
  162. .LOOP2: CALL    SWAIT   ;WAIT FOR REQ
  163.         JNZ     LOST
  164.         IN      SCMD
  165.         ANI     1FH
  166.         CPI     01100B  ;CONTINUE AS LONG AS IT WANTS COMMANDS
  167.         JNZ     ECMD
  168.         ANI     00100B
  169.         JZ      SEQ     ;ABORT IF IT HAS A MESSAGE
  170.         MOV     A,M             ;TRANSMIT COMMAND
  171.         OUT     SDATA
  172.         INX     H
  173.         JMP     .LOOP2
  174. ;       
  175. ECMD:   LHLD    dlen?
  176.         MOV     A,H
  177.         ORA     L
  178.         JZ      EDATA   ;SKIP DATA I/O IF NECESSARY
  179.         CALL    SWAIT   
  180.         JNZ     LOST
  181.         IN      SCMD    ;SEE IF IT REALLY WANTS DATA
  182.         ANI     10H
  183.         JZ      EDATA
  184.         IN      SCMD
  185.         ANI     08H     ;CHECK FOR DATA READ OR WRITE
  186.         JNZ     WIO
  187.         
  188.         ; FILL IN THE DMA PROGRAM WITH THE CORRECT ADDRESS AND LENGTH
  189.         LHLD    dptr?
  190.         SHLD    RDADR
  191.         LHLD    dlen?
  192.         DCX     H
  193.         SHLD    RDCNT
  194. ;
  195.         LXI     H,RDBLK
  196.         MVI     B,RDLEN
  197.         MVI     C,DMAPORT
  198.         OUTIR           ;SEND PROGRAM TO DMA CONTROLLER
  199.         JMP     EDATA
  200. ;
  201. WIO:
  202.         LHLD    dptr?
  203.         SHLD    WRADR
  204.         LHLD    dlen?
  205.         DCX     H
  206.         SHLD    WRCNT
  207. ;
  208.         LXI     H,WRBLK
  209.         MVI     B,WRLEN
  210.         MVI     C,DMAPORT
  211.         OUTIR           ;SEND PROGRAM TO DMA CONTROLLER
  212.  
  213. ;
  214. EDATA:
  215.         CALL    SWAIT   ;WAIT UNTIL THE CONTROLLER WANTS TO SEND NON-DATA
  216.         JNZ     LOST
  217.         IN      SCMD
  218.         ANI     10H
  219.         JNZ     EDATA
  220. ;
  221. ;GET STATUS AND SHUT DOWN
  222. ;
  223.         MVI     A,0A3H
  224.         OUT     DMAPORT ;TURN OFF DMA CONTROLLER
  225.  
  226.         IN      SCMD
  227.         ANI     1FH
  228.         CPI     00100B
  229.         JNZ     SEQ     ;JUMP IF IT DOESN'T WANT TO SEND STATUS
  230. ;
  231.         IN      SDATA
  232.         MOV     L,A
  233.         MVI     H,0
  234.         CALL    SWAIT
  235.         JNZ     LOST
  236.         IN      SCMD
  237.         ANI     1FH
  238.         CPI     00000B
  239.         JNZ     SEQ
  240.         IN      SDATA   ;READ FINAL MESSAGE BYTE
  241. ;
  242. DONE:   POP     B
  243.         MOV     A,H
  244.         ORA     L
  245.         RET
  246. ;
  247. ;
  248. LOST:   LXI     H,-1
  249.         JMP     DONE
  250. ;
  251. SEQ:    CALL    SWAIT
  252.         LXI     H,-2
  253.         JNZ     DONE
  254.         IN      SDATA   ;EAT EXTRA DATA
  255.         JMP     SEQ
  256. ;
  257. HUNG:
  258.         CALL    WRESET
  259.         LXI     H,-3
  260.         JMP     DONE
  261. ;
  262. ; THIS WAITS FOR REQ TO BE ASSERTED OR FOR THE CONNECTION TO BE LOST.
  263. ;A NON-ZERO RETURN MEANS CONNECTION WAS LOST
  264. ;
  265. SWAIT:
  266.         IN      SCMD
  267.         ANI     01
  268.         RNZ             ;RETURN IF NOT EVEN BUSY
  269.         IN      SCMD
  270.         ANI     22H     ;MASK OUT REQ AND MAKE SURE ACK FROM LAST CYCLE IS GONE
  271.         JNZ     SWAIT
  272.         RET
  273. ;
  274. WRESET:
  275.         MVI     A,2
  276.         OUT     SCMD
  277.         XTHL
  278.         XTHL
  279.         XTHL
  280.         XTHL
  281.         XRA     A
  282.         OUT     SCMD
  283.         RET
  284. ;       
  285. ;
  286. ; THESE ARE THE DMA PROGRAMS FOR READ/WRITE
  287. ;
  288. RDBLK:  ;PORT A IS THE CONTROLLER, PORT B IS THE MEMORY
  289.  
  290.         DB      0A3H    ;RESET DMA
  291.         DB      01101101B       ;WR0
  292.         DB      SDATA
  293. RDCNT:  DS      2
  294.         DB      01101100B       ;WR1 
  295.         DB      11001100B       ;PORT A CYCLE LENGTH = 4
  296.         DB      01010000B       ;WR2
  297.         DB      11001101B       ;PORT B CYCLE LENGTH = 3
  298.         DB      11001101B       ;WR4  BURST MODE
  299. RDADR:  DS      2
  300.         DB      10001010B       ;WR5  READY ACTIVE HIGH
  301.         DB      0CFH    ;WR6 LOAD COMMAND
  302.         DB      87H     ;WR6 GO COMMAND
  303.  
  304. RDLEN   EQU $ - RDBLK
  305. ;
  306. ;
  307. WRBLK:
  308.  
  309.         DB      0A3H    ;RESET DMA
  310.         DB      01101101B       ;WR0
  311.         DB      SDATA
  312. WRCNT:  DS      2
  313.         DB      01101100B       ;WR1 
  314.         DB      11001101B       ;PORT A CYCLE LENGTH = 3 (FOR CONTROLLER)
  315.         DB      01010000B       ;WR2
  316.         DB      11001101B       ;PORT B CYCLE LENGTH = 3
  317.         DB      11001101B       ;WR4  BURST MODE
  318. WRADR:  DS      2
  319.         DB      10001010B       ;WR5  READY ACTIVE HIGH
  320.         DB      0CFH    ;WR6 LOAD COMMAND
  321.         DB      00000001B       ;WR0   (ONLY DIFFERENCE)
  322.         DB      0CFH    ;WR6 LOAD COMMAND
  323.         DB      87H     ;WR6 GO COMMAND
  324.  
  325. WRLEN   EQU $ - WRBLK
  326.  
  327. #endasm
  328.         
  329. }
  330.  
  331.