-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathrom.S
308 lines (261 loc) · 10.4 KB
/
rom.S
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
**
** A4091 ROM based on
** Sample autoboot code fragment
**
INCLUDE "exec/types.i"
INCLUDE "exec/nodes.i"
INCLUDE "exec/resident.i"
INCLUDE "lvo/exec_lib.i"
INCLUDE "libraries/configvars.i"
INCLUDE "version.i"
*----- We'll store Version and Revision in serial number
VERSION EQU DEVICE_VERSION ; also the high word of serial number
REVISION EQU DEVICE_REVISION ; also the low word of serial number
* See the Amiga Hardware Manual for more info.
MANUF_ID EQU 514 ; Commodore West Chester
PRODUCT_ID EQU 84 ; A4091
ZORRO_III EQU $80
AUTOBOOT_ROM EQU $10
BOARDSIZE_16MB EQU $00
ER_TYPE EQU (ZORRO_III|AUTOBOOT_ROM|BOARDSIZE_16MB)
ZORRO_III_IO EQU $00
ZORRO_III_MEM EQU $80
ZORRO_III_EXT EQU $20
ZORRO_III_RSVD EQU $10
ER_FLAGS EQU (ZORRO_III_IO|ZORRO_III_EXT|ZORRO_III_RSVD)
ROM_VECTOR EQU $0200 ; $80 in the ROM maps to $200 in the system
CODE
* Define DRIVER_BOOT_CRASH_DEBUG to enable debug where driver will
* "fail" to load 1 out of 4 tries. It writes specific registers to
* fixed Physical addresses in fast memory. These are:
* 0x07770000 The try count (only the bottom two bits matter here)
* 0x07770004 A0 board base address
* 0x07770008 A1
* 0x0777000c A2 Diag/init base address
* 0x07770010 A3 board configdev structure
* 0x07770014 A4
* 0x07770018 A5
* 0x0777001c A6
* DRIVER_BOOT_CRASH_DEBUG EQU 1
******* RomStart ***************************************************
**********************************************************************
RomStart
* ExpansionRom structure
*
* On the A4091 the AUTOCONFIG ROM information is encoded in nibbles across
* two 128 byte arrays.
* er_Type is NOT inverted
dc.b ER_TYPE|$0f, ~(PRODUCT_ID)|$0f, ~(ER_FLAGS), $ff
dc.b (~(MANUF_ID)|$0f)&$ff, (~(MANUF_ID>>8)|$0f)&$ff, ~(VERSION>>8), ~(VERSION)
dc.b ~(REVISION>>8), ~(REVISION), ~(ROM_VECTOR>>8)|$0f, ~(ROM_VECTOR)&$ff
dc.b $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
IFNE *-RomStart-$40
FAIL "Even half of ExpansionRom structure not the right size"
ENDC
dc.b ((ER_TYPE<<4)|$0f)&$ff, ~(PRODUCT_ID<<4)&$ff, ~(ER_FLAGS<<4)&$ff, $ff
dc.b ~(MANUF_ID>>4), ~(MANUF_ID<<4)&$ff, ~(VERSION>>4), ~(VERSION<<4)&$ff
dc.b ~(REVISION>>4), ~(REVISION<<4)&$ff, ~(ROM_VECTOR>>4), ~(ROM_VECTOR<<4)&$ff
dc.b $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
dc.b $ff, $ff, $ff, $ff, $ff, $ff, $ff, $ff
IFNE *-RomStart-$80
FAIL "Odd half of ExpansionROM structure not the right size"
ENDC
******* 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_NIBBLEWIDE+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
******* 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.
*
**********************************************************************
* 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
*
* The Diag routine shall 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.
*
DiagEntry
movem.l d2-d7/a2-a6,-(sp)
; Patch up Romtag Resident Structure in memory
lea.l Romtag(pc),a4 ; find Romtag in memory
move.l a4,RT_MATCHTAG(a4) ; pointer to itself
lea.l EndCopy(pc),a1
move.l a1,RT_ENDSKIP(a4)
lea.l DevName(pc),a1
move.l a1,RT_NAME(a4)
lea.l IdString(pc),a1
move.l a1,RT_IDSTRING(a4)
;----------------------------------------------------------
; Check ROM for a4091.device. If it is not there, this
; is a nodevice rom
;----------------------------------------------------------
move.l #(_device-RomStart),d0
bsr InitHandle
move.l #(65536-4),d0
bsr RomFetch32At
cmp.l #$2f434448,d0
bne .try32
; 64k rom
move.l #(65536-12),d0 ; devicelen
bsr RomFetch32At
tst.l d0 ; No device len?
bne .gorelocate
bra .no_resident
.try32
move.l #(32768-4),d0
bsr RomFetch32At
cmp.l #$2f434448,d0
bne .gorelocate ; not 32 or 64k, you're on your own.
; 32k rom
move.l #(32768-12),d0 ; devicelen
bsr RomFetch32At
tst.l d0 ; No device len?
bne .gorelocate
.no_resident
; destroy memory romtag
lea.l Romtag(pc),a4
move.l #0,(a4)
bra .done
.gorelocate
;----------------------------------------------------------
; a0 - base of your board = RomStart?
move.l #(_device-RomStart),d0
bsr _relocate
tst.l d0
bne.s .ok
******* Show checkered purple failure screen **************************
movem.l d2-d3,-(sp)
move.w #$0020,d2
.fc1
move.w #$ffff,d3
.fc2
move.w #$0000,$dff180 ; black
move.w #$0f0c,$dff180 ; purple
dbra d3,.fc2
dbra d2,.fc1
movem.l (sp)+,d2-d3
******* End checkered purple failure screen **************************
moveq.l #0,d0
movem.l (sp)+,d2-d7/a2-a6
rts
.ok
lea.l Romtag(pc),a4 ; find Romtag in memory
move.l d0,a2
addq.l #4,a2
cmp.w #$4afc,4(a2)
beq.s .new_style
.old_style
move.l a2,RT_INIT(a4)
bra.s .done
.new_style
add.l #4+RT_INIT,a2 ; skip _start and find _auto_init_tables
move.l (a2),RT_INIT(a4)
.done
movem.l (sp)+,d2-d7/a2-a6
moveq.l #1,d0 ; indicate "success"
IFD DRIVER_BOOT_CRASH_DEBUG
******* Debug driver boot crash *********
movem.l a0/d1,-(sp)
move.l #_device,d1
move.l a0,d1
move.l #$07770020,a0
movem.l d1/a1-a6,-(a0)
subi #1,-(a0)
move.l (a0),d1
and.l #$03,d1
bne .ok_to_boot
moveq.l #0,d0 ; indicate "fail"
.ok_to_boot
movem.l (sp)+,a0/d1
ENDIF
rts
******* BootEntry **************************************************
**********************************************************************
BootEntry
lea DosName(PC),a1 ; 'dos.library',0
jsr _LVOFindResident(a6) ; find the DOS resident tag
tst.l d0
beq.s .BadBoot
move.l d0,a0 ; in order to bootstrap
move.l RT_INIT(A0),a0 ; set vector to DOS INIT
jsr (a0) ; and initialize DOS
.BadBoot
rts
******* Resident Structure *****************************************
**********************************************************************
Romtag
dc.w RTC_MATCHWORD ; UWORD RT_MATCHWORD
dc.l 0 ; APTR RT_MATCHTAG
dc.l 0 ; APTR RT_ENDSKIP
dc.b RTF_COLDSTART ; UBYTE RT_FLAGS
dc.b VERSION ; UBYTE RT_VERSION
dc.b NT_DEVICE ; UBYTE RT_TYPE
dc.b 10 ; BYTE RT_PRI
dc.l 0 ; APTR RT_NAME
dc.l 0 ; APTR RT_IDSTRING
dc.l 0 ; APTR RT_INIT
; After Diag patching, our romtag will point its Init pointer
; to the auto_init_tables of a4091.device so that it can be
; called at Resident initialization time.
******* Strings referenced in Diag Copy area **************************
*************************************************************************
DevName
dc.b 'a4091.device',0 ; Name string
IdString
dc.b 'A4091 scsidisk '
dc.b 48+VERSION/10,48+VERSION//10,'.'
dc.b 48+REVISION/10,48+REVISION//10,0 ; Id string
DosName
dc.b 'dos.library',0 ; DOS library name
align 1 ; word align
******* Relocation Code ***********************************************
*************************************************************************
ROM EQU 1
INCLUDE "reloc.S"
*
* End of the Diag copy area which is copied to RAM
*
EndCopy
; keep out of the Diag area copied to RAM automatically
section DEVICE
public _device
_device
*************************************************************************
END