** ** Sample autoboot code fragment ** ** These are the calling conventions for the Diag routine ** ** A7 -- points to at least 2K of stack ** A6 -- ExecBase ** A5 -- ExpansionBase ** A3 -- your board's ConfigDev structure ** A2 -- Base of diag/init area that was copied ** A0 -- Base of your board ** ** Your Diag routine should return a non-zero value in D0 for success. ** If this value is NULL, then the diag/init area that was copied ** will be returned to the free memory pool. ** INCLUDE "exec/types.i" INCLUDE "exec/nodes.i" INCLUDE "exec/resident.i" INCLUDE "libraries/configvars.i" ; LVO's resolved by linking with library amiga.lib XREF _LVOFindResident ROMINFO EQU 1 ROMOFFS EQU $0 * ROMINFO defines whether you want the AUTOCONFIG information in * the beginning of your ROM (set to 0 if you instead have PALS * providing the AUTOCONFIG information instead) * * ROMOFFS is the offset from your board base where your ROMs appear. * Your ROMs might appear at offset 0 and contain your AUTOCONFIG * information in the high nibbles of the first $40 words ($80 bytes). * Or, your autoconfig ID information may be in a PAL, with your * ROMs possibly being addressed at some offset (for example $2000) * from your board base. This ROMOFFS constant will be used as an * additional offset from your configured board address when patching * structures which require absolute pointers to ROM code or data. *----- We'll store Version and Revision in serial number VERSION EQU 37 ; also the high word of serial number REVISION EQU 1 ; also the low word of serial number * See the Addison-Wesley Amiga Hardware Manual for more info. MANUF_ID EQU 2011 ; CBM assigned (2011 for hackers only) PRODUCT_ID EQU 1 ; Manufacturer picks product ID BOARDSIZE EQU $40000 ; How much address space board decodes SIZE_FLAG EQU 3 ; Autoconfig 3-bit flag for BOARDSIZE ; 0=$800000(8meg) 4=$80000(512K) ; 1=$10000(64K) 5=$100000(1meg) ; 2=$20000(128K) 6=$200000(2meg) ; 3=$40000(256K) 7=$400000(4meg) CODE ******* RomStart *************************************************** ********************************************************************** RomStart: IFGT ROMINFO ; ; ExpansionRom structure ; ; Note - If you implement your ExpansionRom and ExpansionControl ; with PALS, then you can comment out everything until DiagStart: ; (ie. Make ROMID EQU 0) * ; High nibbles of first two words ($00,$02) are er_Type (not inverted) ; er_Type dc.w $D000 ; 11xx normal board type ; xx0x not in memory free list ; xxx1 Diag valid (has driver) dc.w (SIZE_FLAG<<12)&$7000 ; 0xxx not chained ; xnnn flags board size * ; High nibbles of next two words are er_Product * ; These are inverted (~), as are all other words except $40 and $42 ; er_Product dc.w (~(PRODUCT_ID<<8))&$f000,(~(PRODUCT_ID<<12))&$f000 ; er_Flags dc.w (~$C000)&$f000 ; ~1xxx board is moveable ; ~x1xx board can't be shut up dc.w (~0)&$f000 ; dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved03 ; er_Manufacturer dc.w (~(MANUF_ID))&$f000,(~(MANUF_ID<<4))&$f000 dc.w (~(MANUF_ID<<8))&$f000,(~(MANUF_ID<<12))&$f000 ; er_SerialNumber dc.w (~(VERSION))&$f000,(~(VERSION<<4))&$f000 dc.w (~(VERSION<<8))&$f000,(~(VERSION<<12))&$f000 dc.w (~(REVISION))&$f000,(~(REVISION<<4))&$f000 dc.w (~(REVISION<<8))&$f000,(~(REVISION<<12))&$f000 ; er_InitDiagVec dc.w (~((DiagStart-RomStart)))&$f000 dc.w (~((DiagStart-RomStart)<<4))&$f000 dc.w (~((DiagStart-RomStart)<<8))&$f000 dc.w (~((DiagStart-RomStart)<<12))&$f000 dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved0c dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved0d dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved0e dc.w (~0)&$f000,(~0)&$f000 ; er_Reserved0f IFNE *-RomStart-$40 FAIL "ExpansionRom structure not the right size" ENDC ;Note: nibbles $40 and $42 are not to be inverted dc.w (0)&$f000,(0)&$f000 ; ec_Interrupt (no interrupts) dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved11 dc.w (~0)&$f000,(~0)&$f000 ; ec_BaseAddress (write only) dc.w (~0)&$f000,(~0)&$f000 ; ec_Shutup (write only) dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved14 dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved15 dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved16 dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved17 dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved18 dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved19 dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1a dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1b dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1c dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1d dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1e dc.w (~0)&$f000,(~0)&$f000 ; ec_Reserved1f IFNE *-RomStart-$80 FAIL "Expansion Control structure not the right size" ENDC ENDC ;ROMINFO ******* DiagStart ************************************************** DiagStart: ; This is the DiagArea structure whose relative offset from ; your board base appears as the Init Diag vector in your ; autoconfig ID information. This structure is designed ; to use all relative pointers (no patching needed). dc.b DAC_WORDWIDE+DAC_CONFIGTIME ; da_Config dc.b 0 ; da_Flags dc.w EndCopy-DiagStart ; da_Size dc.w DiagEntry-DiagStart ; da_DiagPoint dc.w BootEntry-DiagStart ; da_BootPoint dc.w DevName-DiagStart ; da_Name dc.w 0 ; da_Reserved01 dc.w 0 ; da_Reserved02 ******* Resident Structure ***************************************** Romtag: dc.w RTC_MATCHWORD ; UWORD RT_MATCHWORD rt_Match: dc.l Romtag-DiagStart ; APTR RT_MATCHTAG rt_End: dc.l EndCopy-DiagStart ; APTR RT_ENDSKIP dc.b RTW_COLDSTART ; UBYTE RT_FLAGS dc.b VERSION ; UBYTE RT_VERSION dc.b NT_DEVICE ; UBYTE RT_TYPE dc.b 20 ; BYTE RT_PRI rt_Name: dc.l DevName-DiagStart ; APTR RT_NAME rt_Id: dc.l IdString-DiagStart ; APTR RT_IDSTRING rt_Init: dc.l Init-RomStart ; APTR RT_INIT ******* Strings referenced in Diag Copy area ************************ DevName: dc.b 'abc.device',0 ; Name string IdString dc.b 'abc ',48+VERSION,'.',48+REVISION ; Id string DosName: dc.b 'dos.library',0 ; DOS library name DosDevName: dc.b 'ABC',0 ; dos device name for MakeDosNode() ; (dos device will be ABC:) ds.w 0 ; word align ******* DiagEntry ************************************************** ********************************************************************** * * success = DiagEntry(BoardBase,DiagCopy, configDev) * d0 a0 a2 a3 * * Called by expansion architecture to relocate any pointers * in the copied diagnostic area. We will patch the romtag. * If you have pre-coded your MakeDosNode packet, BootNode, * or device initialization structures, they would also need * to be within this copy area, and patched by this routine. * ********************************************************************** DiagEntry: lea patchTable-RomStart(a0),a1 ; find patch table adda.l #ROMOFFS,a1 ; adjusting for ROMOFFS * Patch relative pointers to labels within DiagCopy area * by adding Diag RAM copy address. These pointers were coded as * long relative offsets from base of the DiagArea structure. * dpatches: move.l a2,d1 ;d1=base of ram Diag copy dloop: move.w (a1)+,d0 ;d0=word offs. into Diag needing patch bmi.s bpatches ;-1 is end of word patch offset table add.l d1,0(a2,d0.w) ;add DiagCopy addr to coded rel. offset bra.s dloop * Patches relative pointers to labels within the ROM by adding * the board base address + ROMOFFS. These pointers were coded as * long relative offsets from RomStart. * bpatches: move.l a0,d1 ;d1 = board base address add.l #ROMOFFS,d1 ;add offset to where your ROMs are rloop: move.w (a1)+,d0 ;d0=word offs. into Diag needing patch bmi.s endpatches ;-1 is end of patch offset table add.l d1,0(a2,d0.w) ;add ROM address to coded relative offset bra.s rloop endpatches: moveq.l #1,d0 ; indicate "success" rts ******* BootEntry ************************************************** ********************************************************************** BootEntry: lea DosName(PC),a1 ; 'dos.library',0 jsr _LVOFindResident(a6) ; find the DOS resident tag move.l d0,a0 ; in order to bootstrap move.l RT_INIT(A0),a0 ; set vector to DOS INIT jsr (a0) ; and initialize DOS rts * * End of the Diag copy area which is copied to RAM * EndCopy: ************************************************************************* ************************************************************************* * * Beginning of ROM driver code and data that is accessed only in * the ROM space. This must all be position-independent. * patchTable: * Word offsets into Diag area where pointers need Diag copy address added dc.w rt_Match-DiagStart dc.w rt_End-DiagStart dc.w rt_Name-DiagStart dc.w rt_Id-DiagStart dc.w -1 * Word offsets into Diag area where pointers need boardbase+ROMOFFS added dc.w rt_Init-DiagStart dc.w -1 ******* Romtag InitEntry ********************************************** ************************************************************************* Init: ; After Diag patching, our romtag will point to this ; routine in ROM so that it can be called at Resident ; initialization time. ; This routine will be similar to a normal expansion device ; initialization routine, but will MakeDosNode then set up a ; BootNode, and Enqueue() on eb_MountList. ; rts ; Rest of your position-independent device code goes here. END