[comp.sys.amiga.tech] Unsupported Programming Practices

carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) (01/03/89)

                              IMPORTANT !    

       Official Warning to Rom-Jumpers, Structure-Hackers, and Others
       ==============================================================
          From Commodore Engineering, Commodore-Amiga, and C.A.T.S.

     We who bring you the Amiga want to make it perfectly clear that
if you don't follow the rules, you WILL break.  

     The following practices are NOT supported !
 
       - Jumping directly to ROM code
       - Modifying or depending on private system structures 
       - Depending on the addresses of system structures or free memory
       - Ignoring hardware or software interfacing specifications


     Do not jump into ROM.  Beware of any example code that calls routines
in the $F80000 to $FFFFFF range.  Those are ROM addresses and those ROM
routines WILL move.   The only supported interface to system ROM code
is through the provided library, device, and resource calls. 

     Do not modify or depend on the format of the private system structures.
This includes the poking of copper lists, memory lists, and library bases.

     Do not depend on any address containing any particular system structure 
or type of memory.  The system modules dynamically allocate their memory
space when they are initialized.  The addresses of system structures and 
buffers differ with every OS, every model, and every configuration, as
does the amount of free memory and system stack usage. 

     If you are using the system libraries, devices, and resources, you
must follow the defined interface.  Assembler programmers (and compiler
writers) must enter functions through the library base jump tables,
with arguments passed as longs and library base address in A6.  Results
returned in D0 must be tested, and the contents of D0-D0/A0-A1 must be 
assumed lost after a system call.  

     Do not use assembler instructions which are priviledged on any 
68000 family processor.  All addresses must be 32 bits.  Do not use
the upper 8 bits for other data.  Do not execute code on your stack or
put system structures on your stack.  Do not use the TAS instruction.  
Do not use software instruction based timimg loops or delays.

     If you are programming at the hardware level, you must follow hardware
interfacing specifications.  All hardware is NOT the same.  Do not assume 
that low level hacks for speed or copy protection will work on all drives, 
or all keyboards, or all systems, or future systems.  

     Software distributers who purchase or contract software from
outside programmers must make sure that the programmers are aware
of correct programming practices and are providing software which
will not break on different machines or different OS revisions.


     We are dedicated to enhancing and expanding the capabilities of
the Amiga hardware and software, while maintaining compatibility
wherever possible for those who follow the rules.  Those who don't
follow the rules can consider themselves warned.



-- 
==========================================================================
  Carolyn Scheppner -- CATS  Commodore Amiga Technical Support
  PHONE 215-431-9180   UUCP  ...{uunet,allegra,rutgers}!cbmvax!carolyn 

 Programmers do it a little bit better.
==========================================================================

daveh@cbmvax.UUCP (Dave Haynie) (01/04/89)

in article <5605@cbmvax.UUCP>, carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) says:
> Keywords: warning unsupported

>                               IMPORTANT !    

>      Do not use assembler instructions which are priviledged on any 
> 68000 family processor.  All addresses must be 32 bits.  Do not use
> the upper 8 bits for other data.  Do not execute code on your stack or
> put system structures on your stack.  Do not use the TAS instruction.
> Do not use software instruction based timimg loops or delays.

Along similar lines:

	Don't write self-modifying code.  It currently CAN'T be supported
	for future systems.  Even if you get clever and manage to always
	overrun the cache on a 68020 system, you'll probably not overrun
	the cache on a future system.

	If you're messing with exception stacks, you're responsible for
	doing the right things for each 680x0 processor.  Note that even
	the 68010 has it's own special exception stack in some cases.

	Don't expect OS level things done by user level programs to always
	work.  Things like changing cache parameters or MMU banging are by
	definition things that should be managed by the operating system.
	Currently, some of these aren't.  In the future, they should be.  And
	programs that muck with them today will not likely work once OS 
	support is provided.

>   Carolyn Scheppner -- CATS  Commodore Amiga Technical Support
>   PHONE 215-431-9180   UUCP  ...{uunet,allegra,rutgers}!cbmvax!carolyn 
-- 
Dave Haynie  "The 32 Bit Guy"     Commodore-Amiga  "The Crew That Never Rests"
   {uunet|pyramid|rutgers}!cbmvax!daveh      PLINK: D-DAVE H     BIX: hazy
              Amiga -- It's not just a job, it's an obsession

jesup@cbmvax.UUCP (Randell Jesup) (01/04/89)

In article <5608@cbmvax.UUCP> daveh@cbmvax.UUCP (Dave Haynie) writes:
>in article <5605@cbmvax.UUCP>, carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) says:
>> Keywords: warning unsupported
>
>>                               IMPORTANT !    
>	If you're messing with exception stacks, you're responsible for
>	doing the right things for each 680x0 processor.  Note that even
>	the 68010 has it's own special exception stack in some cases.

	In particular, don't forget that the VBR register exists on '010's
and above - if it's there, use it, don't assume the exception vector
table starts down in low mem.

>>   Carolyn Scheppner -- CATS  Commodore Amiga Technical Support
>>   PHONE 215-431-9180   UUCP  ...{uunet,allegra,rutgers}!cbmvax!carolyn 
-- 
Randell Jesup, Commodore Engineering {uunet|rutgers|allegra}!cbmvax!jesup

wayneck@tekig5.PEN.TEK.COM (Wayne Knapp) (01/05/89)

Can we count on the addresses of the hardware registers, (like the blitter 
registers) always staying the same?  If not how can a program find out the
correct addresses?

Also thanks to all the people who helped me out on the CloseFont call.  I'm
really impressed by the great support here, if only I had a set of manuals
that matched the net support programming the Amiga would easy.

                                    Wayne Knapp

ewhac@well.UUCP (Leo L. Schwab) (01/05/89)

In article <5605@cbmvax.UUCP> carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) writes:
>                              IMPORTANT !    
>       Official Warning to Rom-Jumpers, Structure-Hackers, and Others
>       ==============================================================
>Do not execute code on your stack or put system structures on your stack.

	Why not?

	I occasionally put RastPorts on my stack; does that count?

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape	INET: well!ewhac@ucbvax.Berkeley.EDU
 \_ -_		Recumbent Bikes:	UUCP: pacbell > !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor

steveb@cbmvax.UUCP (Steve Beats) (01/06/89)

In article <10227@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>In article <5605@cbmvax.UUCP> carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) writes:
>>                              IMPORTANT !    
>>       Official Warning to Rom-Jumpers, Structure-Hackers, and Others
>>       ==============================================================
>>Do not execute code on your stack or put system structures on your stack.
>
>	Why not?
>
>	I occasionally put RastPorts on my stack; does that count?
>
Yes that certainly does count.  If Exec ever gets its act together and starts
using the MMU, your stack would be private memory.  If graphics attempted to
access the RastPort (as a separate task through Intuition for instance) it 
would cause an illegal access exception.  I would suggest you either:-

a)	Allocate rastports using MEMF_PUBLIC
b)	Allocate a new stack using MEMF_PUBLIC

I'd like to point out that MEMF_PUBLIC is not really a solution but it should
help out in these retrograde cases.  The most likely solution is that we'll
introduce a new task type that knows it's running under MMU protection.  If
this is the case then your current practices are safe.  However, if this turns
out to be an impractical solution, at least we haven't killed all possibilities
by telling folks it's OK to stick stuff on the stack.

You can't put code on the stack because that's identical to writing self
modifying code.  Since the I-Cache doesn't do any bus snooping, it may have
already cached that location and won't notice the changed code.

	Steve

dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (01/06/89)

:>Do not execute code on your stack or put system structures on your stack.
:
:	Why not?
:
:	I occasionally put RastPorts on my stack; does that count?

	Yah!  so do I .. rastports and bitmap structures .. why not?

	One thing I have always wondered about:  Since many operations start
a blit and return (i.e. Draw()), how can you really be sure when your bitmap's
raster's can be freed?  Is there some call one can make which ensures any
blitter usage from the previous graphics library call will complete before
returning?

					-Matt

dale@boing.UUCP (Dale Luck) (01/07/89)

In article <8901060406.AA22607@postgres.Berkeley.EDU> dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) writes:
$	One thing I have always wondered about:  Since many operations start
$a blit and return (i.e. Draw()), how can you really be sure when your bitmap's
$raster's can be freed?  Is there some call one can make which ensures any
$blitter usage from the previous graphics library call will complete before
$returning?

It's called WaitBlit().
This can be called anytime. Even if you do not own the blitter.

$
$					-Matt


-- 
Dale Luck     GfxBase/Boing, Inc.
{uunet!cbmvax|pyramid}!amiga!boing!dale

cmcmanis%pepper@Sun.COM (Chuck McManis) (01/07/89)

In article <8901060406.AA22607@postgres.Berkeley.EDU> (Matt Dillon) writes:
> Is there some call one can make which ensures any blitter usage from the 
> previous graphics library call will complete before returning?

Would OwnBlitter() work for this? I assume that the sequence :
	Draw(...);
	OwnBlitter();
Can't possibly give you the Blitter before the Draw call has finished
with it.

--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.

rokicki@polya.Stanford.EDU (Tomas G. Rokicki) (01/07/89)

> > Is there some call one can make which ensures any blitter usage from the 
> > previous graphics library call will complete before returning?
> Would OwnBlitter() work for this? I assume that the sequence :
> 	Draw(...);
> 	OwnBlitter();
> Can't possibly give you the Blitter before the Draw call has finished
> with it.

Nicht, won't work.  Even after OwnBlitter() the blitter could very
well be doing a blit; you need a WaitBlit() after that before using
the blitter.  The correct technique is WaitBlit().  This assumes
that Draw() (or the other graphics routines) do not return with more
than one Blit pending (yes, a Draw can require multiple blits).
Can this be guaranteed, Dale?

-tom

pds@quintus.uucp (Peter Schachte) (01/07/89)

In article <5632@cbmvax.UUCP> steveb@cbmvax.UUCP (Steve Beats) writes:
>>	I occasionally put RastPorts on my stack; does that count?
>Yes that certainly does count.  If Exec ever gets its act together and starts
>using the MMU, your stack would be private memory.

Wouldn't it be nice if there were a MEMF_PUBLICLY_READABLE memory type?
The idea is that any process can read that memory, but only its owner
can write to it.  Stacks could use this type of memory by default.  And
a MEMF_READ_ONLY would be useful (for things like sharable libraries),
if someone could work out a semantics that allowed it to be written into
once, sort of like the A1000's WCS.

I dunno if Motorola's memory management hardware would support any of
this.
-Peter Schachte
pds@quintus.uucp
..!sun!quintus!pds

dale@boing.UUCP (Dale Luck) (01/07/89)

In article <84277@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes:
>In article <8901060406.AA22607@postgres.Berkeley.EDU> (Matt Dillon) writes:
>> Is there some call one can make which ensures any blitter usage from the 
>> previous graphics library call will complete before returning?
>
>Would OwnBlitter() work for this? I assume that the sequence :
>	Draw(...);
>	OwnBlitter();
>Can't possibly give you the Blitter before the Draw call has finished
>with it.
>

Nope, not true. OwnBlitter returns when you have logical control of
the blitter. However the blitter may still be finishing up the last
blit. You need to use WaitBlit().

Draw will return after firing off the last blit which is usually the
last plane. However Draw does not wait for the blitter to finish
before Disowning the blitter. This is done to achieve as great amount
of overlap of cpu cycles and blitter cycles as possible.

-- 
Dale Luck     GfxBase/Boing, Inc.
{uunet!cbmvax|pyramid}!amiga!boing!dale

ewhac@well.UUCP (Leo L. Schwab) (01/07/89)

In article <5632@cbmvax.UUCP> steveb@cbmvax.UUCP (Steve Beats) writes:
>In article <10227@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>>In article <5605@cbmvax.UUCP> carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) writes:
>>>Do not execute code on your stack or put system structures on your stack.
>>	I occasionally put RastPorts on my stack; does that count?
>>
>Yes that certainly does count.  If Exec ever gets its act together and starts
>using the MMU, your stack would be private memory.  If graphics attempted to
>access the RastPort (as a separate task through Intuition for instance) it 
>would cause an illegal access exception.  I would suggest you either:-
>
>a)	Allocate rastports using MEMF_PUBLIC
>b)	Allocate a new stack using MEMF_PUBLIC
>
	AARRGGHHH!  What a bloody nuisance.  Throwing temproary RastPorts
around on the stack has been a real nice win for me.  I've been doing things
like this:

	if (loadILBM() == SUCCESS) {
		struct RastPort	lrp;

		InitRastPort (&lrp);
		lrp.BitMap = &loaded_bitmap;
		ClipBlit (&lrp, 0L, 0L, &dest, 0L, 0L, w, h, MINTERM_COPY);
	}

	So now I have to do AllocMem()s with sanity checks with
corresponding FreeMem()s?  Foo.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape	INET: well!ewhac@ucbvax.Berkeley.EDU
 \_ -_		Recumbent Bikes:	UUCP: pacbell > !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor

ewhac@well.UUCP (Leo L. Schwab) (01/07/89)

In article <8901060406.AA22607@postgres.Berkeley.EDU> dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) writes:
>Is there some call one can make which ensures any
>blitter usage from the previous graphics library call will complete before
>returning?
>
	WaitBlit()?

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape	INET: well!ewhac@ucbvax.Berkeley.EDU
 \_ -_		Recumbent Bikes:	UUCP: pacbell > !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor

shimoda@infohh.rmi.de (Markus Schmidt) (01/07/89)

>>       Official Warning to Rom-Jumpers, Structure-Hackers, and Others
>>       ==============================================================
>>Do not execute code on your stack or put system structures on your stack.
Does that appy to Gadget, IText and whatsoever-Structures too??



Please enlighten me!

Cu
Markus

shimoda@infohh.rmi.dr
shimoda@gopnbg.UUCP

shimoda@infohh.rmi.de (Markus Schmidt) (01/07/89)

In article <8901060406.AA22607@postgres.Berkeley.EDU> dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) writes:
>raster's can be freed?  Is there some call one can make which ensures any
>blitter usage from the previous graphics library call will complete before
>returning?
I think WaitBlit() should serve your needs.


C u
Markus

shimoda@infohh.rmi.d

dale@boing.UUCP (Dale Luck) (01/07/89)

In article <5932@polya.Stanford.EDU> rokicki@polya.Stanford.EDU (Tomas G. Rokicki) writes:
>the blitter.  The correct technique is WaitBlit().  This assumes
>that Draw() (or the other graphics routines) do not return with more
>than one Blit pending (yes, a Draw can require multiple blits).
>Can this be guaranteed, Dale?

At this time there is atmost a single blit that the blitter can be
working on at a time. WaitBlit will make sure it is done before allowing
you to proceed.

If in the future there is a hardware/software architecture change then
WaitBlit will be changed to conform and again should be safe to use.

>
>-tom


-- 
Dale Luck     GfxBase/Boing, Inc.
{uunet!cbmvax|pyramid}!amiga!boing!dale

lee@uhccux.uhcc.hawaii.edu (Greg Lee) (01/07/89)

From article <579@boing.UUCP>, by dale@boing.UUCP (Dale Luck):
" You need to use WaitBlit().

Judging from code in the 1.0 rom, you may need to use it twice.
		Greg, lee@uhccux.uhcc.hawaii.edu

john13@garfield.MUN.EDU (John Russell) (01/08/89)

In article <5632@cbmvax.UUCP> steveb@cbmvax.UUCP (Steve Beats) writes:
]If Exec ever gets its act together and starts
]using the MMU, your stack would be private memory.  If graphics attempted to
]access the RastPort (as a separate task through Intuition for instance) it 
]would cause an illegal access exception.  I would suggest you either:-
]
]a)	Allocate rastports using MEMF_PUBLIC
]b)	Allocate a new stack using MEMF_PUBLIC

Is that to say that having a rastport as a global variable will also cause
choking, due to possible non-MEMF_PUBLICness of data hunks? In that case
could a FixHunk-type program be constructed to remedy the problem?

What would be nice would be a "validation" version of Exec. I'll bet that
with very little effort a Kickstart could be made which would require you
to follow some of these rules, and yell at you if you didn't. Eg, do a
typeofmem on memory that was being accessed, and complain if it should be
MEMF_PUBLIC but wasn't. This would be just for testing purposes, and wouldn't
require the actual presence of the MMU/68020/32-bit ram etc, but would detect
stuff which would break on them.

John
-- 
"If you steal all money, kids not be able to BUY TOYS!"
			-- Saturday morning cartoon character explaining
			   why theft is bad

bryce@cbmvax.UUCP (Bryce Nesbitt) (01/08/89)

In article <10262@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>>>In article <5605> carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) writes:
>>>>Do not execute code on your stack or put system structures on your stack.
>>>
>>>	I occasionally put RastPorts on my stack; does that count?
>
>	AARRGGHHH!  What a bloody nuisance.  Throwing temproary RastPorts
>       around on the stack has been a real nice win for me....
 
The recommendation about putting system structures on the stack is on the right
track--but may be safely ignored for now.  There needs to be a comprehensive
document on surviving in an MMU world, but that line is not it.  Panic
changes will hurt more than help.

Most of that "Unsupported Programming Practices" document was
about fatal things that cause problems now, or will soon.  The stack
comment is a bit out of place, sorry.


Executing code on the stack, however, IS FORBIDDEN.
Self-modifying code IS VERY, VERY DANGEROUS.
Depending on the speed of the CPU is JUST PLAIN DUMB.


|\_/|  . ACK!, NAK!, EOT!, SOH!
{O o} .     Bryce Nesbitt
 (")        BIX: bnesbitt
  U	    USENET: cbmvax!bryce@uunet.uu.NET -or- rutgers!cbmvax!bryce
Disclaimer: I'm not an official, and this is not an official opinion.

jimm@amiga.UUCP (Jim Mackraz) (01/08/89)

In article <10262@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
)In article <5632@cbmvax.UUCP> steveb@cbmvax.UUCP (Steve Beats) writes:
)>In article <10227@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
)>>	I occasionally put RastPorts on my stack; does that count?
)>Yes that certainly does count.
)	AARRGGHHH!  What a bloody nuisance.

I think this is going a little far.  I think we have to divide the problems
up into what will break with what.  Most of the things Carolyn suggested are
things that will cause you problems real soon now, for sure.  There were things
that will break with any non-68000 processor, there were things that will
screw up with the data cache on an 030 or the instruction cache on an 020 or 030,
there were things that will break with new ROM revisions. 

These are all things we'll be seeing soon, if not already.

Now, down the future road, there is this dream of a protected task version
of the Amiga OS.

Let's face it, this isn't going to be a smooth transition.  I do not think that
anyone has compiled a list of the areas where we will find problems with
existing programs when and if we try this.  One thing is sure, tossing things
in MEMF_PUBLIC isn't going to be the only trick.  At least not until a big
list is made of everything that would require this.  Don't forget image planes,
sound samples, the name string of your child task, every gadget, your QBSBlit
entry points, your interrupt structures and data areas, and so on.  There are
probably more obvious ones that have never been listed.

It seems clear to me that moving to protected tasks on an Amiga will be an
evolutionary effort.  No existing program will work, I'd expect, so we'll need
to find a way to support the existing programming model side-by-side with new,
protected tasks.  At that time, there will be new rules and procedures for making
protected tasks.  Things like AddTask() (instead of a system CreateTask()) will
probably have to go, anyway, so there will probably be a whole new paradigm.

If we are to move beyond protection into separate, overlapping logical
address spaces for tasks, this whole "pointers to gadgets hanging off of
windows" and "linked lists of menu items" business has to go, anyway.

I strongly believe that a clear line should be drawn between practices which will
break real soon and those, such as the traditional MEMF_PUBLIC lip service,
which target some very long range, foggy future.

Now, if there are concrete, today type reasons why a rastport can't be on
a stack, perhaps I am missing them.  The key question would be whether anyone
might use the rastport asynchronously (i.e., not as your task), and then,
of course, whether the system tasks will ever be disallowed from using
memory on your stack.

My feeling is that until C-A gives the developers a list of exactly what it
will take to be a protected task, including exactly which functions might
use structures you provide to functions on a schedule other than your own,
it is not a positive step to scare people into tossing everything in the
world into MEMF_PUBLIC.

In the meantime, I put rastport structures on my stack all the time.  I love
doing it, it makes me hot.  Of course, I'm prepared to revise my programs
and issue a timely update to my registered users if:
1) I inadvertantly did something incompatible with a new OS release, or
2) I want to take advantage of major new features in a new OS release, or
3) I think they should all send me $25 more. ;^)

I don't like disagreeing with Steve in public like this, because it clouds
the fact that I take almost every other thing he says as Gospel.

Oh, yes, don't take this posting as a suggestion that the majority of
Carolyn's suggestions are not extremely important.  I'd like a little more
explanation about which of the suggestions are related to protected tasks,
and which are related to anticipated new processors, caches, and MMU usage.

Also, note well that my views do not represent Commodore's official policy.

	jimm

-- 
Jim Mackraz, I and I Computing	   	"Like you said when we crawled down
{cbmvax,well,oliveb}!amiga!jimm          from the trees: We're in transition."
							- Gang of Four
Opinions are my own.  Comments are not to be taken as Commodore official policy.

w-colinp@microsoft.UUCP (Colin Plumb) (01/08/89)

In article <10262@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
->> [In response to "allocating RastPorts on the stack is a Bad Idea]

->	AARRGGHHH!  What a bloody nuisance.  Throwing temproary RastPorts
->around on the stack has been a real nice win for me.  I've been doing things
->like this:
->
->	if (loadILBM() == SUCCESS) {
->		struct RastPort	lrp;
->
->		InitRastPort (&lrp);
->		lrp.BitMap = &loaded_bitmap;
->		ClipBlit (&lrp, 0L, 0L, &dest, 0L, 0L, w, h, MINTERM_COPY);
->	}

->	So now I have to do AllocMem()s with sanity checks with
->corresponding FreeMem()s?  Foo.

No; this usage should be safe.  If you're only making *library* calls using
the stack-allocated RaatPort, the only process that needs the data is
yours, so it can be MEMF_PRIVATE.  You only need MEMF_PUBLIC if passing
the RastPort to Intuition or some such.  But in this case, it's going to
be around for a while, so you probably allocate it anyway.
-- 
	-Colin (uunet!microsof!w-colinp)

cs161agc@sdcc10.ucsd.EDU (John Schultz) (01/09/89)

In article <84277@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes:
>Would OwnBlitter() work for this? I assume that the sequence :
>	Draw(...);
>	OwnBlitter();
>Can't possibly give you the Blitter before the Draw call has finished
>with it.
>--Chuck McManis

  Just do a WaitBlit().  OwnBlitter probably calls WaitBlit(),
then you'll also have to call DisownBlitter() before you call any
rom routines.
  For custom blitter stuff, I've always done:

    WaitBlit();
    OwnBlitter();
     // do custom blits
    DisownBlitter();


  Does OwnBlitter() actually call WaitBlit()? Or will it blow up if
OwnBlitter is called without first calling WaitBlit()?


  John Schultz

dale@boing.UUCP (Dale Luck) (01/09/89)

In article <2966@uhccux.uhcc.hawaii.edu> lee@uhccux.uhcc.hawaii.edu (Greg Lee) writes:
>From article <579@boing.UUCP>, by dale@boing.UUCP (Dale Luck):
>" You need to use WaitBlit().
>
>Judging from code in the 1.0 rom, you may need to use it twice.
>		Greg, lee@uhccux.uhcc.hawaii.edu

Pardon me? There is no such thing as a 1.0 rom.

It seems entirely silly to me to make programmers use WaitBlit twice
when WaitBlit already does the proper thing now.


-- 
Dale Luck     GfxBase/Boing, Inc.
{uunet!cbmvax|pyramid}!amiga!boing!dale

dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (01/09/89)

	Linear address space, Linear address space, Linear address space.

	A Linear address space is the only possible way to switch to a MMU
environ without rewriting the entire OS from scratch.  At least that way the 
trillions upon trillions of memory violations that will occur for the first
3 years can be made non-lethal...  as in "warning this is wrong but it'll
still run" type of thing, whereas with a non-linear address space you will
be forced to 'kill the task'.  That isn't the only reason of course, but it's
pretty big.

				-Matt

:Now, down the future road, there is this dream of a protected task version
:of the Amiga OS.
:It seems clear to me that moving to protected tasks on an Amiga will be an
:evolutionary effort.  No existing program will work, I'd expect, so we'll need
:to find a way to support the existing programming model side-by-side with new,
:protected tasks.  At that time, there will be new rules and procedures for making
:protected tasks.  Things like AddTask() (instead of a system CreateTask()) will
:probably have to go, anyway, so there will probably be a whole new paradigm.
:
>If we are to move beyond protection into separate, overlapping logical
:address spaces for tasks, this whole "pointers to gadgets hanging off of
:windows" and "linked lists of menu items" business has to go, anyway.
:
:I strongly believe that a clear line should be drawn between practices which will
:break real soon and those, such as the traditional MEMF_PUBLIC lip service,
:which target some very long range, foggy future.

	MEMF_PUBLIC will have to go completely ... as in be ignored completely.
Create a new MEMF_ flag for the purpose after figure out the specific 
guidelines.  Again, with a linear address space you can make everything work.
Consider the difficulty of writing a library otherwise?  Consider even 
attempting to rewrite the OS?  It just won't happen with distinct address
spaces, too much code relies on the linearity and damn it!  It is a thousand
times easier to write things for a linear address space!

	(I'm trying to drill this into people now so it'll get implemented
this way because I just *KNOW* that if it doesn't the Amiga will go down the
tubes!)

			-Matt

ewhac@well.UUCP (Leo L. Schwab) (01/09/89)

[ "Synthetic electronic sounds / Industrial rhythms all around." ]

	Okay.  Maybe I got a little excited at the prospect of not being
able to throw RastPorts on the stack anymore.

	However, I'd like it to be known that, if ever a protected version
of KickStart ever becomes available, I will happily revise my ways of
thinking, as well as my software, to comply with the new OS.

_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
Leo L. Schwab -- The Guy in The Cape	INET: well!ewhac@ucbvax.Berkeley.EDU
 \_ -_		Recumbent Bikes:	UUCP: pacbell > !{well,unicom}!ewhac
O----^o	      The Only Way To Fly.	      hplabs / (pronounced "AE-wack")
"Work FOR?  I don't work FOR anybody!  I'm just having fun."  -- The Doctor

rap@ardent.UUCP (Rob Peck) (01/10/89)

In article <586@boing.UUCP>, dale@boing.UUCP (Dale Luck) writes:
> In article <2966@uhccux.uhcc.hawaii.edu> lee@uhccux.uhcc.hawaii.edu (Greg Lee) writes:
> >From article <579@boing.UUCP>, by dale@boing.UUCP (Dale Luck):
> >" You need to use WaitBlit().
> >
> >Judging from code in the 1.0 rom, you may need to use it twice.
> >		Greg, lee@uhccux.uhcc.hawaii.edu
> 
> Pardon me? There is no such thing as a 1.0 rom.
> 
> It seems entirely silly to me to make programmers use WaitBlit twice
> when WaitBlit already does the proper thing now.

Dale - I think Greg was referring to the code samples in the 1.0
"RKM"... they are somewhat different from what we released finally
for 1.1 and following... in the 1.0 world, when I asked for a code
example for that, I was told (and documented it as such), that you
WOULD have to call WaitBlit() twice before you could be absolutely
sure the blitter had indeed finished (and folks, that WAS 1.0 and
evidently HAS since been fixed.).  Strangely enough, there ARE
still a few copies of the 1.0 RKM (I have one, of course) still
floating around and also strangely enough, some folks still refer
back to them for information (particularly about EXEC since there
were two different authors with entirely different ways of explaining
EXEC between the two editions -- and some internal details never quite
made the transition as I recall, to the new edition).

So anyway, a book-a-holic has obviously remembered (and found) the
reference to that original "requirement" which (thank goodness) no
longer exists.  

(An avowed book-a-holic myself...Wink-wink-nudge-nudge-know-what-ah-mean  :-).

Rob Peck

rokicki@polya.Stanford.EDU (Tomas G. Rokicki) (01/10/89)

> Does OwnBlitter() actually call WaitBlit()? Or will it blow up if
> OwnBlitter is called without first calling WaitBlit()?

OwnBlitter() doesn't call WaitBlit().  Also, OwnBlitter(); WaitBlit();
should be very marginally faster than WaitBlit(); OwnBlitter() since
in the previous step, the blitter can still run during the OwnBlitter()
call.  OwnBlitter() just says ``don't let anyone else start a blit,
'cause I'm gonna be using it just as soon as I do a WaitBlit().''
As a matter of fact, WaitBlit(); OwnBlitter() isn't any good, since
someone might sneak in and start a blit after your WaitBlit() returns
and before you OwnBlitter() . . . you start mucking with the registers
then, and all hell breaks loose.

(Please note that `loose' rhymes with noose and `lose' rhymes with
shoes.  You seldom loose a game or cut lose.  I've seen these two
words misused too much here and on BIX . . .  No connection to the
above posting.)                                              -tom

abbadon@nuchat.UUCP (David Neal) (01/10/89)

In article <3237@amiga.UUCP> jimm@cloyd.UUCP (Jim Mackraz) writes:
>In article <10262@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>)In article <5632@cbmvax.UUCP> steveb@cbmvax.UUCP (Steve Beats) writes:
>)>In article <10227@well.UUCP> ewhac@well.UUCP (Leo 'Bols Ewhac' Schwab) writes:
>)>>	I occasionally put RastPorts on my stack; does that count?
>)>Yes that certainly does count.
>)	AARRGGHHH!  What a bloody nuisance.
>
>I think this is going a little far.  I think we have to divide the problems
>up into what will break with what.  Most of the things Carolyn suggested are
>things that will cause you problems real soon now, for sure.  There were things
>that will break with any non-68000 processor, there were things that will
>screw up with the data cache on an 030 or the instruction cache on an 020 or 030,
>there were things that will break with new ROM revisions. 

Ahem.

The discussion so far seems to revolve around a very
simple view of memory protection. (No insult intended)

Why can't we have MEMF_USER, MEMF_SUPERVISOR, MEMF_EXECUTIVE,
and MEMF_KERNAL?

Seems like intuition running in SUPERVISOR or EXECUTIVE mode
could ask the o.s. to page in the user's rastport and away
you go. 

I don't know about the 68851, but even the venerable vax
has this. I've even written a couple of programs to play
with OTHER users stacks on the vax, so if a 68k analog
exists, this sounds like the solution.

(It's obvious that all user programs would be MEMF_USER
 unless specified otherwise, thus protecting seperate
 tasks from each other, right?)


Just slap me around and pack me off to comp.arch if my 
brain-aid batteries have run down again.


David Neal
nuchat!abbadon@killer

dale@boing.UUCP (Dale Luck) (01/10/89)

In article  (John Schultz) writes:
>
>  Just do a WaitBlit().  OwnBlitter probably calls WaitBlit(),

Nope, it does nothing with WaitBlit

>then you'll also have to call DisownBlitter() before you call any
>rom routines.

True, but only if those routines will use the blitter.
In general it is a bad idea to be owning the blitter while doing
unrelated things.

>  For custom blitter stuff, I've always done:
>    WaitBlit();
>    OwnBlitter();
>     // do custom blits
>    DisownBlitter();

Nope, this may typically work but wont work under stress. Some other
task can get in between the WaitBlit and OwnBlitter resulting in
a busy Blitter.
After OwnBlitter you need to do a WaitBlit before accessing the
custom chip registers.
All OwnBlitter does is guarentee that no one else will use the blitter
once OwnBlitter returns and before you call DisownBlitter. It has
nothing to do with the current operation status of the blitter.

>
>  John Schultz


-- 
Dale Luck     GfxBase/Boing, Inc.
{uunet!cbmvax|pyramid}!amiga!boing!dale

lee@uhccux.uhcc.hawaii.edu (Greg Lee) (01/10/89)

From article <1425@ardent.UUCP>, by rap@ardent.UUCP (Rob Peck):
" ...
" Dale - I think Greg was referring to the code samples in the 1.0
""RKM"...

Apparently it's academic, but I was referring to the code in
the 1.0 operating system.  When WaitBlit() is [was] called,
it is called twice.  (I disassembled the code.)
		Greg, lee@uhccux.uhcc.hawaii.edu

chad@cup.portal.com (Chad The-Walrus Netzer) (01/11/89)

In a previous article,(Tomas Rokiki) sure plays a mean pinball...
Oops, I mean, writes:
)> Does OwnBlitter() actually call WaitBlit()? Or will it blow up if
)> OwnBlitter is called without first calling WaitBlit()?
)OwnBlitter() doesn't call WaitBlit().  Also, OwnBlitter(); WaitBlit();
)should be very marginally faster than WaitBlit(); OwnBlitter() since
)in the previous step, the blitter can still run during the OwnBlitter()
)call.
    This is the reason why you SHOULD use OwnBlitter() first.
)As a matter of fact, WaitBlit(); OwnBlitter() isn't any good, since
)someone might sneak in and start a blit after your WaitBlit() returns
)and before you OwnBlitter() . . . you start mucking with the registers
)then, and all hell breaks loose.
    This is the reason why you MUST use OwnBlitter() first!  The order of the
calls is always:
	1) OwnBlitter();
	2) WaitBlit();
    ...assuming you want to do your own mucking around with the blitter.  Of
course, in some instances you may want to call only WaitBlit() by itself, or
only OwnBlitter() by itself, although the first case is probably rare, and the
second case is even rarer.
    In general, when doing your own Blitter manipulations, you should do all
your calculations for the Blitter registers, get control of the Blitter (via
OwnBlitter(), then WaitBlit()), stuff the registers with you're values as
quickly as possible, start the blit (by filling the size register last), and
DisownBlitter() right away.  If you need to read the BZERO flag in DMACONR,
then do a WaitBlit() and copy the register value somewhere before the
DisownBlitter() call.
    Doing all this will not only make the Blitter routine work correctly, it
will also make it efficient.  Remember, Be Kind to Your Blitter!
    BTW,  Thanks for sending me the latest BlitLab, Tom.  All us Blitter
Hackers appreciate it!

)(Please note that `loose' rhymes with noose and `lose' rhymes with
)shoes.  You seldom loose a game or cut lose.  I've seen these two
)words misused too much here and on BIX . . .  No connection to the
)above posting.)                                              -tom
    And of course, these conventions are officially supported by Commodore.
Any deviation from these conventions in user documentation will not be
supported, and will probably break your users brain!  Please do not use these
Unsupported Grammer Conventions!  No connection to the above poosting...
errr, that should read posting.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				Chad 'The_Walrus' Netzer -> AmigaManiac++
"I'm "first in" at the LIFO race of life..."

wayneck@tekig5.PEN.TEK.COM (Wayne Knapp) (01/13/89)

In article <13389@cup.portal.com>, chad@cup.portal.com (Chad The-Walrus Netzer) writes:
.     This is the reason why you MUST use OwnBlitter() first!  The order of the
. calls is always:
. 	1) OwnBlitter();
. 	2) WaitBlit();
.     ...assuming you want to do your own mucking around with the blitter.  Of
. course, in some instances you may want to call only WaitBlit() by itself, or
. only OwnBlitter() by itself, although the first case is probably rare, and the
. second case is even rarer.
.     In general, when doing your own Blitter manipulations, you should do all
. your calculations for the Blitter registers, get control of the Blitter (via
. OwnBlitter(), then WaitBlit()), stuff the registers with you're values as
. quickly as possible, start the blit (by filling the size register last), and
. DisownBlitter() right away.  If you need to read the BZERO flag in DMACONR,
. then do a WaitBlit() and copy the register value somewhere before the
. DisownBlitter() call.
.     Doing all this will not only make the Blitter routine work correctly, it
. will also make it efficient.  Remember, Be Kind to Your Blitter!

Actually I prefer:
           
          MyBlitRoutine( ...)
            ...
          { 
               OwnBlitter();
               Compute blitter register values  /* let Blitter still run */ 
               WaitBlit();
               set blitter registers.
               DisownBlitter();
          }

One main point to remember is that very few ROM-kernal routines work between
the OwnBlitter and DisownBlitter() calls.

                                       Wayne Knapp 

cs161agc@sdcc10.ucsd.EDU (John Schultz) (01/14/89)

[earlier I posted:]
>>  For custom blitter stuff, I've always done:
>>    WaitBlit();
>>    OwnBlitter();
>>     // do custom blits
>>    DisownBlitter();

  After checking my code, I've been doing it correctly, as in

    OwnBlitter();
    // pre-compute registers
    WaitBlit();
    // write to custom registers
    DisownBlitter();

  I got the skeleton code from a Thomas Rokiki [uh oh, did I spell
it right?] custom blitter example. Thanks Tom. 
Is this legal for 1.4?


  John Schultz

ali@polya.Stanford.EDU (Ali T. Ozer) (01/16/89)

In article <47@sdcc10.ucsd.EDU> John Schultz writes:
>  I got the skeleton code from a Thomas Rokiki [uh oh, did I spell
>it right?] custom blitter example. 

Tom's name should get an award for being one of the most widely
abused names around. 8-) It's Tomas Rokicki!

Of course, Jim Mackraz's name isn't much better...

Ali 

dale@boing.UUCP (Dale Luck) (01/18/89)

In article  wayneck@tekig5.PEN.TEK.COM (Wayne Knapp) writes:
>          MyBlitRoutine( ...)
>          { 
>               OwnBlitter();
>               Compute blitter register values  /* let Blitter still run */ 
>               WaitBlit();
>               set blitter registers.
>               DisownBlitter();
>          }
>                                       Wayne Knapp 

In general we try to minimize the time we Own the Blitter, it is a
scarce but often used resource.
Nearly all the amiga graphics routines do something similar to this.

{
	Compute blitter register values
	OwnBlitter
	WaitBlit
	set blitter registers
	DisownBlitter
}
In a multiplane blit we use:
{
	Computer blitter registers that do not change between planes
		such as modulos, blitsize, bltconx's, fw/lwmask, etc.
	OwnBlitter
	WaitBlit
	load non changing blit registers
	for each plane to blit
		compute new changing blit registers such as ptrs to
			bitplanes
		WaitBlit
		load registers that need to be reloaded per blit.
		zap bltsize (starts the blit)
	endforeach
	DisownBlitter
}



-- 
Dale Luck     GfxBase/Boing, Inc.
{uunet!cbmvax|pyramid}!amiga!boing!dale