home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR2
/
DIGIPROG.ZIP
/
64KTO8K.DOC
next >
Wrap
Text File
|
1993-12-13
|
6KB
|
203 lines
This document is designed to assist Digiboard customers in converting
custom device drivers from the PC/8e with a fixed memory window to the
newer version with a memory window interface.
The procedures for loading the BIOS and FEP are discussed along with how
to access channel buffers. Not all cases where a driver has to access
memory are discussed, but it is hoped that these examples will illustrate
how to interface to the Digiboard with a memory window interface.
In the discussion to follow the following notation will be used:
devb[i] The ith byte of board I/O space
memb[i] The 8-bit byte of board memory at board relative address i
as viewed by the host.
memw[i] The 16-bit word of board memory at board relative address i
as viewed by the host.
In fixed memory window products memory was enabled by placing 0x02 in the
io port base register.
devb[0] = 0x02 ;
Memory window products enable a single page of memory by selecting the
memory page in the lower bits of the second io port and a 1 in the upper most
bit to enable memory.
devb[1] = 0x80 ; enables window zero
devb[1] = 0x87 ; enables window seven
Loading the BIOS
The BIOS is loaded into the upper region of memory(specifically at
0xff800).
For the old board this is done with the following code:
devb[0] = 0x06 ; /* hold reset and enable memory */
mem_ptr = board_addr+(0xff800-membase);
for(i = 0; i < n; i++)
{
*mem_ptr++ = bios[i];
}
board_addr + 0xC00 = 0; /* clear bios start flag */
devb[0] = 0x02 ; /* release reset to start BIOS */
Where:
board_addr is the base address of the board as seen by the host
mem_ptr is a pointer to board memory
membase is the base address of dual ported memory. (0xf0000 for
64K)
bios[] is a char array containing the BIOS code.
For the new board this is done with the following code:
devb[0] = 0x04 ; /* board held in reset */
devb[1] = 0x87 ; /* Select page 7 and enable memory
*/
mem_ptr = board_addr + 0x1800 ;
for(i = 0; i != n; i++)
{
*mem_ptr++ = bios[i];
}
devb[1] = 0x80 ; /* point to window 0 for global
data */
board_addr + 0xC00 = 0 ; /* clear bios start flag */
devb[0] = 0x00 ; /* release reset to start bios */
Loading the FEP
The FEP code is loaded at location 0x2000 as seen by the PC/Xe
For the old board this is done as follows:
mem_ptr = board_addr + 0x2000 ;
for(i = 0; i < n; i++)
{
*mem_ptr++ = fep[i];
}
board_addr + 0xc40 = 02 ; /* Command */
board_addr + 0xc42 = 0x200 ; /* From */
board_addr + 0xc44 = 0 ;
board_addr + 0xc46 = 0x200 ; /* To */
board_addr + 0xc48 = 0;
board_addr + 0xc4a = 0x2000 ; /* FEP/OS size */
devb[0] = 0x0a ; /* Interrupt to BIOS */
devb[0] = 0x02 ;
Where:
fep[] is a char array containing the FEP code.
For the new board the procedure is as follows:
devb[1] = 0x81 ; /* point at window 1 */
mem_ptr = board_addr ;
for( i = 0; i != n; i++)
{
*fep_ptr++ = fep[i] ;
}
devb[1] = 0x80 ; /* point at window 0 */
board_addr + 0xc40 = 02 ; /* Command */
board_addr + 0xc42 = 0x200 ; /* From */
board_addr + 0xc44 = 0 ;
board_addr + 0xc46 = 0x200 ; /* To */
board_addr + 0xc48 = 0;
board_addr + 0xc4a = 0x2000 ; /* FEP/OS size */
devb[0] = 0x08 ; /* Interrupt to BIOS */
devb[0] = 0x00 ;
Accessing Channel Buffers:
When using the old board, the method to access a channel receive buffer
is as follows:
/* get board address from channel structure receive segment */
chan_rcv = board_addr + (chan_ptr->rseg - base_seg) << 4 ;
/* get character from head of buffer */
while (chan_ptr->rout != chan_ptr->rin)
{
rcv_char = chan_rcv + chan_ptr->rout ;
chan_ptr->rout = (chan_ptr->rout + 1) & chan_ptr->rmax ;
}
Where:
chan_rcv is the start of the channel receive buffer.
chan_ptr is a pointer to the channel structure.
base_seg is the memory segment for the base of dual ported
memory as seen by teh PC/Xe.
The procedure for the new board is as follows:
/* enable window 0 */
devb[1] = 0x80 ;
rin_sav = chan_ptr->rin ;
rout_sav = chan_ptr->rout ;
rmax_sav = chan_ptr->rmax ;
reg_sav = chan_ptr->rseg ;
while(rin_sav != rout_sav)
{
/* calcluate offet of data from window base */
win_offset=((rseg_sav <<4) & 0x7fff) + rout_sav ;
/* select correct window */
devb[1] = 0x80 | (rseg_sav >>11)) ;
/* read in character */
rcv_char = board_addr + win_offset ;
/* update local copy of buffer pointer */
rout_sav = (rout_sav + 1) & rmax_sav ;
}
/* reselect base window */
devb[1] = 0x80 ;
chan_ptr->rout = rout_sav ; /* update out pointer */
Where:
rin_sav is a local copy of the receive input pointer
rout_sav is a local copy of the receive output pointer
rmax_sav is a local copy of the buffer size mask
rseg_sav is a local copy of the buffer segment as seen by the
PC/Xe
win_offset is the offset into the current window in bytes