home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR2 / DIGIPROG.ZIP / 64KTO8K.DOC next >
Text File  |  1993-12-13  |  6KB  |  203 lines

  1.  
  2.  
  3.  
  4.  This document is designed to assist Digiboard customers in converting
  5.  custom device drivers from the PC/8e with a fixed memory window to the
  6.  newer version with a memory window interface.
  7.  
  8.  The procedures for loading the BIOS and FEP are discussed along with how
  9.  to access channel buffers. Not all cases where a driver has to access 
  10.  memory are discussed, but it is hoped that these examples will illustrate
  11.  how to interface to the Digiboard with a memory window interface.
  12.  
  13.  In the discussion to follow the following notation will be used:
  14.  
  15.     devb[i]    The ith byte of board I/O space
  16.     memb[i]    The 8-bit byte of board memory at board relative address i
  17.                as viewed by the host.
  18.     memw[i]    The 16-bit word of board memory at board relative address i
  19.                as viewed by the host.
  20.  
  21.  
  22.  In fixed memory window products memory was enabled by placing 0x02 in the
  23.  io port base register.
  24.  
  25.          devb[0] = 0x02 ;
  26.  
  27.  Memory window products enable a single page of memory by selecting the
  28.  memory page in the lower bits of the second io port and a 1 in the upper most
  29.  bit to enable memory.
  30.  
  31.          devb[1] = 0x80 ;        enables window zero
  32.  
  33.          devb[1] = 0x87 ;        enables window seven
  34.  
  35.  
  36.  Loading the BIOS
  37.  
  38.  The BIOS is loaded into the upper region of memory(specifically at 
  39. 0xff800).
  40.  
  41.  For the old board this is done with the following code:
  42.  
  43.          devb[0] = 0x06 ;                /* hold reset and enable memory */
  44.  
  45.          mem_ptr = board_addr+(0xff800-membase);
  46.  
  47.          for(i = 0; i < n; i++)
  48.          {
  49.                  *mem_ptr++ = bios[i];
  50.          }
  51.  
  52.          board_addr + 0xC00 = 0;         /* clear bios start flag */
  53.  
  54.          devb[0] = 0x02 ;                /* release reset to start BIOS */
  55.  
  56.  
  57.  Where:
  58.          board_addr is the base address of the board as seen by the host
  59.          mem_ptr is a pointer to board memory
  60.          membase is the base address of dual ported memory. (0xf0000 for 
  61. 64K)
  62.          bios[] is a char array containing the BIOS code.
  63.  
  64.  
  65.  For the new board this is done with the following code:
  66.  
  67.          devb[0] = 0x04 ;                /* board held in reset */
  68.          devb[1] = 0x87 ;                /* Select page 7 and enable memory
  69. */
  70.  
  71.          mem_ptr = board_addr + 0x1800 ;
  72.  
  73.          for(i = 0; i != n; i++)
  74.          {
  75.              *mem_ptr++ = bios[i];
  76.          }
  77.  
  78.          devb[1] = 0x80 ;                /* point to window 0 for global
  79. data */
  80.  
  81.          board_addr + 0xC00 = 0 ;        /* clear bios start flag */
  82.  
  83.          devb[0] = 0x00 ;                /* release reset to start bios */
  84.  
  85.  
  86.  
  87.  Loading the FEP
  88.  
  89.  The FEP code is loaded at location 0x2000 as seen by the PC/Xe
  90.  
  91.  
  92.  For the old board this is done as follows:
  93.  
  94.          mem_ptr = board_addr + 0x2000 ;
  95.  
  96.          for(i = 0; i < n; i++)
  97.          {
  98.              *mem_ptr++ = fep[i];
  99.          }
  100.  
  101.          board_addr + 0xc40 = 02 ;       /* Command */
  102.          board_addr + 0xc42 = 0x200 ;    /* From */
  103.          board_addr + 0xc44 = 0 ;
  104.          board_addr + 0xc46 = 0x200 ;    /* To */
  105.          board_addr + 0xc48 = 0;
  106.          board_addr + 0xc4a = 0x2000 ;   /* FEP/OS size */
  107.  
  108.          devb[0] = 0x0a ;                /* Interrupt to BIOS */
  109.          devb[0] = 0x02 ;
  110.  
  111.  Where:
  112.          fep[] is a char array containing the FEP code.
  113.  
  114.  
  115.  For the new board the procedure is as follows:
  116.  
  117.          devb[1] = 0x81 ;                /* point at window 1 */
  118.  
  119.          mem_ptr = board_addr ;
  120.  
  121.          for( i = 0; i != n; i++)
  122.          {
  123.              *fep_ptr++ = fep[i] ;
  124.          }
  125.  
  126.          devb[1] = 0x80 ;                /* point at window 0 */
  127.  
  128.          board_addr + 0xc40 = 02 ;       /* Command */
  129.          board_addr + 0xc42 = 0x200 ;    /* From */
  130.          board_addr + 0xc44 = 0 ;
  131.          board_addr + 0xc46 = 0x200 ;    /* To */
  132.          board_addr + 0xc48 = 0;
  133.          board_addr + 0xc4a = 0x2000 ;   /* FEP/OS size */
  134.  
  135.          devb[0] = 0x08 ;                /* Interrupt to BIOS */
  136.          devb[0] = 0x00 ;
  137.  
  138.  
  139.  
  140.  Accessing Channel Buffers:
  141.  
  142.  When using the old board, the method to access a channel receive buffer
  143.  is as follows:
  144.  
  145.          /* get board address from channel structure receive segment */
  146.  
  147.          chan_rcv = board_addr + (chan_ptr->rseg - base_seg) << 4 ;
  148.  
  149.          /* get character from head of buffer */
  150.  
  151.          while (chan_ptr->rout != chan_ptr->rin)
  152.          {
  153.              rcv_char = chan_rcv + chan_ptr->rout ;
  154.              chan_ptr->rout = (chan_ptr->rout + 1) & chan_ptr->rmax ;
  155.          }
  156.  
  157.  
  158.  
  159.  Where:
  160.          chan_rcv is the start of the channel receive buffer.
  161.          chan_ptr is a pointer to the channel structure.
  162.          base_seg is the memory segment for the base of dual ported
  163.              memory as seen by teh PC/Xe.
  164.  
  165.  
  166.  The procedure for the new board is as follows:
  167.  
  168.          /* enable window 0 */
  169.          devb[1] = 0x80 ;
  170.  
  171.          rin_sav = chan_ptr->rin ;
  172.          rout_sav = chan_ptr->rout ;
  173.          rmax_sav = chan_ptr->rmax ;
  174.          reg_sav = chan_ptr->rseg ;
  175.  
  176.          while(rin_sav != rout_sav)
  177.          {
  178.              /* calcluate offet of data from window base */
  179.              win_offset=((rseg_sav <<4) & 0x7fff) + rout_sav ;
  180.  
  181.              /* select correct window */
  182.              devb[1] = 0x80 | (rseg_sav >>11)) ;
  183.  
  184.              /* read in character */
  185.              rcv_char = board_addr + win_offset ;
  186.  
  187.              /* update local copy of buffer pointer */
  188.              rout_sav = (rout_sav + 1) & rmax_sav ;
  189.          }
  190.          /* reselect base window */
  191.          devb[1] = 0x80 ;
  192.          chan_ptr->rout = rout_sav ; /* update out pointer */
  193.  
  194.  Where:
  195.  
  196.          rin_sav is a local copy of the receive input pointer
  197.          rout_sav is a local copy of the receive output pointer
  198.          rmax_sav is a local copy of the buffer size mask
  199.          rseg_sav is a local copy of the buffer segment as seen by the 
  200. PC/Xe
  201.          win_offset is the offset into the current window in bytes
  202.  
  203.