Click Here
home features news forums classifieds faqs links search
6071 members 
Amiga Q&A /  Free for All /  Emulation /  Gaming / (Latest Posts)
Login

Nickname

Password

Lost Password?

Don't have an account yet?
Register now!

Support Amigaworld.net
Your support is needed and is appreciated as Amigaworld.net is primarily dependent upon the support of its users.
Donate

Menu
Main sections
» Home
» Features
» News
» Forums
» Classifieds
» Links
» Downloads
Extras
» OS4 Zone
» IRC Network
» AmigaWorld Radio
» Newsfeed
» Top Members
» Amiga Dealers
Information
» About Us
» FAQs
» Advertise
» Polls
» Terms of Service
» Search

IRC Channel
Server: irc.amigaworld.net
Ports: 1024,5555, 6665-6669
SSL port: 6697
Channel: #Amigaworld
Channel Policy and Guidelines

Who's Online
15 crawler(s) on-line.
 135 guest(s) on-line.
 0 member(s) on-line.



You are an anonymous user.
Register Now!
 Gunnar:  28 mins ago
 pixie:  47 mins ago
 DiscreetFX:  1 hr 27 mins ago
 DWolfman:  1 hr 36 mins ago
 cncparts:  3 hrs 9 mins ago
 saipaman4366:  3 hrs 55 mins ago
 Beajar:  4 hrs 15 mins ago
 Rob:  4 hrs 17 mins ago
 agami:  5 hrs 20 mins ago
 RobertB:  5 hrs 40 mins ago

/  Forum Index
   /  Classic Amiga Software
      /  What are the use cases for Forbid/Permit ?
Register To Post

Goto page ( 1 | 2 | 3 | 4 Next Page )
PosterThread
Mobileconnect 
What are the use cases for Forbid/Permit ?
Posted on 22-Oct-2021 18:10:08
#1 ]
Regular Member
Joined: 13-Jun-2003
Posts: 478
From: Unknown

Apart from stopping multitasking completely so one can take full control of the system, what are the 'valid' use cases that require one to call Forbid and Permit? yes I know the answer is "there aren't any" but once upon a time people thought there were and used and abused them.

If we can identify all the possible reasons (surely there can't be more than 4 or 5) why developers did it, then we can implement workarounds that mean we can change Forbid to not actually stop multitasking, or to timeout if Permit isn't called fast enough, while still allowing the process to do what it thinks it needs to use Forbid to be able to do.

_________________

 Status: Offline
Profile     Report this post  
NutsAboutAmiga 
Re: What are the use cases for Forbid/Permit ?
Posted on 22-Oct-2021 18:19:04
#2 ]
Elite Member
Joined: 9-Jun-2004
Posts: 12795
From: Norway

@Mobileconnect

1) Take over the computer, disable any resource that’s needs CPU cycles in the background, when playing console games. on 7mhz Amiga it made sense, once upon a time.

2) It’s used as global mutex to protect list structures, so your not reading a record being modified, or change something while some task is reading it.
(Horrible use case..)

3) It’s used to when you send messages to program, it prevents program from closing while your find a message port, or while sending the message to it.
(freeze things in time, horrible implementation.)

Disable / Forbid, is also used for timing critical stuff, I had disable interrupts, while initializing the catweasel mk4, to upload the firmware to PCI card, if not the upload failed.

Last edited by NutsAboutAmiga on 23-Oct-2021 at 09:55 AM.
Last edited by NutsAboutAmiga on 23-Oct-2021 at 09:54 AM.
Last edited by NutsAboutAmiga on 22-Oct-2021 at 07:31 PM.
Last edited by NutsAboutAmiga on 22-Oct-2021 at 06:36 PM.
Last edited by NutsAboutAmiga on 22-Oct-2021 at 06:22 PM.

_________________
http://lifeofliveforit.blogspot.no/
Facebook::LiveForIt Software for AmigaOS

 Status: Offline
Profile     Report this post  
Mobileconnect 
Re: What are the use cases for Forbid/Permit ?
Posted on 22-Oct-2021 18:57:09
#3 ]
Regular Member
Joined: 13-Jun-2003
Posts: 478
From: Unknown

@NutsAboutAmiga

I thought so. So with a bit of outside the box thinking, these use cases could be accounted for by the system to prevent them being problematic.

Take the 3rd case for example - if messageports are not immediately deleted when disposed of, but instead a 'soft delete' is used by which i mean they become no longer valid for receiving new messages, and 'ownership' is transferred from the creating process, to the exec, then exec can safely receive new messages on those ports and simply ignore them or respond to them itself with a 'this port has gone away now' error. It could then run a garbage collection every few minutes where it closes and frees message ports that it owns that haven't received any new messages for a while.

A lot more resources can also be managed this way, DOS files, intuition objects etc. - if the system philosophy is changed from 'the process owns its own resources' to 'the operating system owns all resources, and user processes are only granted leases on those resources'.

When you open a file, DOS opens the file, and then creates an entry in a private open files table that creates a proxy resource handle and returns that instead, as well as a reference count on the resource, and a process/task ID. If you use that file handle pointer with DOS functions then it knows to always swap that for it's own real handle. If you try to use the file handle directly in illegal ways, garbage happens for your process because it's not really a valid file handle, but that's fine because the OS integrity is preserved. A garbage collector can spot that the process/task ID has died, and free the resource without risk that the handle will get used. Pass a handle to another process directly? It's treated as invalid if used by the incorrect process, unless some specific 'transfer my resource' API is called first.

For the second case, the definition of Forbid could be changed from "prevent multitasking" to "this process is going to do something funky so put a semaphore in place that wrote locks all system lists for the next fraction of a second and times out if Permit is not called in time". Maybe then exiting the naughty process with a 'didn't call Permit fast enough' error.

If combined with implementing a client server system like above, whereby a user process never actually gets pointers to the operating system's real resources, but only actually to 'proxy' resource handles which are unique to that process, then the damage it can do is limited.

_________________

 Status: Offline
Profile     Report this post  
NutsAboutAmiga 
Re: What are the use cases for Forbid/Permit ?
Posted on 22-Oct-2021 19:39:35
#4 ]
Elite Member
Joined: 9-Jun-2004
Posts: 12795
From: Norway

@Mobileconnect

I suggest let old crap be, old program like it just the way they are.

instead old message ports, create new message port for new programs, that is forbid free.
the new message port, will have function like


// an atomic function (Exec is responsible for making it atomic.)
// (locks should also record the task that has the obtains.)

lock = ObtaionXPortLock( “Name” );
if (lock)
{
// using the lock makes it impossible to send a message unless you have a lock
Success = SendXPort( lock, msg ); // Fail if program has crashed or is frozen..
ReleaseXPort( lock );
}


and you should not be able to delete XPort until obtains are released.

as more of OS, and programs are updated, the less of issue this gets.

Last edited by NutsAboutAmiga on 23-Oct-2021 at 09:58 AM.
Last edited by NutsAboutAmiga on 22-Oct-2021 at 08:30 PM.
Last edited by NutsAboutAmiga on 22-Oct-2021 at 07:58 PM.
Last edited by NutsAboutAmiga on 22-Oct-2021 at 07:50 PM.
Last edited by NutsAboutAmiga on 22-Oct-2021 at 07:48 PM.
Last edited by NutsAboutAmiga on 22-Oct-2021 at 07:43 PM.
Last edited by NutsAboutAmiga on 22-Oct-2021 at 07:40 PM.

_________________
http://lifeofliveforit.blogspot.no/
Facebook::LiveForIt Software for AmigaOS

 Status: Offline
Profile     Report this post  
tonyw 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 9:32:20
#5 ]
Elite Member
Joined: 8-Mar-2003
Posts: 3240
From: Sydney (of course)

@NutsAboutAmiga

One big problem is that most uses for Forbid/Permit are simply to protect critical areas of code. Years ago, it was the only way they had to prevent other programs from interfering with buffers and pointers while they were using them.

There are still 460-odd files in OS4 that use Forbid/Permit. If we were to change every call to use Semaphores or Mutexes, it would take forever to change them all and test it properly. And that wouldn't change any of the dynosaur^h^h^h^h^h^h^h^h legacy software that we are so keen to preserve.

I would like to see Forbid() changed to mean "Don't let anyone else past here until I say 'Permit()'", but it's easy to think of ways it could be broken. It's like the single memory space idea: it was a good idea back in 1984, but these days it is a damned nuisance having to support it.

Last edited by tonyw on 23-Oct-2021 at 09:34 AM.
Last edited by tonyw on 23-Oct-2021 at 09:33 AM.

_________________
cheers
tony

Hyperion Support Forum: http://forum.hyperion-entertainment.biz/index.php

 Status: Offline
Profile     Report this post  
NutsAboutAmiga 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 9:53:01
#6 ]
Elite Member
Joined: 9-Jun-2004
Posts: 12795
From: Norway

@tonyw

Quote:
I would like to see Forbid() changed to mean "Don't let anyone else past here until I say 'Permit()'", but it's easy to think of ways it could be broken. It's like the single memory space idea: it was a good idea back in 1984, but these days it is a damned nuisance having to support it.


I agree that be kind of nice, but case 3, will not work as then program your trying to send message to program that has quit’ed, and then you send message into limbo.

Basically we are stuck with it.
I’m sure some cases in device drivers too, SendIO, DoIO stuff.

_________________
http://lifeofliveforit.blogspot.no/
Facebook::LiveForIt Software for AmigaOS

 Status: Offline
Profile     Report this post  
Hedeon 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 10:08:51
#7 ]
New Member
Joined: 23-May-2016
Posts: 8
From: Unknown

@Mobileconnect

Aren't you confusing this with Enable/Disable? Interrupts still occur after Forbid(). Only task scheduling is stopped. At least according to the docs.

Nevermind. I see you said multitasking. I see interrupts in another post below and got confused 🤔

Last edited by Hedeon on 23-Oct-2021 at 10:11 AM.
Last edited by Hedeon on 23-Oct-2021 at 10:11 AM.

 Status: Offline
Profile     Report this post  
Mobileconnect 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 10:09:29
#8 ]
Regular Member
Joined: 13-Jun-2003
Posts: 478
From: Unknown

@ both thanks for the input.

One of the assumptions we have is that all code is treated equal on Amiga. I think this is also an assumption we can and should change. If it was deigned that only certain types of binaries could access certain functions e.g. only device drivers and whitelisted operating system components then one could still keep all those Forbids that are a pain to remove, whilst putting the less well tested and less well programmed world of third party software into an 'untrusted' domain.

This isn't new - the JIT blacklist already exists for similar reasons. If I were architect of OS4 or 5 or whatever, I would do it this way:
1) For 68K binaries NOT running in a UAE sandbox, Forbid is allowed but does not actually prevent multitasking as per some of the ideas I put above.
2) For OS4 powerPC binaries not 'trusted' parts of the OS, deny them the right to use Forbid completely - for the few if any independent OS4 native apps that use this, we assume the author is still alive to make the necessary changes if they really want.
3) For OS4 powerPC binaries that are part of the OS, their checksum is compared against a table of known-good versions before they are loaded otherwise the user receives a warning. Yes the table could be altered but as with all things Amiga, we trust the user to have full control over their system. These binaries can do things that are considered illegal for third parties to do as per rule 2

I know we don't have signed binaries and a secure seg loader. It's not needed for this, that's not the problem I'm trying to solve. I'm trying to solve the problem of system stability in a world with common address space and all software given equal ability to bring down the system.

Another approach could be to scan a binary on first load and if it appears to be calling Forbid at any point, then the user is prompted to suggest the app only run inside a UAE sandbox. This choice then saved in a tooltype, and the Workbench would choose to load the app inside a UAE environment just like RunInUAE enables. Maybe it's a workbench only feature so if you really want to bypass it you can run from a shell.

Last edited by Mobileconnect on 23-Oct-2021 at 10:10 AM.

_________________

 Status: Offline
Profile     Report this post  
kamelito 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 12:32:05
#9 ]
Cult Member
Joined: 26-Jul-2004
Posts: 813
From: Unknown

@tonyw

Why not just use semaphores/mutex by redirecting Forbud()/Permit() calls to theses functions instead?
Automation testing should take care of regressions.

 Status: Offline
Profile     Report this post  
NutsAboutAmiga 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 12:51:09
#10 ]
Elite Member
Joined: 9-Jun-2004
Posts: 12795
From: Norway

@kamelito

it does solve cases like

Forbid()
task = FindTask("Clock");
if (task)
{
........
}
Permit();

if forbid() does stop the Clock task, it can quit... while reading / writing to message ports or tasks, this Find#?() functions, are not SMP friendly. the OS does not know if someone is reading the task struct or doing anything with the message port.

I'm sure there other cases as well.

Last edited by NutsAboutAmiga on 23-Oct-2021 at 01:14 PM.
Last edited by NutsAboutAmiga on 23-Oct-2021 at 12:55 PM.
Last edited by NutsAboutAmiga on 23-Oct-2021 at 12:53 PM.

_________________
http://lifeofliveforit.blogspot.no/
Facebook::LiveForIt Software for AmigaOS

 Status: Offline
Profile     Report this post  
Georg 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 13:18:41
#11 ]
Regular Member
Joined: 14-May-2003
Posts: 451
From: Unknown

"AmiWest 2021 Day 1 Live Stream" video on YouTube at time 7:07:20 talks about being surprised that programs do Wait() after a Forbid(). I'm surprised such standard stuff is surprising to Exec(SG) developers ...

 Status: Offline
Profile     Report this post  
NutsAboutAmiga 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 14:42:59
#12 ]
Elite Member
Joined: 9-Jun-2004
Posts: 12795
From: Norway

@Georg

That’s not standard, if in forbid nothing should be able signal the task.
(But some function can break forbid, thats also true)

Last edited by NutsAboutAmiga on 23-Oct-2021 at 02:44 PM.

_________________
http://lifeofliveforit.blogspot.no/
Facebook::LiveForIt Software for AmigaOS

 Status: Offline
Profile     Report this post  
Mobileconnect 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 15:16:14
#13 ]
Regular Member
Joined: 13-Jun-2003
Posts: 478
From: Unknown

All problems with writing to structure directly that might disappear while you're using it, can be eliminated by soft-deleting structures

In old days, we have small RAM, you want to free RAM as soon as you're finished with it and use it for something else. These days we have lots of RAM, even simple Amiga user probably has 10MB, any power user surely has 64MB+. So all these small allocations are inefficient to keep freeing, it leads to fragmentation.

A MUCH better idea is this: Exec, DOS, Intuition preallocates good numbers of objects of all kinds - file handles, message ports etc. I know we are not an object oriented OS but these are objects for all intents and purposes, they just predate C++ so they are all structs.

When a program wants one of these, it is allocated a clean one from the existing pool. When it is finished with it, exec marks it as dirty, but does NOT delete it. Then, any late attempts to access that memory or even write to it, have no effect, as the memory is just sitting there unused by anything else. Eventually after enough time has passed, the object can be recycled.

P.S. this is basically how NT Kernel object manager does it.

Last edited by Mobileconnect on 23-Oct-2021 at 03:17 PM.

_________________

 Status: Offline
Profile     Report this post  
Georg 
Re: What are the use cases for Forbid/Permit ?
Posted on 23-Oct-2021 15:32:43
#14 ]
Regular Member
Joined: 14-May-2003
Posts: 451
From: Unknown

@NutsAboutAmiga

For example sample code on Amiga Dev CD for ARexx stuff does:

Forbid();

if(RexxPort = FindPort(RXSDIR))
{
PutMsg(RexxPort,RexxMsg);

WaitPort(ReplyPort);
GetMsg(ReplyPort);

Error = 0;
}
else
Error = ERROR_OBJECT_NOT_FOUND;

Permit();

 Status: Offline
Profile     Report this post  
matthey 
Re: What are the use cases for Forbid/Permit ?
Posted on 24-Oct-2021 2:45:05
#15 ]
Super Member
Joined: 14-Mar-2007
Posts: 1968
From: Kansas

tonyw Quote:

One big problem is that most uses for Forbid/Permit are simply to protect critical areas of code. Years ago, it was the only way they had to prevent other programs from interfering with buffers and pointers while they were using them.


"Years ago" like 1979 when the 68000 was released? The 68000 had only TAS as a non-blocking atomic instruction and it was fairly weak. The Amiga developers chose to use a memory optimization for the Amiga chipset instead of supporting TAS in chip memory. This didn't seem to be a bad tradeoff for losing a weak atomic instruction for a uniprocessor system. The IBM System\370, first released in 1970, had introduced a more useful CAS instruction which was introduced to the 68020 in 1984, before the Amiga was released but perhaps too late to change even if they wanted to. Even PCs with advanced hardware like the Amiga were likely to be uniprocessor systems for many years.

https://en.wikipedia.org/wiki/Compare-and-swap Quote:

CAS, and other atomic instructions, are sometimes thought to be unnecessary in uniprocessor systems, because the atomicity of any sequence of instructions can be achieved by disabling interrupts while executing it. However, disabling interrupts has numerous downsides. For example, code that is allowed to do so must be trusted not to be malicious and monopolize the CPU, as well as to be correct and not accidentally hang the machine in an infinite loop or page fault. Further, disabling interrupts is often deemed too expensive to be practical. Thus, even programs only intended to run on uniprocessor machines will benefit from atomic instructions, as in the case of Linux's futexes.

In multiprocessor systems, it is usually impossible to disable interrupts on all processors at the same time. Even if it were possible, two or more processors could be attempting to access the same semaphore's memory at the same time, and thus atomicity would not be achieved. The compare-and-swap instruction allows any processor to atomically test and modify a memory location, preventing such multiple-processor collisions.

On server-grade multi-processor architectures of the 2010s, compare-and-swap is cheap relative to a simple load that is not served from cache. A 2013 paper points out that a CAS is only 1.15 times more expensive than a non-cached load on Intel Xeon (Westmere-EX) and 1.35 times on AMD Opteron (Magny-Cours).

...

As of 2013, most multiprocessor architectures support CAS in hardware, and the compare-and-swap operation is the most popular synchronization primitive for implementing both lock-based and non-blocking concurrent data structures.


The 68020 received not only CAS but CAS2 which is nice for doubly linked lists like the AmigaOS uses.
There were multiprocessor systems, the predecessor to multicore which used these instructions effectively and efficiently as the following paper reports.

A Lock-Free Multiprocessor OS Kernel
https://cs.uwaterloo.ca/~brecht/servers/readings-new/massalin91lockfree.pdf

Perhaps the original Amiga developers made a judgement error.

tonyw Quote:

There are still 460-odd files in OS4 that use Forbid/Permit. If we were to change every call to use Semaphores or Mutexes, it would take forever to change them all and test it properly. And that wouldn't change any of the dynosaur^h^h^h^h^h^h^h^h legacy software that we are so keen to preserve.


Then the AmigaOS 4 developers likely made another judgement error.

Hypex Quote:

I think it would have been better to handle this when porting OS4 began.


Indeed, AmigaOS 4 doesn't really seem like a next generation desktop OS but rather a cheap port to PPC with some eye candy added and perhaps fraudulent promises of SMP to enhance sales which were still quite poor. The 68k could have been sandboxed but mistakes were repeated instead despite a much clearer picture of multiprocessing by this time. Of course it would be a tremendous amount of work to remove and replace so many forbids, especially for so few PPC AmigaOS 4 users, but SMP will always have an efficiency handicap without it. Still, you are correct that we do want to preserve legacy software compatibility by supporting forbid and disable kludges in as efficient and compatible of way as possible.

The code reaching a Forbid() or Disable() can be stopped for some time before entering the restricted code section. The forbid function could AddTail() to a global queue nodes of cores reaching a Forbid() or Disable() and then would spin or wait for a signal that all other cores are waiting (not running tasks). When all cores are no longer running, the first core in the queue will signal that it is running, disable interrupts if a Disable(), execute the critical code section, Reenable interrupts if Disable(), remove the node entry from the queue, signal that it is waiting and spin or wait until the queue is empty. The next entry in the queue will follow until there are no more entries and all cores can continue regular execution. The advantage here is that multiple forbids and disables on different cores can be run while the cores are stopped.

Rather than stopping all running cores immediately, wait for the task switch timer to interrupt and then check if the global queue of waiting forbids and permits is empty and spin or wait if it is not. Every core will stop eventually when there is a pending forbid or disable in the queue. This has lower overhead than stopping the running cores immediately after a core has encountered a Forbid or Permit and flushing write buffers using memory barriers (sync, eieio/mbar, msync) which may happen anyway on a context/task switch.

I believe my idea for handling Forbid() and Permit() would be pretty simple and easy to try. There would be multicore arbitration needed for adding nodes to the queue and for the mask of cores waiting/spinning. The nodes for the forbid queue should probably be embedded in a core context structure for each core so they don't have to be dynamically allocated. This is probably about as good as it gets to handle Forbid() and Disable() without hardware help.

Last edited by matthey on 24-Oct-2021 at 02:50 AM.

 Status: Offline
Profile     Report this post  
OneTimer1 
Re: What are the use cases for Forbid/Permit ?
Posted on 24-Oct-2021 12:39:52
#16 ]
Cult Member
Joined: 3-Aug-2015
Posts: 962
From: Unknown

@NutsAboutAmiga

Quote:


2) It’s used as global mutex to protect list structures, so your not reading a record being modified, or change something while some task is reading it.
(Horrible use case..)


But absolute important.

If your task access system lists you should always protect it with Forbid/Permit.

Necessary when

- Opening or changing a window or screen.
- Accessing hardware resources for audio

 Status: Offline
Profile     Report this post  
Mobileconnect 
Re: What are the use cases for Forbid/Permit ?
Posted on 24-Oct-2021 14:29:14
#17 ]
Regular Member
Joined: 13-Jun-2003
Posts: 478
From: Unknown

@matthey

Quote:
Indeed, AmigaOS 4 doesn't really seem like a next generation desktop OS but rather a cheap port to PPC with some eye candy added


No different from Mac OS 9 in that respect. As you and others observe, As DOS->NT and MacOS9->OSX requires a complete break with the past, with the past supported only through sandbox based emulation.

My point is how can we make current gen AmigaOS more robust, in the absence of a next generation successor to Amiga (of which Haiku is probably the closest one will ever get).

_________________

 Status: Offline
Profile     Report this post  
NutsAboutAmiga 
Re: What are the use cases for Forbid/Permit ?
Posted on 24-Oct-2021 16:50:49
#18 ]
Elite Member
Joined: 9-Jun-2004
Posts: 12795
From: Norway

@Mobileconnect

Need to gradually do it, get people update software, then when lot of software is playing nice, you do it, but you can’t do over night and expect everything to work like that.

What can be do is do virtualization thing, where the OS exists with in another OS, but that is lot of work, WarpOS recreated few times now for example.

Last edited by NutsAboutAmiga on 24-Oct-2021 at 04:53 PM.

_________________
http://lifeofliveforit.blogspot.no/
Facebook::LiveForIt Software for AmigaOS

 Status: Offline
Profile     Report this post  
OneTimer1 
Re: What are the use cases for Forbid/Permit ?
Posted on 24-Oct-2021 18:00:30
#19 ]
Cult Member
Joined: 3-Aug-2015
Posts: 962
From: Unknown

@Mobileconnect

Quote:

Mobileconnect wrote:
… how can we make current gen AmigaOS more robust, ..



You can't do anything, you would need the source code of AOS4 to make some changes.

Well, to be honest, there is a Amiga like OS where you can have the source, so if you really want to do something go to AROS.

 Status: Offline
Profile     Report this post  
ppcamiga1 
Re: What are the use cases for Forbid/Permit ?
Posted on 24-Oct-2021 18:16:50
#20 ]
Cult Member
Joined: 23-Aug-2015
Posts: 762
From: Unknown

@Mobileconnect

Yes Amiga OS 4 and MOS are something like Mac Os 9.
Port to faster hardware, binary and source compatible.

No haiku aros x86/arm or any other crap.
New Amiga NG (NG 2.0) should be just Amiga gui and graphics on top of unix.
Open source, hardware agnostic.
Something like Mac Os X.

 Status: Offline
Profile     Report this post  
Goto page ( 1 | 2 | 3 | 4 Next Page )

[ home ][ about us ][ privacy ] [ forums ][ classifieds ] [ links ][ news archive ] [ link to us ][ user account ]
Copyright (C) 2000 - 2019 Amigaworld.net.
Amigaworld.net was originally founded by David Doyle