|
| 1 | +/* |
| 2 | +** DenebClockport V0.0 (23-Jan-08) by Chris Hodges <hodges@in.tum.de> |
| 3 | +** |
| 4 | +** Project started: 23-Jan-08 |
| 5 | +** Releases : |
| 6 | +*/ |
| 7 | + |
| 8 | +#define __NOLIBBASE__ |
| 9 | +#include <stddef.h> |
| 10 | +#include <stdlib.h> |
| 11 | +#include <string.h> |
| 12 | +#include <exec/exec.h> |
| 13 | +#include <exec/resident.h> |
| 14 | +#include <dos/dos.h> |
| 15 | +#include <libraries/configvars.h> |
| 16 | +#include <proto/exec.h> |
| 17 | +#include <proto/expansion.h> |
| 18 | +#include <proto/dos.h> |
| 19 | + |
| 20 | +#include "deneb.h" |
| 21 | + |
| 22 | +#define MACH_CLOCKPORT_Z2 (0x0200>>1) // WORD offset |
| 23 | +#define MACH_CLKPORTCTRL_Z2 (0x02fc>>1) // WORD offset |
| 24 | + |
| 25 | +#define MCPCB_FAST_Z2 15 /* Enable Fast Zorro II */ |
| 26 | +#define MCPCB_RESET_Z2 2 /* Clockport reset */ |
| 27 | +#define MCPCB_INTEN_Z2 1 /* Enable interrupts */ |
| 28 | +#define MCPCB_INT2_Z2 0 /* Use INT2 instead of INT6 */ |
| 29 | + |
| 30 | +#define MCPCF_FAST_Z2 (1UL<<MCPCB_FAST_Z2) |
| 31 | +#define MCPCF_RESET_Z2 (1UL<<MCPCB_RESET_Z2) |
| 32 | +#define MCPCF_INTEN_Z2 (1UL<<MCPCB_INTEN_Z2) |
| 33 | +#define MCPCF_INT2_Z2 (1UL<<MCPCB_INT2_Z2) |
| 34 | + |
| 35 | +#define VERSION 1 |
| 36 | +#define REVISION 1 |
| 37 | +#define DATE "30.03.08" |
| 38 | +#define VERS "DenebClockport 1.1" |
| 39 | +#define VSTRING "DenebClockport 1.1 (30.03.08)" |
| 40 | +#define VERSTAG "\0$VER: DenebClockport 1.1 (30.03.08) © 2008 Written by Chris Hodges" |
| 41 | + |
| 42 | +ULONG AddClockport(struct CPConfig *cpc); |
| 43 | +__saveds void romstart(void); |
| 44 | + |
| 45 | +struct CPNode |
| 46 | +{ |
| 47 | + UWORD cpn_VendorID; |
| 48 | + UWORD cpn_ProductID; |
| 49 | + UWORD cpn_Offset; |
| 50 | + STRPTR cpn_Name; |
| 51 | +}; |
| 52 | + |
| 53 | +struct CPNode cpboards[]; |
| 54 | + |
| 55 | +#define ARGS_BOARD 0 |
| 56 | +#define ARGS_CS 1 |
| 57 | +#define ARGS_AS 2 |
| 58 | +#define ARGS_RP 3 |
| 59 | +#define ARGS_WP 4 |
| 60 | +#define ARGS_SIZEOF 5 |
| 61 | + |
| 62 | +struct CPConfig |
| 63 | +{ |
| 64 | + UWORD cpc_VendorID; |
| 65 | + UWORD cpc_ProductID; |
| 66 | + UWORD cpc_Offset; |
| 67 | + UWORD cpc_CSDelay; |
| 68 | + UWORD cpc_AddressSetup; |
| 69 | + UWORD cpc_ReadPulse; |
| 70 | + UWORD cpc_WritePulse; |
| 71 | +}; |
| 72 | + |
| 73 | +ULONG main(void) |
| 74 | +{ |
| 75 | + struct Library *DOSBase; |
| 76 | + struct CPConfig cpc; |
| 77 | + struct CPNode *cpn = cpboards; |
| 78 | + struct RDArgs *ArgsHook; |
| 79 | + LONG ArgsArray[ARGS_SIZEOF] = { 0, 0, 0, 0, 0 }; |
| 80 | + char *template = "BOARD,CSDELAY=CS/K/N,ADDRESSSETUP=AS/K/N,READPULSE=RP/K/N,WRITEPULSE=WP/K/N"; |
| 81 | + ULONG retval; |
| 82 | + |
| 83 | + DOSBase = OpenLibrary("dos.library", 36); |
| 84 | + if(!DOSBase) |
| 85 | + { |
| 86 | + return(RETURN_FAIL); |
| 87 | + } |
| 88 | + if(!(ArgsHook = ReadArgs(template, ArgsArray, NULL))) |
| 89 | + { |
| 90 | + PutStr("Wrong arguments!\n"); |
| 91 | + CloseLibrary(DOSBase); |
| 92 | + return(RETURN_FAIL); |
| 93 | + } |
| 94 | + cpc.cpc_Offset = cpn->cpn_Offset; |
| 95 | + cpc.cpc_CSDelay = 0x03; |
| 96 | + cpc.cpc_AddressSetup = 0x03; |
| 97 | + cpc.cpc_ReadPulse = 0x14; |
| 98 | + cpc.cpc_WritePulse = 0x14; |
| 99 | + |
| 100 | + if(ArgsArray[ARGS_BOARD]) |
| 101 | + { |
| 102 | + while(cpn->cpn_Name) |
| 103 | + { |
| 104 | + STRPTR bname = (STRPTR) ArgsArray[ARGS_BOARD]; |
| 105 | + STRPTR cptr = cpn->cpn_Name; |
| 106 | + while(*bname && *cptr) |
| 107 | + { |
| 108 | + if((*bname & 0xcf) != (*cptr & 0xcf)) |
| 109 | + { |
| 110 | + break; |
| 111 | + } |
| 112 | + bname++; |
| 113 | + cptr++; |
| 114 | + } |
| 115 | + if(!(*cptr || *bname)) |
| 116 | + { |
| 117 | + break; |
| 118 | + } |
| 119 | + cpn++; |
| 120 | + } |
| 121 | + if(!cpn->cpn_Name) |
| 122 | + { |
| 123 | + Printf("Wrong board name '%s', using default!\n", ArgsArray[ARGS_BOARD]); |
| 124 | + cpn = cpboards; |
| 125 | + } |
| 126 | + } |
| 127 | + cpc.cpc_VendorID = cpn->cpn_VendorID; |
| 128 | + cpc.cpc_ProductID = cpn->cpn_ProductID; |
| 129 | + |
| 130 | + if(ArgsArray[ARGS_CS]) |
| 131 | + { |
| 132 | + cpc.cpc_CSDelay = *((ULONG *) ArgsArray[ARGS_CS]); |
| 133 | + } |
| 134 | + if(ArgsArray[ARGS_AS]) |
| 135 | + { |
| 136 | + cpc.cpc_AddressSetup = *((ULONG *) ArgsArray[ARGS_AS]); |
| 137 | + } |
| 138 | + if(ArgsArray[ARGS_RP]) |
| 139 | + { |
| 140 | + cpc.cpc_ReadPulse = *((ULONG *) ArgsArray[ARGS_RP]); |
| 141 | + } |
| 142 | + if(ArgsArray[ARGS_WP]) |
| 143 | + { |
| 144 | + cpc.cpc_WritePulse = *((ULONG *) ArgsArray[ARGS_WP]); |
| 145 | + } |
| 146 | + retval = AddClockport(&cpc); |
| 147 | + FreeArgs(ArgsHook); |
| 148 | + CloseLibrary(DOSBase); |
| 149 | + return(retval); |
| 150 | +} |
| 151 | + |
| 152 | +static const char prgname[] = VERS; |
| 153 | +static const char prgidstring[] = VSTRING; |
| 154 | +static const char prgverstag[] = VERSTAG; |
| 155 | + |
| 156 | +struct CPNode cpboards[] = |
| 157 | +{ |
| 158 | + { 0x1212, 0x0017, 0xa001, "XSurf" }, /* X-Surf CP 0 */ |
| 159 | + { 0x1212, 0x0017, 0xc000, "XSurf2" }, /* X-Surf CP 1 */ |
| 160 | + { 0x0861, 0x00c8, 0x4000, "Highway" }, /* Highway */ |
| 161 | + { 0x0861, 0x0081, 0x0001, "Unity" }, /* Unity Prototype CP 0 */ |
| 162 | + { 0x0861, 0x0081, 0x0041, "Unity2" }, /* Unity Prototype CP 1 */ |
| 163 | + { 0x1212, 0x0005, 0x8000, "ISDNSurfer" }, /* ISDN-Surfer */ |
| 164 | + { 0x1212, 0x0007, 0x9000, "VarIO" }, /* VarIO */ |
| 165 | + { 0x1212, 0x0000, 0x0e00, "Buddha" }, /* Buddha flash */ |
| 166 | + { 0x1212, 0x000a, 0x8000, "Kickflash" }, /* Kickflash */ |
| 167 | + { 0x0000, 0x0000, 0x0000, NULL } |
| 168 | +}; |
| 169 | + |
| 170 | + |
| 171 | +static |
| 172 | +const struct Resident ROMTag = |
| 173 | +{ |
| 174 | + RTC_MATCHWORD, |
| 175 | + (struct Resident *) &ROMTag, |
| 176 | + (struct Resident *) (&ROMTag + 1), |
| 177 | +#ifdef __MORPHOS__ |
| 178 | + RTF_PPC|RTF_COLDSTART, |
| 179 | +#else /* __MORPHOS__ */ |
| 180 | + RTF_COLDSTART, |
| 181 | +#endif /* __MORPHOS__ */ |
| 182 | + VERSION, |
| 183 | + NT_UNKNOWN, |
| 184 | + 103, |
| 185 | + (char *) prgname, |
| 186 | + (char *) prgidstring, |
| 187 | + (APTR) &romstart |
| 188 | +}; |
| 189 | + |
| 190 | +/* ---------------------------------------------------------------------- */ |
| 191 | + |
| 192 | +__saveds void romstart(void) |
| 193 | +{ |
| 194 | + struct CPConfig cpc; |
| 195 | + cpc.cpc_VendorID = cpboards->cpn_VendorID; |
| 196 | + cpc.cpc_ProductID = cpboards->cpn_ProductID; |
| 197 | + cpc.cpc_Offset = cpboards->cpn_Offset; |
| 198 | + cpc.cpc_CSDelay = 0x03; |
| 199 | + cpc.cpc_AddressSetup = 0x03; |
| 200 | + cpc.cpc_ReadPulse = 0x14; |
| 201 | + cpc.cpc_WritePulse = 0x14; |
| 202 | + AddClockport(&cpc); |
| 203 | +} |
| 204 | + |
| 205 | +/* /// "AddClockport()" */ |
| 206 | +__saveds ULONG AddClockport(struct CPConfig *cpc) |
| 207 | +{ |
| 208 | + struct ConfigDev *confdev = NULL; |
| 209 | + struct ConfigDev *cpconfdev; |
| 210 | + struct Library *ExpansionBase; |
| 211 | + ULONG retval = RETURN_WARN; |
| 212 | + volatile ULONG *hwbase; |
| 213 | + ULONG clkbits; |
| 214 | + |
| 215 | + if(!(ExpansionBase = OpenLibrary("expansion.library", 36))) |
| 216 | + { |
| 217 | + return(RETURN_FAIL); |
| 218 | + } |
| 219 | + |
| 220 | + while(confdev = FindConfigDev(confdev, 0xe3b, 0x10)) /* Deneb: E3B, Product No 0x10 (Zorro III) */ |
| 221 | + { |
| 222 | + cpconfdev = (struct ConfigDev *) confdev->cd_Unused[0]; |
| 223 | + if(!cpconfdev) |
| 224 | + { |
| 225 | + // FIXME check if clockport is available at all! |
| 226 | + cpconfdev = AllocConfigDev(); |
| 227 | + if(!cpconfdev) |
| 228 | + { |
| 229 | + break; |
| 230 | + } |
| 231 | + cpconfdev->cd_Flags = CDF_CONFIGME; |
| 232 | + cpconfdev->cd_Rom.er_Type = ERT_ZORROIII|(1<<ERT_MEMBIT); |
| 233 | + cpconfdev->cd_Rom.er_Flags = ERFF_ZORRO_III; |
| 234 | + cpconfdev->cd_Rom.er_Reserved03 = 0x00; |
| 235 | + cpconfdev->cd_Rom.er_SerialNumber = 0xFA1CB0AD; |
| 236 | + cpconfdev->cd_Rom.er_InitDiagVec = 0; |
| 237 | + cpconfdev->cd_Rom.er_Reserved0c = 0; |
| 238 | + cpconfdev->cd_Rom.er_Reserved0d = 0; |
| 239 | + cpconfdev->cd_Rom.er_Reserved0e = 0; |
| 240 | + cpconfdev->cd_Rom.er_Reserved0f = 0; |
| 241 | + cpconfdev->cd_BoardSize = 64<<10; |
| 242 | + cpconfdev->cd_SlotAddr = confdev->cd_SlotAddr; |
| 243 | + cpconfdev->cd_SlotSize = confdev->cd_SlotSize; |
| 244 | + cpconfdev->cd_Driver = cpconfdev; // mark as used |
| 245 | + cpconfdev->cd_NextCD = NULL; |
| 246 | + AddConfigDev(cpconfdev); |
| 247 | + confdev->cd_Unused[0] = (ULONG) cpconfdev; |
| 248 | + } |
| 249 | + cpconfdev->cd_Rom.er_Manufacturer = cpc->cpc_VendorID; |
| 250 | + cpconfdev->cd_Rom.er_Product = cpc->cpc_ProductID; |
| 251 | + cpconfdev->cd_BoardAddr = ((UBYTE *) confdev->cd_BoardAddr) + (MACH_CLOCKPORT<<2) - (cpc->cpc_Offset & 1); |
| 252 | + hwbase = (ULONG *) confdev->cd_BoardAddr; |
| 253 | + clkbits = MCPCF_INTEN; |
| 254 | + clkbits |= (cpc->cpc_CSDelay<<MCPCS_CSDELAY) & MCPCM_CSDELAY; |
| 255 | + clkbits |= (cpc->cpc_AddressSetup<<MCPCS_ADRSETUP) & MCPCM_ADRSETUP; |
| 256 | + clkbits |= (cpc->cpc_ReadPulse<<MCPCS_READPULSE) & MCPCM_READPULSE; |
| 257 | + clkbits |= (cpc->cpc_WritePulse<<MCPCS_WRITEPULSE) & MCPCM_WRITEPULSE; |
| 258 | + hwbase[MACH_CLKPORTCTRL] = clkbits; |
| 259 | + |
| 260 | + retval = RETURN_OK; |
| 261 | + } |
| 262 | + |
| 263 | + while(confdev = FindConfigDev(confdev, 0xe3b, 0x12)) /* Deneb: E3B, Product No 0x12 (Zorro II) */ |
| 264 | + { |
| 265 | + cpconfdev = (struct ConfigDev *) confdev->cd_Unused[0]; |
| 266 | + if(!cpconfdev) |
| 267 | + { |
| 268 | + // FIXME check if clockport is available at all! |
| 269 | + cpconfdev = AllocConfigDev(); |
| 270 | + if(!cpconfdev) |
| 271 | + { |
| 272 | + break; |
| 273 | + } |
| 274 | + cpconfdev->cd_Flags = CDF_CONFIGME; |
| 275 | + cpconfdev->cd_Rom.er_Type = ERT_ZORROII|(1<<ERT_MEMBIT); |
| 276 | + cpconfdev->cd_Rom.er_Flags = 0; |
| 277 | + cpconfdev->cd_Rom.er_Reserved03 = 0x00; |
| 278 | + cpconfdev->cd_Rom.er_SerialNumber = 0xFA1CB0AD; |
| 279 | + cpconfdev->cd_Rom.er_InitDiagVec = 0; |
| 280 | + cpconfdev->cd_Rom.er_Reserved0c = 0; |
| 281 | + cpconfdev->cd_Rom.er_Reserved0d = 0; |
| 282 | + cpconfdev->cd_Rom.er_Reserved0e = 0; |
| 283 | + cpconfdev->cd_Rom.er_Reserved0f = 0; |
| 284 | + cpconfdev->cd_BoardSize = 64<<10; |
| 285 | + cpconfdev->cd_SlotAddr = confdev->cd_SlotAddr; |
| 286 | + cpconfdev->cd_SlotSize = confdev->cd_SlotSize; |
| 287 | + cpconfdev->cd_Driver = cpconfdev; // mark as used |
| 288 | + cpconfdev->cd_NextCD = NULL; |
| 289 | + AddConfigDev(cpconfdev); |
| 290 | + confdev->cd_Unused[0] = (ULONG) cpconfdev; |
| 291 | + } |
| 292 | + cpconfdev->cd_Rom.er_Manufacturer = cpc->cpc_VendorID; |
| 293 | + cpconfdev->cd_Rom.er_Product = cpc->cpc_ProductID; |
| 294 | + cpconfdev->cd_BoardAddr = ((UBYTE *) confdev->cd_BoardAddr) + (MACH_CLOCKPORT_Z2<<1) - cpc->cpc_Offset; |
| 295 | + hwbase = (ULONG *) confdev->cd_BoardAddr; |
| 296 | + hwbase[MACH_CLKPORTCTRL_Z2] |= MCPCF_INTEN_Z2; |
| 297 | + |
| 298 | + retval = RETURN_OK; |
| 299 | + } |
| 300 | + |
| 301 | + CloseLibrary(ExpansionBase); |
| 302 | + return(retval); |
| 303 | +} |
| 304 | +/* \\\ */ |
| 305 | + |
0 commit comments