Copy Link
Add to Bookmark
Report

Atari Bit-Block Transfer Processor (BLiTTER)

atari's profile picture
Published in 
atari
 · 29 Nov 2020

  
Well, here's a doc for all those people trying to get to grips with the
new ST BLITTER Chip. Many thanks to Paul The Wop for sending us this file,
which was edited extensively for Sewer Doc Disk 16 by Sewer Rat.

****
****
****
******
** ** **
** ** **
** ** **

User Manual for the Atari ST

Bit-Block Transfer Processor (BLiTTER)


TABLE OF CONTENTS


Introduction ...................................... 1

Bit-Block Transfers .......................... 2
Bit-Block Transfer ........................... 3

Functional Description ............................ 3

Programming Model ................................. 5
Register Map ................................. 5
Bit-Block Addresses .......................... 5
Source X Increment ...................... 6
Source Y Increment ...................... 6
Destination Address ..................... 6
Destination X Increment ................. 6
Destination Y Increment ................. 6
X Count ................................. 7
Y Count ................................. 7
Bit-Block Alignments ......................... 7
Endmask 1, 2, 3 ......................... 7
Skew .................................... 7
FXSR .................................... 7
NSFR .................................... 8
Logic Operations ............................. 8
Logic Operations ........................ 8
Halftone Operations .......................... 8
Halftone RAM ............................ 8
Line Number ............................. 8
Smudge .................................. 9
Halftone Operations ..................... 9
Bus Accesses ................................. 9
Hog ..................................... 9
Busy .................................... 9

Appendix A -- Programming Example ................. 10

Appendix B -- References .......................... 17



THE SCOPE OF THIS DOCUMENT is limited to a functional description of the
Atari ST BLiTTER. This document is not a data sheet for system inte-
gration, rather it is a user manual for system programming. For more
information, please refer to the texts listed at the end of this document.


*** INTRODUCTION

The Atari ST Bit-Block Transfer Processor (BLiTTER) is a hardware imple-
mentation of the bit-block transfer (BitBlt) algorithm. BitBlt can be
simply described as a procedure that moves bit-aligned data from a source
location to a destination location through a given logic operation. The
BitBlt primitive can be used to perform such operations as:

o Area seed filling
o Rotation by recursive subdivision
o Slice and smear magnification
o Brush line drawing using Bresenham DDA
o Text transformations (eg. bold, italic, outline)
o Text scrolling
o Window updating
o Pattern filling

And general memory-to-memory block copying [1].

The heart of BitBlt was first formally defined by Newman and Sproull in
their description of the function RasterOp [2]. As defined, RasterOp
performed its block transfers on a bit-by-bit basis and was limited to a
small subset of possible source and destination Boolean combinations.
Enhancements to RasterOp such as processing bits in parallel or intro-
ducing a halftone pattern into the transfer were literally left as
exercises for the reader.

In an effort to improve the functionality and performance of the original
algorithm, the prescribed enhancements were incorporated into the
definition of RasterOp and implemented in hardware as the RasterOp Chip
[3]. However the RasterOp Chip lacked the two-dimensionality of the
original function and suffered from a performance bottleneck caused by the
loading and reloading of source, destination, and halftone data (ie. it
could not DMA).

While efforts were being made to improve the performance of RasterOp, the
formal definition of RasterOp was further refined and became the basis of
the BitBlt copyLoop primitive in the Smalltalk-80 graphics kernel [4].
Because of its comprehensive interface definition, the BitBlt primitive
was inefficient and required special-case optimizations that violated its
general-purpose nature. Clearly a hardware solution was necessary to
increase the performance of the BitBlt copyLoop without sacrificing its
functionality.

The Atari ST BLiTTER is a hardware solution to the performance problems of
BitBlt. The BLiTTER is a DMA device that implements the full BitBlt
copyLoop definition with the addition of a few minor extensions. Single
word or multi-word increments and decrements are provided for transfers to
destinations in Atari ST video display memory. A center mask, which would
otherwise be a constant all ones, is also provided for an additional
level of texture. The remainder of this document is directly based on the
original functional description of the Atari ST BLiTTER.


*** BIT-BLOCK TRANSFERS

As previously stated, a bit-block transfer can be described as a procedure
that moves bit-aligned data from a source location to a destination
location through a given logic operation. There are sixteen logic
combination rules associated with the merging of source and destination
data. Note that this set contains all possible combinations between
source and destination. The following table contains the valid BitBlt
combination rules:

LOGIC OPERATIONS
(~s&~d)|(~s&d)|(s&~d)|(s&d)
_______________________________________
| | |
MSB LSB | OP | COMBINATION RULE |
| | |
0 0 0 0 | 0 | all zeros |
0 0 0 1 | 1 | source AND destination |
0 0 1 0 | 2 | source AND NOT destination |
0 0 1 1 | 3 | source |
0 1 0 0 | 4 | NOT source AND destination |
0 1 0 1 | 5 | destination |
0 1 1 0 | 6 | source XOR destination |
0 1 1 1 | 7 | source OR destination |
1 0 0 0 | 8 | NOT source AND NOT destination |
1 0 0 1 | 9 | NOT source XOR destination |
1 0 1 0 | A | NOT destination |
1 0 1 1 | B | source OR NOT destination |
1 1 0 0 | C | NOT source |
1 1 0 1 | D | NOT source OR destination |
1 1 1 0 | E | NOT source OR NOT destination |
1 1 1 1 | F | all ones |
|____|__________________________________|


Adjustments to block extents and several other transfer parameters are
determined prior to the invocation of the actual block transfer. These
adjustments and parameters include clipping, skew, end masks, and overlap.

Clipping. The source and destination block extents are adjusted to
conform with a specified clipping rectangle. Since both source and
destination blocks are of equal dimension, the destination block extent is
clipped to the extent of the source block (or vice versa). Note that the
block transfer need not be performed if the resultant extent is zero.

Skew. The source-to-destination horizontal bit skew is calculated.

End Masks. The left and right partial word masks are determined. The
masks are merged if the destination is one word in width.

Overlap. The block locations are checked for possible overlap in order to
avoid the destruction of source data before it is transferred.

In non-overlapping transfers the source block scanning direction is
inconsequential and can by default be from upper left to lower right. In
overlapping transfers the source scanning direction is also from upper
left to lower right if the source-to-destination transfer direction is up
and/or to the left (ie. source address is greater than or equal to
destination address). However, if the overlapping source-to-destination
transfer direction is down and/or to the right (ie. source address is less
than destination address), then the source data is scanned from lower
right to upper left.

After the transfer parameters are determined the bit-block transfer
operation can be invoked, transferring source to destination through the
logic operation (HALFTONE and HOP will be described in the next section):


*** BIT-BLOCK TRANSFER
_________ _____________ ________________
| || | | |
| SOURCE || SOURCE | | DESTINATION |
|_________||_____________| |________________|
|________________|<< SKEW | |
| |
______________ ___|____ ________________ |
| | | | | | |
| HALFTONE |----| HOP |-----| LOGIC OP |--|
|______________| |________| |________________| |
| |
____|____ |
| | |
| ENDMASK |____|
|_________|
|
_________|_________
| |
| NEW DESTINATION |
|___________________|



*** FUNCTIONAL DESCRIPTION

Please refer to the bit-block transfer diagram in the previous section.
To understand how the components of a block transfer work, let's look at
the simplest possible transfer. Take the case where we wish to fill a
block of memory with either all zeros or all ones (OP = 0 or OP = F). In
this case only the LOGIC OP block, which generates the ones or zeros, and
the ENDMASK block are in the data path. If the end mask contains all
ones, the BLiTTER will simply write one word after the other to the dest-
ination address without ever reading the destination.

As the writes take place the destination address will be adjusted
according to the values in the DESTINATION X INCREMENT, DESTINATION Y
INCREMENT, X COUNT, and Y COUNT registers. These registers define the
size and shape of the block to be transferred. The X and Y COUNT
registers define the size of the block. The X COUNT register specifies
the number of word-size writes required to update one line of the
destination. The Y COUNT register specifies the number of these lines in
the block. The DESTINATION X INCREMENT register is a signed (2's
complement) 16-bit quantity which is added to the destination address to
calculate the address of the next destination word of the line. On the
last write of the line the DESTINATION Y INCREMENT is added to calculate
the address of the first word of the next line.

The end mask determines which bits of the destination word will be up-
dated. Bits of the destination which correspond to ones in the end mask
will be updated. Bits of the destination which correspond to zeros in the
end mask will remain unchanged. Note that if any bits of the destination
are to be left unchanged, a read-modify-write is required. In order to
improve performance a read will only be performed if it is required.
There are three ENDMASK registers numbered 1 through 3. ENDMASK 1 is used
only for the first write of the line. ENDMASK 3 is used only for the last
write of the line. ENDMASK 2 is used for all other writes.

Now let's consider a more complicated case, suppose we want to XOR a
destination block with a 16 x 16 halftone pattern. First we load the
HALFTONE RAM with the halftone pattern. Select halftone only using the
HOP register and select source XOR destination using the OP register. The
LINE NUMBER register is used to specify which of the 16 words of HALFTONE
RAM is used for the current line. This register will be incremented or
decremented at the end of each line according to the sign of the DES-
TINATION Y INCREMENT register. Set the DESTINATION X and Y INCREMENT and
X and Y COUNT registers to the appropriate values and start the transfer.
This same procedure can be followed to do the combination using any logic
operation by simply changing the value in the OP register. Similarly the
combination can be performed using a source block instead of the HALFTONE
RAM or using the logical AND of a source block and the HALFTONE RAM by
changing the value of the HOP register. A source block is the same size
as the destination block but may have different increments and address
defined by the SOURCE X and Y INCREMENT and SOURCE ADDRESS registers.

Finally, let's look at the case when the source and destination blocks are
not bit-aligned. In this case we may need to read the first two source
words into the 32-bit source buffer and use the 16 bits that line up with
the appropriate bits of the destination, as specified by the SKEW reg-
ister. When the next source word is read, the lower 16 bits of the source
buffer is transferred to the upper 16 bits and the lower is replaced by
the new data. This process is reversed when the source is being read
from the right to the left (SOURCE X INCREMENT negative). Since there are
cases when it may be necessary for an extra source read to be performed
at the beginning of each line to "prime" the source buffer and cases when
it may not be necessary due to the choice of end mask, a bit has been
provided which forces the extra read. The FXSR (aka. pre-fetch) bit in
the SKEW register indicates, when set, that an extra source read should be
performed at the beginning of each line to "prime" the source buffer.
Similarly the NFSR (aka post-flush) bit, when set, will prevent the last
source read of the line. This read may not be necessary with certain
combinations of end masks and skews. If the read is suppressed, the lower
to upper half buffer transfer still occurs. Also in this case, a read-
modify-write cycle is performed on the destination for the last write of
each line regardless of the value of the corresponding ENDMASK register.


*** PROGRAMMING MODEL

The BLiTTER contains a set of registers that specify bit-block addresses,
bit-block alignments, logic and halftone operations, and bus accesses.
The register set-up time remains practically constant and is large
relative to small block transfers, whereas large bit-blocks are dominated
by the execution time of the transfer itself.


** REGISTER MAP

The following is a map of the BLiTTER programmable registers (note that
all unused bits read back as zeros):


FF 8A00 |oooooooo||oooooooo| HALFTONE RAM
FF 8A02 |oooooooo||oooooooo|
FF 8A04 |oooooooo||oooooooo|
: :: :
FF 8A1E |oooooooo||oooooooo|
FF 8A20 |oooooooo||ooooooo-| SOURCE X INCREMENT
FF 8A22 |oooooooo||ooooooo-| SOURCE Y INCREMENT
FF 8A24 |--------||oooooooo| SOURCE ADDRESS
FF 8A26 |oooooooo||ooooooo-|
FF 8A28 |oooooooo||oooooooo| ENDMASK 1
FF 8A2A |oooooooo||oooooooo| ENDMASK 2
FF 8A2C |oooooooo||oooooooo| ENDMASK 3
FF 8A2E |oooooooo||ooooooo-| DESTINATION X INCREMENT
FF 8A30 |oooooooo||ooooooo-| DESTINATION Y INCREMENT
FF 8A32 |--------||oooooooo| DESTINATION ADDRESS
FF 8A34 |oooooooo||ooooooo-|
FF 8A36 |oooooooo||oooooooo| X COUNT
FF 8A38 |oooooooo||oooooooo| Y COUNT

FF 8A3A |------oo| HOP
FF 8A3B |----oooo| OP

FF 8A3C |ooo-oooo|
||| |__|_____________ LINE NUMBER
|||__________________ SMUDGE
||__________________ HOG
|___________________ BUSY

FF 8A3D |oo--oooo|
|| |__|_____________ SKEW
||___________________ NFSR
|____________________ FXSR


** BIT-BLOCK ADDRESSES

This subsection describes registers that specify bit-block origins,
address increments, and extents.

SOURCE ADDRESS

This 23-bit register contains the current address of the source field
(only word addresses may be specified). It may be accessed using either
word or longword instructions. The value read back is always the address
of the next word to be used in a source operation. It will be updated by
the amounts specified in the SOURCE X INCREMENT and the SOURCE Y INCREMENT
registers as the transfer progresses.

SOURCE X INCREMENT

This is a signed 15-bit register, the least significant bit is ignored,
specifying the offset in bytes to the address of the next source word in
the current line. This value will be sign-extended and added to the
SOURCE ADDRESS register at the end of a source word fetch, whenever the X
COUNT register does not contain a value of one. If the X COUNT register
is loaded with a value of one this register is not used. Byte
instructions can not be used to read or write this register.

SOURCE Y INCREMENT

This is a signed 15-bit register, the least significant bit is ignored,
specifying the offset in bytes to the address of the first source word in
the next line. This value will be sign-extended and added to the SOURCE
ADDRESS register at the end of the last source word fetch of each line
(when the X COUNT register contains a value of one). If the X COUNT
register is loaded with a value of one this register is used exclusively.
Byte instructions can not be used to read or write this register.

DESTINATION ADDRESS

This 23-bit register contains the current address of the destination field
(only word addresses may be specified). It may be accessed using either
word or long-word instructions. The value read back is always the address
of the next word to be modified in the destination field. It will be
updated by the amounts specified in the DESTINATION X INCREMENT and the
DESTINATION Y INCREMENT registers as the transfer progresses.

DESTINATION X INCREMENT

This is a signed 15-bit register, the least significant bit is ignored,
specifying the offset in bytes to the address of the next destination word
in the current line. This value will be sign-extended and added to the
DESTINATION ADDRESS register at the end of a destination word write,
whenever the X COUNT register does not contain a value of one. If the X
COUNT register is loaded with a value of one this register is not used.
Byte instructions can not be used to read or write this register.

DESTINATION Y INCREMENT

This is a signed 15-bit register, the least significant bit is ignored,
specifying the offset in bytes to the address of the first destination
word in the next line. This value will be sign-extended and added to the
DESTINATION ADDRESS register at the end of the last destination word write
of each line (when the X COUNT register contains a value of one). If the
X COUNT register is loaded with a value of one this register is used
exclusively. Byte instructions cannot be used on this register.

X COUNT

This 16-bit register specifies the number of words contained in one
destination line. The minimum number is one and the maximum is 65536
designated by zero. Byte instructions can not be used to read or write
this register. Reading this register returns the number of destination
words yet to be written in the current line, NOT necessarily the value
initially written to the register. Each time a destination word is
written the value will be decremented until it reaches zero, at which time
it will be returned to its initial value.

Y COUNT

This 16-bit register specifies the number of lines in the destination
field. The minimum number is one and the maximum is 65536 designated by
zero. Byte instructions can not be used to read or write this register.
Reading this register returns the number of destination lines yet to be
written, NOT necessarily the value initially written to the register.
Each time a destination line is completed the value will be decremented
until it reaches zero, at which time the tranfer is complete.


** BIT-BLOCK ALIGNMENTS

This subsection describes registers that specify bit-block end masks,
source-to-destination skew, and source data fetching.

ENDMASK 1, 2, 3

These 16-bit registers are used to mask destination writes. Bits of the
destination word which correspond to ones in the current ENDMASK register
will be modified. Bits of the destination word which correspond to zeros
in the current ENDMASK register will remain unchanged. The current
ENDMASK register is determined by position in the line. ENDMASK 1 is used
only for the first write of a line. ENDMASK 3 is used only for the last
write of a line. ENDMASK 2 is used in all other cases. In the case of a
one word line ENDMASK 1 is used. Byte instructions can not be used to
read or write these registers.

SKEW

The least significant four bits of the byte-wide register at FF 8A3D
specify the source skew. This is the amount the data in the source data
latch is shifted right before being combined with the halftone mask and
destination data.

FXSR

FXSR stands for Force eXtra Source Read. When this bit is set one extra
source read is performed at the start of each line to initialize the
remainder portion source data latch.

NFSR

NFSR stands for No Final Source Read. When this bit is set the last
source read of each line is not performed. Note that use of this and/or
the FXSR bit the requires an adjustment to the SOURCE Y INCREMENT and
SOURCE ADDRESS registers.


** LOGIC OPERATIONS

This subsection describes registers that specify the logic combinations of
source and destination bit-block data.

The least significant four bits of the byte-wide register at FF 8A3B
specify the source/destination combination rule according to the following
table:

_______________________________________
| | |
| OP | COMBINATION RULE |
| | |
| 0 | all zeros |
| 1 | source AND destination |
| 2 | source AND NOT destination |
| 3 | source |
| 4 | NOT source AND destination |
| 5 | destination |
| 6 | source XOR destination |
| 7 | source OR destination |
| 8 | NOT source AND NOT destination |
| 9 | NOT source XOR destination |
| A | NOT destination |
| B | source OR NOT destination |
| C | NOT source |
| D | NOT source OR destination |
| E | NOT source OR NOT destination |
| F | all ones |
|____|__________________________________|


** HALFTONE OPERATIONS

This subsection describes registers that specify the halftone pattern
memory, halftone word index, and combinations of source and halftone data.

HALFTONE RAM

This RAM holds a 16x16 halftone pattern mask. Each word is valid for one
line of the destination field and is repeated every 16 lines. The current
word is pointed to by the value in the LINE NUMBER register. These
registers may be read, but can not be accessed using byte-wide
instructions.

LINE NUMBER

The least significant four bits of the byte-wide register at FF 8A3C
specify the current halftone mask. The current value times two plus FF
8A00 gives the address of the current halftone mask. This value is
incremented or decremented at the end of each line and will wrap through
zero. The sign of the DESTINATION Y INCREMENT determines if the line
number is incremented or decremented (increment if positive, decrement if
negative).

SMUDGE

The SMUDGE bit, when set, causes the least significant four bits of the
skewed source data to be used as the address of the current halftone
pattern. Note that the halftone operation is still valid when SMUDGE is
set.

HALFTONE OPERATIONS

The least significant two bits of the byte-wide register at FF 8A3A
specify the source/halftone combination rule according to the following
table:

_____________________________
| | |
| HOP| COMBINATION RULE |
| | |
| 0 | all ones |
| 1 | halftone |
| 2 | source |
| 3 | source AND halftone |
|____|________________________|


** BUS ACCESSES

This subsection describes registers that specify bus access control and
BLiTTER start/status.

HOG

The HOG bit, when cleared, causes the processor and the blitter to share
the bus equally. In this mode each will get 64 bus cycles while the other
is halted. When set, the bit will cause the processor to be halted until
the transfer is complete. In either case the BLiTTER will yield to other
DMA devices. Bus arbitration may allow the processor to execute one or
more instructions even in hog mode. Therefore, don't assume that the
instruction following the one which sets the BUSY bit will be executed
only after the transfer is complete. The BUSY bit may be polled to
achieve this kind of synchronization.

BUSY

The BUSY bit is set after all the other registers have been initialized to
begin the transfer operation. It will remain set until the transfer is
complete. The interrupt line is a duplicate of this bit. See the
Programming Example for more details on how to use the BUSY bit.


Appendix A -- Programming Example

In order to maintain software compatibility with new or upgraded Atari STs
equipped with the BLiTTER, software developers need only follow guidelines
set forth by the VDI and "LINE A" documents. Revised TOS ROMs will work
in concert with the BLiTTER, enhancing the performance of many VDI and
"LINE A" operations. This occurs in a manner transparent to an executing
program. Thus no special actions need be taken to utilize the performance
advantages of the BLiTTER.

As a rule of thumb, never make a VDI or "LINE A" call from within an
interrupt context since unpredictable and potentially catastrophic results
will occur should one BLiTTER operation interrupt another BLiTTER
operation.

The following program has not been optimized and is presented here for
exemplary purposes only.

* (c) 1987 Atari Corporation
* All Rights Reserved.

* BLiTTER BASE ADDRESS

BLiTTER equ $FF8A00

* BLiTTER REGISTER OFFSETS

Halftone equ 0
Src_Xinc equ 32
Src_Yinc equ 34
Src_Addr equ 36
Endmask1 equ 40
Endmask2 equ 42
Endmask3 equ 44
Dst_Xinc equ 46
Dst_Yinc equ 48
Dst_Addr equ 50
X_Count equ 54
Y_Count equ 56
HOP equ 58
OP equ 59
Line_Num equ 60
Skew equ 61

* BLiTTER REGISTER FLAGS

fHOP_Source equ 1
fHOP_Halftone equ 0

fSkewFXSR equ 7
fSkewNFSR equ 6

fLineBusy equ 7
fLineHog equ 6
fLineSmudge equ 5

* BLiTTER REGISTER MASKS

mHOP_Source equ $02
mHOP_Halftone equ $01

mSkewFXSR equ $80
mSkewNFSR equ $40

mLineBusy equ $80
mLineHog equ $40
mLineSmudge equ $20

* E n D m A s K d A t A
*
* These tables are referenced by PC relative instructions. Thus,
* the labels on these tables must remain within 128 bytes of the
* referencing instructions forever. Amen.
*
* 0: Destination 1: Source <<< Invert right end mask data >>>

lf_endmask:
dc.w $FFFF

rt_endmask:
dc.w $7FFF
dc.w $3FFF
dc.w $1FFF
dc.w $0FFF
dc.w $07FF
dc.w $03FF
dc.w $01FF
dc.w $00FF
dc.w $007F
dc.w $003F
dc.w $001F
dc.w $000F
dc.w $0007
dc.w $0003
dc.w $0001
dc.w $0000

* TiTLE: BLiT_iT
*
* PuRPoSE:
* Transfer a rectangular block of pixels located at an
* arbitrary X,Y position in the source memory form to
* another arbitrary X,Y position in the destination memory
* form using replace mode (boolean operator 3).
* The source and destination rectangles should not overlap.
*
* iN:
* a4 pointer to 34 byte input parameter block
*
* Note: This routine must be executed in supervisor mode as
* access is made to hardware registers in the protected region
* of the memory map.
*
*
* I n p u t p a r a m e t e r b l o c k o f f s e t s

SRC_FORM equ 0 ; Base address of source memory form .l
SRC_NXWD equ 4 ; Offset between words in source plane .w
SRC_NXLN equ 6 ; Source form width .w
SRC_NXPL equ 8 ; Offset between source planes .w
SRC_XMIN equ 10 ; Source blt rectangle minimum X .w
SRC_YMIN equ 12 ; Source blt rectangle minimum Y .w

DST_FORM equ 14 ; Base address of destination memory form .l
DST_NXWD equ 18 ; Offset between words in destination plane.w
DST_NXLN equ 20 ; Destination form width .w
DST_NXPL equ 22 ; Offset between destination planes .w
DST_XMIN equ 24 ; Destination blt rectangle minimum X .w
DST_YMIN equ 26 ; Destination blt rectangle minimum Y .w

WIDTH equ 28 ; Width of blt rectangle .w
HEIGHT equ 30 ; Height of blt rectangle .w
PLANES equ 32 ; Number of planes to blt .w

BLiT_iT:

lea BLiTTER,a5 ; a5-> BLiTTER register block

*
* Calculate Xmax coordinates from Xmin coordinates and width
*
move.w WIDTH(a4),d6
subq.w #1,d6 ; d6<- width-1

move.w SRC_XMIN(a4),d0 ; d0<- src Xmin
move.w d0,d1
add.w d6,d1 ; d1<- src Xmax=src Xmin+width-1

move.w DST_XMIN(a4),d2 ; d2<- dst Xmin
move.w d2,d3
add.w d6,d3 ; d3<- dst Xmax=dstXmin+width-1

*
* Endmasks are derived from source Xmin mod 16 and source Xmax
* mod 16
*
moveq.l #$0F,d6 ; d6<- mod 16 mask

move.w d2,d4 ; d4<- DST_XMIN
and.w d6,d4 ; d4<- DST_XMIN mod 16
add.w d4,d4 ; d4<- offset into left end mask tbl

move.w lf_endmask(pc,d4.w),d4 ; d4<- left endmask

move.w d3,d5 ; d5<- DST_XMAX
and.w d6,d5 ; d5<- DST_XMAX mod 16
add.w d5,d5 ; d5<- offset into right end mask tbl

move.w rt_endmask(pc,d5.w),d5 ; d5<-inverted right end mask
not.w d5 ; d5<- right end mask

*
* Skew value is (destination Xmin mod 16 - source Xmin mod 16)
* && 0x000F. Three discriminators are used to determine the
* states of FXSR and NFSR flags:
*
* bit 0 0: Source Xmin mod 16 =< Destination Xmin mod 16
* 1: Source Xmin mod 16 > Destination Xmin mod 16
*
* bit 1 0: SrcXmax/16-SrcXmin/16 <> DstXmax/16-DstXmin/16
* Source span Destination span
* 1: SrcXmax/16-SrcXmin/16 == DstXmax/16-DstXmin/16
*
* bit 2 0: multiple word Destination span
* 1: single word Destination span
*
* These flags form an offset into a skew flag table yielding
* correct FXSR and NFSR flag states for the given source and
* destination alignments
*

move.w d2,d7 ; d7<- Dst Xmin
and.w d6,d7 ; d7<- Dst Xmin mod16
and.w d0,d6 ; d6<- Src Xmin mod16
sub.w d6,d7 ; d7<- Dst Xmin mod16-Src Xmin mod16
* ; if Sx&F > Dx&F then cy:1 else cy:0
clr.w d6 ; d6<- initial skew flag table index
addx.w d6,d6 ; d6[bit0]<- intraword alignment flag

lsr.w #4,d0 ; d0<- word offset to src Xmin
lsr.w #4,d1 ; d1<- word offset to src Xmax
sub.w d0,d1 ; d1<- Src span - 1

lsr.w #4,d2 ; d2<- word offset to dst Xmin
lsr.w #4,d3 ; d3<- word offset to dst Xmax
sub.w d2,d3 ; d3<- Dst span - 1
bne set_endmasks ; 2nd discriminator is one word dst

* When destination spans a single word, both end masks are merged
* into Endmask1. The other end masks will be ignored by the BLiTTER

and.w d5,d4 ; d4<- single word end mask
addq.w #4,d6 ; d6[bit2]:1 => single word dst

set_endmasks:

move.w d4,Endmask1(a5) ; left end mask
move.w #$FFFF,Endmask2(a5) ; center end mask
move.w d5,Endmask3(a5) ; right end mask

cmp.w d1,d3 ; the last discriminator is the
bne set_count ; equality of src and dst spans

addq.w #2,d6 ; d6[bit1]:1 => equal spans

set_count:
move.w d3,d4
addq.w #1,d4 ; d4<- number of words in dst line
move.w d4,X_Count(a5) ; set value in BLiTTER

* Calculate Source starting address:
*
* Source Form address +
* (Source Ymin * Source Form Width) +
* ((Source Xmin/16) * Source Xinc)

move.l SRC_FORM(a4),a0 ; a0-> start of Src form
move.w SRC_YMIN(a4),d4 ; d4<- offset in lines to Src Ymin
move.w SRC_NXLN(a4),d5 ; d5<- length of Src form line
mulu d5,d4 ; d4<- byte offset to (0, Ymin)
add.l d4,a0 ; a0-> (0, Ymin)

move.w SRC_NXWD(a4),d4; d4<- offset between consecutive
move.w d4,Src_Xinc(a5) ; words in Src plane

mulu d4,d0 ; d0<- offset to word containing Xmin
add.l d0,a0 ; a0-> 1st src word (Xmin, Ymin)

* Src_Yinc is the offset in bytes from the last word of one Source
* line to the first word of the next Source line

mulu d4,d1 ; d1<- width of src line in bytes
sub.w d1,d5 ; d5<- value added to ptr at end
move.w d5,Src_Yinc(a5) ; of line to reach start of next

* Calculate Destination starting address

move.l DST_FORM(a4),a1 ; a1-> start of dst form
move.w DST_YMIN(a4),d4 ; d4<- offset in lines to dst Ymin
move.w DST_NXLN(a4),d5 ; d5<- width of dst form

mulu d5,d4 ; d4<- byte offset to (0, Ymin)
add.l d4,a1 ; a1-> dst (0, Ymin)

move.w DST_NXWD(a4),d4 ; d4<- offset between consecutive
move.w d4,Dst_Xinc(a5) ; words in dst plane

mulu d4,d2 ; d2<- DST_NXWD * (DST_XMIN/16)
add.l d2,a1 ; a1-> 1st dst word (Xmin, Ymin)

* Calculate Destination Yinc

mulu d4,d3 ; d3<- width of dst line - DST_NXWD
sub.w d3,d5 ; d5<- value added to dst ptr at
move.w d5,Dst_Yinc(a5) ; end of line to reach next line

* The low nibble of the difference in Source and Destination alignment
* is the skew value. Use the skew flag index to reference FXSR and
* NFSR states in skew flag table.

and.b #$0F,d7 ; d7<- isolated skew count
or.b skew_flags(pc,d6.w),d7 ; d7<- necessary flags and skew
move.b d7,Skew(a5) ; load Skew register

move.b #mHOP_Source,HOP(a5) ; set HOP to source only
move.b #3,OP(a5) ; set OP to "replace" mode

lea Line_Num(a5),a2 ; fast refer to Line_Num register
move.b #fLineBusy,d2 ; fast refer to LineBusy flag
move.w PLANES(a4),d7 ; d7 <- plane counter
bra begin

* T h e s e t t i n g o f s k e w f l a g s
*
*
* QUALIFIERS ACTIONS BITBLT DIRECTION: LEFT -> RIGHT
*
* equal Sx&F>
* spans Dx&F FXSR NFSR
*
* 0 0 0 1 |..ssssssssssssss|ssssssssssssss..|
* |......dddddddddd|dddddddddddddddd|dd..............|
*
* 0 1 1 0 |..dddddddddddddd|dddddddddddddd..|
* |......ssssssssss|ssssssssssssssss|ss..............|
*
* 1 0 0 0 |..ssssssssssssss|ssssssssssssss..|
* |...ddddddddddddd|ddddddddddddddd.|
*
* 1 1 1 1 |...sssssssssssss|sssssssssssssss.|
* |..dddddddddddddd|dddddddddddddd..|


skew_flags:

dc.b mSkewNFSR ; Source span < Destination span
dc.b mSkewFXSR ; Source span > Destination span
dc.b 0 ; Spans equal Shift Source right
dc.b mSkewNFSR+mSkewFXSR ; Spans equal Shift Source left

* When Destination span is but a single word ...

dc.b 0 ; Implies a Source span of no words
dc.b mSkewFXSR ; Source span of two words
dc.b 0 ; Skew flags aren't set if Source and
dc.b 0 ; Destination spans are both one word

next_plane:
move.l a0,Src_Addr(a5) ; load Source pointer to this plane

move.l a1,Dst_Addr(a5) ; load Dest ptr to this plane
move.w HEIGHT(a4),Y_Count(a5) ; load the line count

move.b #mLineBusy,(a2) ; <<< start the BLiTTER >>>

add.w SRC_NXPL(a4),a0 ; a0-> start of next src plane
add.w DST_NXPL(a4),a1 ; a1-> start of next dst plane


* The BLiTTER is usually operated with the HOG flag cleared.
* In this mode the BLiTTER and the ST's cpu share the bus equally,
* each taking 64 bus cycles while the other is halted. This mode
* allows interrupts to be fielded by the cpu while an extensive
* BitBlt is being processed by the BLiTTER. There is a drawback in
* that BitBlts in this shared mode may take twice as long as BitBlts
* executed in hog mode. Ninety percent of hog mode performance is
* achieved while retaining robust interrupt handling via a method
* of prematurely restarting the BLiTTER. When control is returned
* to the cpu by the BLiTTER, the cpu immediately resets the BUSY
* flag, restarting the BLiTTER after just 7 bus cycles rather than
* after the usual 64 cycles. Interrupts pending will be serviced
* before the restart code regains control. If the BUSY flag is
* reset when the Y_Count is zero, the flag will remain clear
* indicating BLiTTER completion and the BLiTTER won't be restarted.
*
* (Interrupt service routines may explicitly halt the BLiTTER
* during execution time critical sections by clearing the BUSY flag.
* The original BUSY flag state must be restored however, before
* termination of the interrupt service routine.)

restart:
bset.b d2,(a2) ; Restart BLiTTER and test the BUSY
nop ; flag state. The "nop" is executed
bne restart ; prior to the BLiTTER restarting.
* ; Quit if the BUSY flag was clear.

begin:
dbra d7,next_plane
rts



Appendix B -- References


[1] Rob Pike, Leo Guibas, and Dan Ingalls, 'SIGGRAPH'84
Course Notes: Bitmap Graphics', AT&T Bell Laboratories
1984.


[2] William Newman and Robert Sproull, 'Principles of
Interactive Computer Graphics', McGraw-Hill 1979,
Chapter 18.


[3] John Atwood, '16160 RasterOp Chip Data Sheet', Silicon
Compilers 1984. See also 'VL16160 RasterOp
Graphics/Boolean Operation ALU', VLSI Technology 1986.


[4] Adele Goldberg and David Robson, 'Smalltalk-80: The
Language and its Implementation', Addison-Wesley 1983,
Chapter 18.


---- END OF TEXT ----

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT