diff --git a/arch/m68k-amiga/hidd/gayle_ata/bus_class.h b/arch/m68k-amiga/hidd/gayle_ata/bus_class.h index e2e1def4e6d..62eed1b9d87 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/bus_class.h +++ b/arch/m68k-amiga/hidd/gayle_ata/bus_class.h @@ -9,6 +9,7 @@ struct ata_ProbedBus UBYTE *altport; UBYTE *gayleirqbase; BOOL a4000; + BOOL a500; UBYTE doubler; }; @@ -22,6 +23,7 @@ struct ATA_BusData UBYTE *gayleirqbase; UBYTE *gayleintbase; BOOL ideintadded; + BOOL a500; }; struct ataBase diff --git a/arch/m68k-amiga/hidd/gayle_ata/gayleata_busclass.c b/arch/m68k-amiga/hidd/gayle_ata/gayleata_busclass.c index 71bc4d2cd71..9a16029c7db 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/gayleata_busclass.c +++ b/arch/m68k-amiga/hidd/gayle_ata/gayleata_busclass.c @@ -1,5 +1,5 @@ /* - Copyright © 2013-2020, The AROS Development Team. All rights reserved. + Copyright © 2013-2020, The AROS Development Team. All rights reserved. $Id$ Desc: A600/A1200/A4000 ATA HIDD @@ -57,12 +57,21 @@ static BOOL ata_CreateGayleInterrupt(struct ATA_BusData *bus, UBYTE num) { struct Interrupt *irq = &bus->ideint; - bus->gayleintbase = (UBYTE*)GAYLE_INT_1200; - irq->is_Code = (APTR)IDE_Handler_A1200; - + if(bus->a500) + { + bus->gayleintbase = (UBYTE*)GAYLE_INT_500; + } + else + { + bus->gayleintbase = (UBYTE*)GAYLE_INT_1200; + } + irq->is_Code = (APTR)IDE_Handler_A1200; + irq->is_Node.ln_Pri = 20; irq->is_Node.ln_Type = NT_INTERRUPT; - irq->is_Node.ln_Name = "AT-IDE"; + if(bus->a500) + irq->is_Node.ln_Name = "AT-IDE2"; + else irq->is_Node.ln_Name = "AT-IDE"; irq->is_Data = bus; AddIntServer(INTB_PORTS, irq); @@ -112,6 +121,7 @@ OOP_Object *GAYLEATA__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New * data->bus->atapb_Node.ln_Succ = (struct Node *)-1; data->gaylebase = data->bus->port; data->gayleirqbase = data->bus->gayleirqbase; + data->a500 = data->bus->a500; //ata_CreateGayleInterrupt(data, 0); //mDispose = msg->mID - moRoot_New + moRoot_Dispose; @@ -201,6 +211,7 @@ APTR GAYLEATA__Hidd_ATABus__GetPIOInterface(OOP_Class *cl, OOP_Object *o, OOP_Ms pio->port = data->bus->port; pio->altport = data->bus->altport; pio->dataport = (UBYTE*)(((ULONG)pio->port) & ~3); + pio->a500 = data->bus->a500; /* * (A600/A1200) Data port is in a shadow bank of gayle (offset of 0x2000). * This shadow bank is for 16/32-bit data transfers, while the diff --git a/arch/m68k-amiga/hidd/gayle_ata/interface_pio.c b/arch/m68k-amiga/hidd/gayle_ata/interface_pio.c index 5d83d3c6d77..194b602a001 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/interface_pio.c +++ b/arch/m68k-amiga/hidd/gayle_ata/interface_pio.c @@ -34,13 +34,25 @@ static void ata_outsl(struct pio_data *data, APTR address, ULONG count) { volatile ULONG *addr = (ULONG*)data->dataport; - + if(data->a500) + { + asm volatile( +"1: move.l (%[address])+,(0xda2000) \n" +" move.l (%[address])+,(0xda2000) \n" +" subq.l #1,%[count] \n" +" bnes 1b \n" + ::[count]"d"(count >> 3),[address]"a"(address),[port]"a"(addr)); + } + else + { asm volatile( "1: move.l (%[address])+,(0xdd2000) \n" " move.l (%[address])+,(0xdd2000) \n" " subq.l #1,%[count] \n" " bnes 1b \n" ::[count]"d"(count >> 3),[address]"a"(address),[port]"a"(addr)); + } + } @@ -48,7 +60,18 @@ static void ata_insl(struct pio_data *data, APTR address, ULONG count) { volatile ULONG *addr = (ULONG*)data->dataport; - + if(data->a500) + { + asm volatile( +" bra 2f \n" +"1: \n" +" move16 0x00da6000,(%[address])+ \n" +" move16 0x00da6000,(%[address])+ \n" +"2: dbra %[count],1b \n" + ::[count]"d"(count >> 5),[address]"a"(address)); + } + else + { asm volatile( " bra 2f \n" "1: \n" @@ -56,6 +79,7 @@ static void ata_insl(struct pio_data *data, APTR address, ULONG count) " move16 0x00dd6000,(%[address])+ \n" "2: dbra %[count],1b \n" ::[count]"d"(count >> 5),[address]"a"(address)); + } } const APTR bus_FuncTable[] = diff --git a/arch/m68k-amiga/hidd/gayle_ata/interface_pio.h b/arch/m68k-amiga/hidd/gayle_ata/interface_pio.h index 9ac3a3c0ab0..7049ccbf2a3 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/interface_pio.h +++ b/arch/m68k-amiga/hidd/gayle_ata/interface_pio.h @@ -7,13 +7,23 @@ /* * Standard Amiga Gayle Definitions */ -#define GAYLE_BASE_1200 0xdd0000 /* 0xda0000.W, 0xda0004.B, 0xda0008.B ... */ +#if VAMPIRECARDSERIES==2 +#define GAYLE_BASE_1200 0xda0000 /* 0xda0000.W, 0xda0004.B, 0xda0008.B ... */ +#define GAYLE_IRQ_1200 0xda9000 +#define GAYLE_INT_1200 0xdaa000 +#else +#define GAYLE_BASE_1200 0xdd0000 /* 0xdd0000.W, 0xdd0004.B, 0xdd0008.B ... */ #define GAYLE_IRQ_1200 0xdd9000 #define GAYLE_INT_1200 0xdda000 +#endif #define GAYLE_BASE_4000 0xdd2022 /* 0xdd2020.W, 0xdd2026.B, 0xdd202a.B ... (argh!) */ #define GAYLE_IRQ_4000 0xdd3020 +#define GAYLE_BASE_500 0xda0000 /* Let's call it A500 even if it's used in others as well */ +#define GAYLE_IRQ_500 0xda9000 +#define GAYLE_INT_500 0xdaa000 + #define GAYLE_IRQ_IDE 0x80 #define GAYLE_INT_IDE 0x80 @@ -22,6 +32,7 @@ struct pio_data UBYTE *dataport; UBYTE *port; UBYTE *altport; + BOOL a500; }; extern const APTR bus_FuncTable[]; diff --git a/arch/m68k-amiga/hidd/gayle_ata/probe.c b/arch/m68k-amiga/hidd/gayle_ata/probe.c index 3674f6af9b1..c2b1dc3101a 100644 --- a/arch/m68k-amiga/hidd/gayle_ata/probe.c +++ b/arch/m68k-amiga/hidd/gayle_ata/probe.c @@ -1,5 +1,5 @@ /* - Copyright © 2013-2020, The AROS Development Team. All rights reserved. + Copyright © 2013-2020, The AROS Development Team. All rights reserved. $Id$ Desc: A600/A1200/A4000 ATA HIDD hardware detection routine @@ -33,18 +33,63 @@ -static UBYTE *getport(struct ata_ProbedBus *ddata) +static UBYTE *getport(struct ata_ProbedBus *ddata, int a500) { volatile struct Custom *custom = (struct Custom*)0xdff000; UBYTE id, status1, status2; volatile UBYTE *port, *altport; struct GfxBase *gfx; - + int retrynum = 0; + + struct GayleAdr {unsigned short a;}; + struct GayleAdr *ga = (struct GayleAdr *)0xda0018; + struct GayleAdr *gd = (struct GayleAdr *)0xdd0018; + struct GayleAdr *ca = (struct GayleAdr *)0xda1010; + struct GayleAdr *cd = (struct GayleAdr *)0xdd1010; + struct GayleAdr *cmda = (struct GayleAdr *)0xda101C; + struct GayleAdr *cmdd = (struct GayleAdr *)0xdd101C; + struct Board {UWORD type;}; + struct Board *MyBoard = (struct Board *)0xDFF3FC; + /* Is the following correct or can we do it more intelligent? */ + if(a500 > 0) + { + // A500 only has one controller + if((MyBoard->type == 0x02)||(MyBoard->type == 0x03)) + return 0; + ga->a = 0x0; + cmda->a = 0x10; + ca->a = 0x10; + if(ca->a != 0x10) return 0; // no hardware? + ca->a = 0x34; + if(ca->a != 0x34) return 0; // no hardware? + if((ga->a & 0xFF) == 0xFF) return 0; + } + else + { + gd->a = 0x0; + cd->a = 0x10; + cmdd->a = 0x10; + if(cd->a != 0x10) return 0; // no hardware? + cd->a = 0x34; + if(cd->a != 0x34) return 0; // no hardware? + if((gd->a & 0xFF ) == 0xFF) return 0; + } + port = NULL; gfx = (struct GfxBase*)TaggedOpenLibrary(TAGGEDOPEN_GRAPHICS); Disable(); - port = (UBYTE*)GAYLE_BASE_1200; - ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_1200; + if(a500 > 0) + { + port = (UBYTE*)GAYLE_BASE_500; + ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_500; + ddata->a500 = TRUE; + } + else + { + port = (UBYTE*)GAYLE_BASE_1200; + ddata->gayleirqbase = (UBYTE*)GAYLE_IRQ_1200; + ddata->a500 = FALSE; + } Enable(); CloseLibrary((struct Library*)gfx); @@ -73,7 +118,9 @@ static UBYTE *getport(struct ata_ProbedBus *ddata) if ( (((status1 | status2) & (ATAF_BUSY | ATAF_DRDY)) == (ATAF_BUSY | ATAF_DRDY)) || ((status1 | status2) & (ATAF_ERROR | ATAF_DATAREQ))) { -// goto RETRY; + retrynum++; + if(retrynum == 10) return NULL; + goto RETRY; //D(bug("[ATA:Gayle] No Devices detected\n");) //return NULL; @@ -87,70 +134,94 @@ static int gayle_bus_Scan(struct ataBase *base) { struct ata_ProbedBus *probedbus; OOP_Class *busClass = base->GayleBusClass; - struct TagItem ata_tags[] = + + for(int i=0; i<2; i++) { - {aHidd_Name , (IPTR)"ata_gayle.hidd" }, - {aHidd_HardwareName , 0 }, + + struct TagItem ata_tags[] = + { + {aHidd_Name , (IPTR)"ata_gayle.hidd" }, + {aHidd_HardwareName , 0 }, #define ATA_TAG_HARDWARENAME 1 - {TAG_DONE , 0 } - }; - - probedbus = AllocVec(sizeof(struct ata_ProbedBus), MEMF_ANY | MEMF_CLEAR); - if (probedbus && getport(probedbus)) { - OOP_Object *ata; - if (probedbus->doubler == 0) - ata_tags[ATA_TAG_HARDWARENAME].ti_Data = (IPTR)"Amiga(tm) Gayle IDE Controller"; + {TAG_DONE , 0 } + }; + + probedbus = AllocVec(sizeof(struct ata_ProbedBus), MEMF_ANY | MEMF_CLEAR); + if (probedbus && getport(probedbus, i)) { + OOP_Object *ata; + if(i == 0) + { + if (probedbus->doubler == 0) + ata_tags[ATA_TAG_HARDWARENAME].ti_Data = (IPTR)"Amiga(tm) Gayle IDE Controller"; + else + ata_tags[ATA_TAG_HARDWARENAME].ti_Data = (IPTR)"Amiga(tm) Gayle IDE Controller + Port Doubler"; + } else - ata_tags[ATA_TAG_HARDWARENAME].ti_Data = (IPTR)"Amiga(tm) Gayle IDE Controller + Port Doubler"; - - ata = HW_AddDriver(base->storageRoot, base->ataClass, ata_tags); - if (ata) { - struct TagItem attrs[] = { - {aHidd_Name , (IPTR)"ata_gayle.hidd" }, - {aHidd_HardwareName , 0 }, + if (probedbus->doubler == 0) + ata_tags[ATA_TAG_HARDWARENAME].ti_Data = (IPTR)"Amiga(tm) Gayle IDE Controller 2"; + else + ata_tags[ATA_TAG_HARDWARENAME].ti_Data = (IPTR)"Amiga(tm) Gayle IDE Controller 2 + Port Doubler"; + } + + ata = HW_AddDriver(base->storageRoot, base->ataClass, ata_tags); + if (ata) { + struct TagItem attrs[] = + { + {aHidd_Name , (IPTR)"ata_gayle.hidd" }, + {aHidd_HardwareName , 0 }, #define BUS_TAG_HARDWARENAME 1 - {aHidd_DriverData , (IPTR)probedbus }, - {aHidd_ATABus_PIODataSize , sizeof(struct pio_data) }, - {aHidd_ATABus_BusVectors , (IPTR)bus_FuncTable }, - {aHidd_ATABus_PIOVectors , (IPTR)pio_FuncTable }, - {aHidd_Bus_KeepEmpty , FALSE }, - {TAG_DONE , 0 } - }; - OOP_Object *bus; - - /* - * We use this field as ownership indicator. - * The trick is that HW_AddDriver() fails if either object creation fails - * or subsystem-side setup fails. In the latter case our object will be - * disposed. - * We need to know whether OOP_DisposeObject() or we should deallocate - * this structure on failure. - */ - probedbus->atapb_Node.ln_Succ = NULL; - - /* - * Check if we have a FastATA adaptor - */ - attrs[BUS_TAG_HARDWARENAME].ti_Data = (IPTR)"Gayle IDE Channel"; + {aHidd_DriverData , (IPTR)probedbus }, + {aHidd_ATABus_PIODataSize , sizeof(struct pio_data) }, + {aHidd_ATABus_BusVectors , (IPTR)bus_FuncTable }, + {aHidd_ATABus_PIOVectors , (IPTR)pio_FuncTable }, + {aHidd_Bus_KeepEmpty , FALSE }, + {TAG_DONE , 0 } + }; + if(i == 1) + attrs[0].ti_Data = (IPTR)"ata_gayle2.hidd"; + + OOP_Object *bus; + + /* + * We use this field as ownership indicator. + * The trick is that HW_AddDriver() fails if either object creation fails + * or subsystem-side setup fails. In the latter case our object will be + * disposed. + * We need to know whether OOP_DisposeObject() or we should deallocate + * this structure on failure. + */ + probedbus->atapb_Node.ln_Succ = NULL; + + /* + * Check if we have a FastATA adaptor + */ + if(i == 0) + attrs[BUS_TAG_HARDWARENAME].ti_Data = (IPTR)"Gayle IDE Channel"; + else attrs[BUS_TAG_HARDWARENAME].ti_Data = (IPTR)"Gayle IDE Channel 2"; - bus = HIDD_StorageController_AddBus(ata, busClass, attrs); - if (bus) - return TRUE; - D(bug("[ATA:Gayle] Failed to create object for device IO: %x:%x IRQ: %x\n", - probedbus->port, probedbus->altport, probedbus->gayleirqbase);) - - /* - * Free the structure only upon object creation failure! - * In case of success it becomes owned by the driver object! - */ - if (!probedbus->atapb_Node.ln_Succ) - FreeVec(probedbus); - return TRUE; + bus = HIDD_StorageController_AddBus(ata, busClass, attrs); + + // Do not exit, we could have more controllers + // if (bus) + // return TRUE; + + D(bug("[ATA:Gayle] Failed to create object for device IO: %x:%x IRQ: %x\n", + probedbus->port, probedbus->altport, probedbus->gayleirqbase);) + + /* + * Free the structure only upon object creation failure! + * In case of success it becomes owned by the driver object! + * Edit: Can we really free it yet? We are collecting controllers. Please enable the two lines if sure. + */ + // if (!probedbus->atapb_Node.ln_Succ) + // FreeVec(probedbus); + // return TRUE; + } } + FreeVec(probedbus); } - FreeVec(probedbus); return TRUE; } diff --git a/rom/devs/ata/ata.c b/rom/devs/ata/ata.c index a809f2c25d1..7df4f5718d5 100755 --- a/rom/devs/ata/ata.c +++ b/rom/devs/ata/ata.c @@ -1093,3 +1093,97 @@ void BusTaskCode(struct ata_Bus *bus, struct ataBase *ATABase) } } } +void BusTaskCode2(struct ata_Bus *bus, struct ataBase *ATABase) +{ + ULONG sig; + int iter; + struct IORequest *msg; + OOP_Object *unitObj; + struct ata_Unit *unit; + + DINIT(bug("[ATA**] Task started (bus: %u)\n", bus->ab_BusNum)); + + bus->ab_Timer = ata_OpenTimer(ATABase); +// bus->ab_BounceBufferPool = CreatePool(MEMF_CLEAR | MEMF_31BIT, 131072, 65536); + + /* Get the signal used for sleeping */ + bus->ab_Task = FindTask(0); + bus->ab_SleepySignal = AllocSignal(-1); + /* Failed to get it? Use SIGBREAKB_CTRL_E instead */ + if (bus->ab_SleepySignal < 0) + bus->ab_SleepySignal = SIGBREAKB_CTRL_E; + + sig = 1L << bus->ab_MsgPort->mp_SigBit; + + for (iter = 0; iter < MAX_BUSUNITS; ++iter) + { + DINIT(bug("[ATA**] Device %u type %d\n", iter, bus->ab_Dev[iter])); + + if (bus->ab_Dev[iter] > DEV_UNKNOWN) + { + unitObj = OOP_NewObject(ATABase->unitClass, NULL, NULL); + if (unitObj) + { + unit = OOP_INST_DATA(ATABase->unitClass, unitObj); + ata_init_unit(bus, unit, iter); + if (ata_setup_unit(bus, unit)) + { + /* + * Add unit to the bus. + * At this point it becomes visible to OpenDevice(). + */ + bus->ab_Units[iter] = unitObj; + + if (unit->au_XferModes & AF_XFER_PACKET) + { + struct ata_Controller *ataNode = NULL; + + ata_RegisterVolume(0, 0, unit); + + OOP_GetAttr(bus->ab_Object, aHidd_ATABus_Controller, (IPTR *)&ataNode); + } + else + { + ata_RegisterVolume(0, unit->au_Cylinders - 1, unit); + } + } + else + { + /* Destroy unit that couldn't be initialised */ + OOP_DisposeObject((OOP_Object *)unit); + bus->ab_Dev[iter] = DEV_NONE; + } + } + } + } + + D(bug("[ATA--] Bus %u scan finished\n", bus->ab_BusNum)); + ReleaseSemaphore(&ATABase->DetectionSem); + + /* Wait forever and process messages */ + for (;;) + { + Wait(sig); + + /* Even if you get new signal, do not process it until Unit is not active */ + if (!(bus->ab_Flags & UNITF_ACTIVE)) + { + bus->ab_Flags |= UNITF_ACTIVE; + + /* Empty the request queue */ + while ((msg = (struct IORequest *)GetMsg(bus->ab_MsgPort))) + { + /* And do IO's */ + HandleIO(msg, ATABase); + + /* TD_ADDCHANGEINT doesn't require reply */ + if (msg->io_Command != TD_ADDCHANGEINT) + { + ReplyMsg((struct Message *)msg); + } + } + + bus->ab_Flags &= ~(UNITF_INTASK | UNITF_ACTIVE); + } + } +} diff --git a/rom/devs/ata/ata.h b/rom/devs/ata/ata.h index bd7094e775f..18943316eb8 100755 --- a/rom/devs/ata/ata.h +++ b/rom/devs/ata/ata.h @@ -188,6 +188,8 @@ struct ata_Bus APTR ab_BounceBufferPool; + BOOL use_da; + /** functions go here **/ void (*ab_HandleIRQ)(struct ata_Unit* unit, UBYTE status); }; @@ -407,6 +409,7 @@ void ata_init_unit(struct ata_Bus *bus, struct ata_Unit *unit, UBYTE u); BOOL ata_RegisterVolume(ULONG StartCyl, ULONG EndCyl, struct ata_Unit *unit); void BusTaskCode(struct ata_Bus *bus, struct ataBase *ATABase); +void BusTaskCode2(struct ata_Bus *bus, struct ataBase *ATABase); void DaemonCode(struct ataBase *LIBBASE, struct ata_Controller *ataNode); BYTE SCSIEmu(struct ata_Unit*, struct SCSICmd*); diff --git a/rom/devs/ata/ata_busclass.c b/rom/devs/ata/ata_busclass.c index 813b95e66fc..8ed6beed63d 100644 --- a/rom/devs/ata/ata_busclass.c +++ b/rom/devs/ata/ata_busclass.c @@ -1,5 +1,5 @@ /* - Copyright © 1995-2019, The AROS Development Team. All rights reserved. + Copyright © 1995-2019, The AROS Development Team. All rights reserved. $Id$ */ @@ -941,6 +941,7 @@ void ATABus__Hidd_ATABus__Shutdown(OOP_Class *cl, OOP_Object *o, OOP_Msg *msg) BOOL Hidd_ATABus_Start(OOP_Object *o, struct ataBase *ATABase) { struct ata_Bus *ab = OOP_INST_DATA(ATABase->busClass, o); + STRPTR TaskName = "ATA[PI] Subsystem"; D(bug("[ATA:Bus] %s()\n", __func__)); @@ -948,7 +949,27 @@ BOOL Hidd_ATABus_Start(OOP_Object *o, struct ataBase *ATABase) OOP_SetAttrsTags(o, aHidd_Bus_IRQHandler, Hidd_ATABus_HandleIRQ, aHidd_Bus_IRQData , ab, TAG_DONE); - + unsigned short *pd = (unsigned char *)0xdd0018; + unsigned short *pa = (unsigned char *)0xda0018; + unsigned short d, a; + d = *pd; + a = *pa; + + // is this check correct? Please find more accurate way if possible + if(ATABase->ata__buscount == 0) + { + if((d & 0xFF) != 0xFF) + ab->use_da = FALSE; + else ab->use_da = TRUE; + } + else + { + if((a & 0xFF) != 0xFF) + ab->use_da = TRUE; + else ab->use_da = FALSE; + TaskName = "ATA[PI] Subsystem 2"; + } + /* scan bus - try to locate all devices (disables irq) */ ata_InitBus(ab); @@ -995,14 +1016,26 @@ BOOL Hidd_ATABus_Start(OOP_Object *o, struct ataBase *ATABase) * then, if successful, insert units. This allows to keep things parallel. */ D(bug("[ATA>>] Start: Bus %u: Unit 0 - %d, Unit 1 - %d\n", ab->ab_BusNum, ab->ab_Dev[0], ab->ab_Dev[1])); - return NewCreateTask(TASKTAG_PC , BusTaskCode, - TASKTAG_NAME , "ATA[PI] Subsystem", + if(ATABase->ata__buscount == 0) + { + return NewCreateTask(TASKTAG_PC , BusTaskCode, + TASKTAG_NAME , TaskName, TASKTAG_STACKSIZE , STACK_SIZE, TASKTAG_PRI , TASK_PRI, TASKTAG_TASKMSGPORT, &ab->ab_MsgPort, TASKTAG_ARG1 , ab, TASKTAG_ARG2 , ATABase, TAG_DONE) ? TRUE : FALSE; + }else{ + return NewCreateTask(TASKTAG_PC , BusTaskCode2, + TASKTAG_NAME , TaskName, + TASKTAG_STACKSIZE , STACK_SIZE, + TASKTAG_PRI , TASK_PRI, + TASKTAG_TASKMSGPORT, &ab->ab_MsgPort, + TASKTAG_ARG1 , ab, + TASKTAG_ARG2 , ATABase, + TAG_DONE) ? TRUE : FALSE; + } } AROS_UFH3(BOOL, Hidd_ATABus_Open, diff --git a/rom/devs/ata/lowlevel.c b/rom/devs/ata/lowlevel.c index 17b31ddad45..37f9386377c 100644 --- a/rom/devs/ata/lowlevel.c +++ b/rom/devs/ata/lowlevel.c @@ -177,7 +177,10 @@ static void ata_IRQSetHandler(struct ata_Unit *unit, static void ata_IRQNoData(struct ata_Unit *unit, UBYTE status) { - volatile UBYTE *port=0xDD201C; + volatile UBYTE *port; + if(unit->au_Bus->use_da) + port = 0xDA201C; + else port = 0xDD201C; status = *port; if (status & ATAF_BUSY) @@ -200,8 +203,11 @@ static void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status) { ULONG count; APTR address; - volatile UBYTE *port=0xDD201C; - long retrycount; + volatile UBYTE *port; + long retrycount; + if(unit->au_Bus->use_da) + port = 0xDA201C; + else port = 0xDD201C; AGAIN: retrycount=100000000; @@ -222,13 +228,25 @@ static void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status) count = (unit->au_cmd_length>>5); address = unit->au_cmd_data; - + + if (unit->au_Bus->use_da) + { + asm volatile( + " bra 2f \n" + "1: move16 (0xDA6000),(%[address])+ \n" + " move16 (0xDA6000),(%[address])+ \n" + "2: dbra %[count],1b \n" + :[count]"+d"(count),[address]"+a"(address)::"cc"); + } + else + { asm volatile( " bra 2f \n" "1: move16 (0xDD6000),(%[address])+ \n" " move16 (0xDD6000),(%[address])+ \n" "2: dbra %[count],1b \n" :[count]"+d"(count),[address]"+a"(address)::"cc"); + } // /* @@ -274,10 +292,13 @@ static void ata_PIOWriteBlk(struct ata_Unit *unit) static void ata_IRQPIOWrite(struct ata_Unit *unit, UBYTE status) { - volatile UBYTE *port=0xDD201C; + volatile UBYTE *port; ULONG count; APTR address; - long retrycount; + long retrycount; + if(unit->au_Bus->use_da) + port = 0xDA201C; + else port = 0xDD201C; /* * If there's more data left for this transfer, write it, keep same * handler and wait for next interrupt @@ -302,13 +323,24 @@ static void ata_IRQPIOWrite(struct ata_Unit *unit, UBYTE status) count = unit->au_cmd_length>>3; address = unit->au_cmd_data; + if(unit->au_Bus->use_da) + { + asm volatile( + " bra 2f \n" + "1: move.l (%[address])+,(0xDA2000) \n" + " move.l (%[address])+,(0xDA2000) \n" + "2: dbra %[count],1b \n" + :[count]"+d"(count),[address]"+a"(address)::"cc"); + } + else + { asm volatile( " bra 2f \n" "1: move.l (%[address])+,(0xDD2000) \n" " move.l (%[address])+,(0xDD2000) \n" "2: dbra %[count],1b \n" :[count]"+d"(count),[address]"+a"(address)::"cc"); - + } unit->au_cmd_data += unit->au_cmd_length; unit->au_cmd_total -= unit->au_cmd_length; @@ -554,8 +586,19 @@ static BYTE ata_exec_cmd(struct ata_Unit* unit, ata_CommandBlock *block) BYTE err = 0; APTR mem = block->buffer; UBYTE status; - volatile WORD *irqreg=0xDD9000; - volatile WORD *irqen=0xDDA000; + volatile WORD *irqreg; + volatile WORD *irqen; + + if(unit->au_Bus->use_da) + { + irqreg = 0xDA9000; + irqen = 0xDAA000; + } + else + { + irqreg = 0xDD9000; + irqen = 0xDDA000; + } /* * Use a short timeout for Identify commands. This is because some bad diff --git a/rom/graphics/changesprite.c b/rom/graphics/changesprite.c index 15d9fa2e152..edc3a48ad23 100644 --- a/rom/graphics/changesprite.c +++ b/rom/graphics/changesprite.c @@ -1,5 +1,5 @@ /* - Copyright © 1995-2007, The AROS Development Team. All rights reserved. + Copyright © 1995-2007, The AROS Development Team. All rights reserved. $Id$ Desc: Graphics function ChangeSprite() @@ -50,8 +50,13 @@ { AROS_LIBFUNC_INIT - /* TODO: Write graphics/ChangeSprite() */ - aros_print_not_implemented ("ChangeSprite"); + WORD x,y; + + s->posctldata = newdata; + x = s->x; + y = s->y; + + MoveSprite(vp, s, x, y); AROS_LIBFUNC_EXIT } /* ChangeSprite */ diff --git a/rom/graphics/gfxfuncsupport.c b/rom/graphics/gfxfuncsupport.c index 4a65ede9515..e29d9a6ac3c 100644 --- a/rom/graphics/gfxfuncsupport.c +++ b/rom/graphics/gfxfuncsupport.c @@ -1242,3 +1242,94 @@ void GenMinterms(struct RastPort *rp) } } } + +/****************************************************************************************/ + +void pokeCL(UWORD *ci, UWORD target, UWORD table) +{ + ULONG targ = (ULONG)target; + if(!ci) return; + targ &= 0x1fe; + for(;ci;ci+=2) + { + if( ((*ci)==0xffff) && ((*(ci+1) == 0xfffe))) return; + if(*ci == targ) break; + } + if (((*ci) == 0xffff) && ((*(ci+1)==0xfffe))) return; + if(*ci == targ) + { + ci++; + *ci++ = table; + } +} + +/****************************************************************************************/ + +struct CopIns *pokeCI(struct CopIns *ci, UWORD *field1, short field2) +{ + struct CopIns *c; + UWORD op = COPPER_MOVE; + c = ci; + if(c) + { + short out = FALSE; + while(!out) + { + switch(c->OpCode & 3) + { + case COPPER_MOVE: + { + if(c->DESTADDR == (((UWORD)field1) & 0x1fe)) + { + short mask; + if((mask = op&0xC000)) + { + if(c->OpCode & mask) + { + c->DESTDATA = field2; + return c; + } + } + else + { + c->DESTDATA = field2; + return c; + } + } + c++; + break; + } + case COPPER_WAIT: + { + if(c->HWAITPOS == 255) + { + return 0; + } + else c++; + break; + } + case CPRNXTBUF: + { + if(c->NXTLIST == NULL) + { + out = TRUE; + } + else + { + if((c = c->NXTLIST->CopIns) == NULL) + { + out = TRUE; + } + } + break; + } + default: + { + out=TRUE; + break; + } + } + } + } + return 0; +} diff --git a/rom/graphics/gfxfuncsupport.h b/rom/graphics/gfxfuncsupport.h index f12603a1101..788539a3e27 100644 --- a/rom/graphics/gfxfuncsupport.h +++ b/rom/graphics/gfxfuncsupport.h @@ -220,6 +220,8 @@ void BltRastPortBitMap(struct RastPort *srcRastPort, WORD xSrc, WORD ySrc, struct GfxBase *GfxBase); void GenMinterms(struct RastPort *rp); +void pokeCL(UWORD *ci, UWORD target, UWORD table); +struct CopIns *pokeCI(struct CopIns *ci, UWORD *field1, short field2); /****************************************************************************************/ diff --git a/rom/graphics/loadrgb4.c b/rom/graphics/loadrgb4.c index ee5cc84614c..2730dce4e14 100644 --- a/rom/graphics/loadrgb4.c +++ b/rom/graphics/loadrgb4.c @@ -8,6 +8,93 @@ #include #include "graphics_intern.h" +static void pokeCL(UWORD *ci, UWORD target, UWORD table) +{ + ULONG targ = (ULONG)target; + if(!ci) return; + targ &= 0x1fe; + for(;ci;ci+=2) + { + if( ((*ci)==0xffff) && ((*(ci+1) == 0xfffe))) return; + if(*ci == targ) break; + } + if (((*ci) == 0xffff) && ((*(ci+1)==0xfffe))) return; + if(*ci == targ) + { + ci++; + *ci++ = table; + } +} + +static struct CopIns *pokeCI(struct CopIns *ci, UWORD *field1, short field2) +{ + struct CopIns *c; + UWORD op=COPPER_MOVE; + c = ci; + if(c) + { + short out = FALSE; + while(!out) + { + switch(c->OpCode & 3) + { + case COPPER_MOVE: + { + if(c->DESTADDR == (((UWORD)field1) & 0x1fe)) + { + short mask; + if((mask = op&0xC000)) + { + if(c->OpCode & mask) + { + c->DESTDATA = field2; + return c; + } + } + else + { + c->DESTDATA = field2; + return c; + } + } + c++; + break; + } + case COPPER_WAIT: + { + if(c->HWAITPOS == 255) + { + return 0; + } + else c++; + break; + } + case CPRNXTBUF: + { + if(c->NXTLIST == NULL) + { + out = TRUE; + } + else + { + if((c = c->NXTLIST->CopIns) == NULL) + { + out = TRUE; + } + } + break; + } + default: + { + out=TRUE; + break; + } + } + } + } + return 0; +} + /***************************************************************************** NAME */ @@ -55,14 +142,35 @@ AROS_LIBFUNC_INIT WORD t; + int i; + volatile struct Custom *custom = (struct Custom *)0xdff000; if (!vp) + { + // No ViewPort? Then alter the colors directly + for (i = 0; i < count ; i++) + custom->color[i] = *colors++; return; - + } ASSERT_VALID_PTR(vp); ASSERT_VALID_PTR(colors); /* TODO: Optimization */ + struct ColorMap *cm; + UWORD *ct; + + // Why do we need this? Answer: For non hidd screens SetRGB32 might fail to fill the color table. This is a good place, I think + if(vp->ColorMap) + { + cm = vp->ColorMap; + ct = cm->ColorTable; + if(count > cm->Count) count = cm->Count; + for(i = 0; iActiViewCprSemaphore); + for (t = 0; t < count; t ++ ) + { + // Remaining question: Do we need to check VP_HIDE? + if(vp->DspIns) + { + // we need to store it into the intermediate CopperList too + pokeCL(vp->DspIns->CopLStart, &custom->color[t], colors[t]); + pokeCL(vp->DspIns->CopSStart, &custom->color[t], colors[t]); + pokeCI(vp->DspIns->CopIns, &custom->color[t], colors[t]); + } + } + ReleaseSemaphore(GfxBase->ActiViewCprSemaphore); + + // To make it visible immediately we need to update the view. To simplify it, we call MrgCop + MrgCop(GfxBase->ActiView); + if(TypeOfMem(GfxBase->ActiView->LOFCprList->start) == MEMF_CHIP) + GfxBase->LOFlist = GfxBase->ActiView->LOFCprList->start; AROS_LIBFUNC_EXIT diff --git a/rom/graphics/setrgb4.c b/rom/graphics/setrgb4.c index 0fcf155a109..7e3f3cb0376 100644 --- a/rom/graphics/setrgb4.c +++ b/rom/graphics/setrgb4.c @@ -12,6 +12,7 @@ NAME */ #include #include +#include "gfxfuncsupport.h" AROS_LH5(void, SetRGB4, @@ -63,8 +64,29 @@ { AROS_LIBFUNC_INIT + UWORD col; + volatile struct Custom *custom = (struct Custom *)0xdff000; + + col = ((r & 0xF) << 8) | ((g & 0xF) << 4) | (b & 0xF); + if (!vp) + { + custom->color[n] = col; return; + } + + if(vp->ColorMap) + SetRGB4CM(vp->ColorMap, n, r, g, b); + + if(vp->DspIns) + { + ObtainSemaphore(GfxBase->ActiViewCprSemaphore); + pokeCL(vp->DspIns->CopLStart, &custom->color[n], col); + pokeCL(vp->DspIns->CopSStart, &custom->color[n], col); + + pokeCI(vp->DspIns->CopIns,&custom->color[n],col); + ReleaseSemaphore(GfxBase->ActiViewCprSemaphore); + } r = (( r & 0xF) << 4) | (r & 0xFF ); r = r | (r << 8) | ( r << 16 ) | (r << 24 ); @@ -75,6 +97,10 @@ SetRGB32( vp, n, r, g, b ); + MrgCop(GfxBase->ActiView); + if(TypeOfMem(GfxBase->ActiView->LOFCprList->start) == MEMF_CHIP) + GfxBase->LOFlist = GfxBase->ActiView->LOFCprList->start; + /************************************************************ / This is the code that works correctly on the real thing struct ColorMap * CM = vp->ColorMap; diff --git a/rom/intuition/refreshglist.c b/rom/intuition/refreshglist.c index 2c3f2df367d..c659b23472e 100644 --- a/rom/intuition/refreshglist.c +++ b/rom/intuition/refreshglist.c @@ -91,11 +91,12 @@ struct Gadget *findprevgadget(struct Gadget *gadget,struct Window *window,struct gadgets = requester->ReqGadget; } -#ifdef USEGADGETLOCK +// Lock both in any way. If not correct, revert, but it seems fine +//#ifdef USEGADGETLOCK LOCKGADGET(IntuitionBase) -#else +//#else LOCKWINDOWLAYERS(window); -#endif +//#endif int_refreshglist(gadgets, window, @@ -105,11 +106,11 @@ struct Gadget *findprevgadget(struct Gadget *gadget,struct Window *window,struct 0, IntuitionBase); -#ifdef USEGADGETLOCK +//#ifdef USEGADGETLOCK UNLOCKGADGET(IntuitionBase) -#else +//#else UNLOCKWINDOWLAYERS(window); -#endif +//#endif ReturnVoid("RefreshGList"); @@ -120,6 +121,10 @@ void int_refreshglist(struct Gadget *gadgets, struct Window *window, struct Requester *requester, LONG numGad, LONG mustbe, LONG mustnotbe, struct IntuitionBase *IntuitionBase) { + +// Might help to undef this +#undef GADTOOLSCOMPATIBLE + #ifdef GADTOOLSCOMPATIBLE struct Gadget *gadtoolsgadget = 0; #endif @@ -131,15 +136,15 @@ void int_refreshglist(struct Gadget *gadgets, struct Window *window, gadgets, window, requester, numGad, mustbe, mustnotbe)); // in case we're not called from RefreshGList... -#ifdef USEGADGETLOCK +//#ifdef USEGADGETLOCK LOCKGADGET(IntuitionBase) -#else +//#else LOCKWINDOWLAYERS(window); -#endif +//#endif for ( ; gadgets && numGad; gadgets=gadgets->NextGadget, numGad --) { - if (gadgets->GadgetType == 0) + if ((gadgets->GadgetType == 0) || (gadgets->GadgetType == 0x100) || (gadgets->GadgetType == 0x105) || (gadgets->Flags == 0x8007)) { #ifdef GADTOOLSCOMPATIBLE if (gadgets->GadgetType & 0x100) @@ -172,7 +177,7 @@ void int_refreshglist(struct Gadget *gadgets, struct Window *window, gadgets = firstgad; for ( ; gadgets && numGad; gadgets=gadgets->NextGadget, numGad --) { - if (gadgets->GadgetType > 0) + if ((gadgets->GadgetType > 0) && (gadgets->GadgetType != 0x100) && (gadgets->GadgetType != 0x105) && (gadgets->Flags != 0x8007)) { #ifdef GADTOOLSCOMPATIBLE if (gadgets->GadgetType & 0x100) @@ -213,11 +218,11 @@ void int_refreshglist(struct Gadget *gadgets, struct Window *window, } #endif -#ifdef USEGADGETLOCK +//#ifdef USEGADGETLOCK UNLOCKGADGET(IntuitionBase) -#else +//#else UNLOCKWINDOWLAYERS(window); -#endif +//#endif } BOOL qualifygadget(struct Gadget *gadgets,LONG mustbe, LONG mustnotbe,struct IntuitionBase *IntuitionBase) @@ -271,6 +276,14 @@ BOOL qualifygadget(struct Gadget *gadgets,LONG mustbe, LONG mustnotbe,struct Int { if (mustbe & REFRESHGAD_BOOPSI) return FALSE; /* don't refresh if not boopsi gadget */ } + if (gadgets->Flags & (GFLG_GADGIMAGE|GFLG_GADGHNONE) == GFLG_GADGIMAGE|GFLG_GADGHNONE) + { + if (mustnotbe & REFRESHGAD_BOOPSI) return FALSE; /* don't refresh if boopsi gadget */ + } + else + { + if (mustbe & REFRESHGAD_BOOPSI) return FALSE; /* don't refresh if not boopsi gadget */ + } } /* if ((mustbe != 0) || (mustnotbe != 0)) */ return TRUE;