mirror of
https://github.com/LIV2/CIDER-Software.git
synced 2025-12-06 00:23:50 +00:00
Add IDE boot rom
This commit is contained in:
parent
fae07c034a
commit
061e307e06
5
iderom/.gitignore
vendored
Normal file
5
iderom/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
obj/**
|
||||
at
|
||||
*.rom
|
||||
**/*.o
|
||||
**/*.out
|
||||
37
iderom/Makefile
Normal file
37
iderom/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
PROGRAM=cider.rom
|
||||
INCLUDE=/opt/amiga/m68k-amigaos/ndk-include
|
||||
AS=vasmm68k_mot
|
||||
ASFLAGS=-Fhunk -I$(INCLUDE) -quiet -align
|
||||
LINKER=vlink
|
||||
LINKFLAGS=-brawbin1 -s -sc -sd -mrel
|
||||
OBJDIR=obj
|
||||
|
||||
.PHONY: all clean rom
|
||||
|
||||
SRCS = bootldr.S
|
||||
OBJS = $(SRCS:%.S=$(OBJDIR)/%.o)
|
||||
|
||||
all: $(PROGRAM)
|
||||
|
||||
$(OBJDIR)/mungerom: mungerom.c
|
||||
@mkdir -p $(OBJDIR)
|
||||
$(CC) $< -Wall -o $@
|
||||
|
||||
$(OBJDIR)/%.o: %.S
|
||||
@mkdir -p $(OBJDIR)
|
||||
$(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
$(OBJDIR)/bootldr: $(OBJDIR)/bootldr.o
|
||||
$(LINKER) $(LINKFLAGS) -o $@ $<
|
||||
|
||||
$(OBJDIR)/bootnibbles: $(OBJDIR)/bootldr $(OBJDIR)/mungerom
|
||||
@mkdir -p $(OBJDIR)
|
||||
./obj/mungerom
|
||||
|
||||
$(PROGRAM): $(OBJDIR)/bootnibbles $(OBJDIR)/assets.o
|
||||
$(LINKER) $(LINKFLAGS) -Trom.ld -o $@ $(OBJDIR)/assets.o
|
||||
|
||||
clean:
|
||||
rm -f $(OBJDIR)/*
|
||||
rm -f $(PROGRAM)
|
||||
rm -f mungerom
|
||||
3
iderom/README.md
Normal file
3
iderom/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
## ide boot rom
|
||||
|
||||
WIP for the IDE driver, currently just loads Oktapus driver from ROM
|
||||
5
iderom/assets.S
Normal file
5
iderom/assets.S
Normal file
@ -0,0 +1,5 @@
|
||||
section BOOTLDR
|
||||
incbin "obj/bootnibbles"
|
||||
|
||||
section DEVICE
|
||||
incbin "cider.device"
|
||||
147
iderom/bootldr.S
Normal file
147
iderom/bootldr.S
Normal file
@ -0,0 +1,147 @@
|
||||
; Based on rom.S from Open Source A4091.device by Stefan Reinauer & Chris Hooper
|
||||
include libraries/configvars.i
|
||||
include exec/resident.i
|
||||
include lvo/exec_lib.i
|
||||
|
||||
|
||||
VERSION = 0
|
||||
REVISION = 1
|
||||
ROMOFFSET = $2000
|
||||
|
||||
******* 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)
|
||||
|
||||
move.l #ROMOFFSET,d0
|
||||
bsr _relocate
|
||||
tst.l d0
|
||||
|
||||
bne.s .ok
|
||||
.err
|
||||
******* 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
|
||||
move.l #$1000,d3
|
||||
|
||||
move.l d0,a2
|
||||
.findrt cmpi.w #$4AFC,(a2)
|
||||
beq.s .found
|
||||
addq.l #2,a2
|
||||
dbra d3,.findrt
|
||||
bra.s .err
|
||||
|
||||
.found lea.l Romtag(pc),a4 ; find Romtag in memory
|
||||
move.l RT_INIT(a2),d0
|
||||
move.l d0,RT_INIT(a4)
|
||||
|
||||
moveq.l #1,d0 ; indicate "success"
|
||||
.done
|
||||
movem.l (sp)+,d2-d7/a2-a6
|
||||
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 0 ; UBYTE RT_TYPE
|
||||
dc.b 0 ; BYTE RT_PRI
|
||||
dc.l 0 ; APTR RT_NAME
|
||||
dc.l 0 ; APTR RT_IDSTRING
|
||||
dc.l 0 ; APTR RT_INIT
|
||||
|
||||
******* Strings referenced in Diag Copy area **************************
|
||||
*************************************************************************
|
||||
DevName
|
||||
dc.b 'Oktagon',0 ; Name string
|
||||
align 1
|
||||
IdString
|
||||
dc.b 'Oktagon',0
|
||||
DosName
|
||||
dc.b 'dos.library',0 ; DOS library name
|
||||
align 1 ; word align
|
||||
|
||||
include reloc.S
|
||||
EndCopy:
|
||||
33
iderom/mungerom.c
Normal file
33
iderom/mungerom.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Chop up the bootrom section into nibbles for Z2 nibblewise bootrom - Kick 1.3 and below don't support DAC_BYTEWIDE :(
|
||||
// The device driver will be loaded bytewise by reloc
|
||||
int main () {
|
||||
FILE *fh = fopen("obj/bootldr","r");
|
||||
|
||||
char *src,*dst = NULL;
|
||||
|
||||
src = malloc(2048);
|
||||
dst = malloc(4096);
|
||||
|
||||
int len = fread(src,1,2048,fh);
|
||||
fclose(fh);
|
||||
for (int i=0; i<len;i++) {
|
||||
char hi = *(src+i) & 0xF0;
|
||||
char lo = *(src+i) & 0x0F;
|
||||
lo <<= 4;
|
||||
dst[i<<1] = hi;
|
||||
dst[(i<<1)+1] = lo;
|
||||
}
|
||||
|
||||
fh = fopen("obj/bootnibbles","w");
|
||||
|
||||
fwrite(dst,1,len*2,fh);
|
||||
|
||||
fclose(fh);
|
||||
|
||||
free(src);
|
||||
free(dst);
|
||||
}
|
||||
328
iderom/reloc.S
Normal file
328
iderom/reloc.S
Normal file
@ -0,0 +1,328 @@
|
||||
; reloc
|
||||
; Modified from Open Source A4091.device reloc.S by Stefan Reinauer & Chris Hooper
|
||||
INCLUDE "exec/memory.i"
|
||||
INCLUDE "lvo/exec_lib.i"
|
||||
|
||||
NUM_ENTRIES EQU 5
|
||||
|
||||
; API:
|
||||
; Z2 ROM access:
|
||||
; a0: rombase
|
||||
; d0: offset
|
||||
; Memory (RAM) access:
|
||||
; a0: pointer to binary
|
||||
; d0: 0
|
||||
public _relocate
|
||||
_relocate
|
||||
movem.l d1-d7/a0-a6,-(sp)
|
||||
|
||||
bsr InitHandle
|
||||
|
||||
; fetch file header
|
||||
bsr RomFetch32
|
||||
cmp.l #$3f3,d0 ; We only know hunk_hdr
|
||||
bne .RelocateFail
|
||||
|
||||
; consume the header and remember number of hunks
|
||||
bsr RomFetch32
|
||||
bsr RomFetch32
|
||||
move.l d0,d7 ; table size
|
||||
subq.l #1,d7
|
||||
move.l d7,d6 ; for HUNK_END
|
||||
bsr RomFetch32
|
||||
bsr RomFetch32
|
||||
|
||||
; Go through hunk header and allocate all segments
|
||||
move.l 4,a6 ; execbase
|
||||
|
||||
move.l pHunks(pc),a2 ; segment pointers
|
||||
lea.l 4*NUM_ENTRIES(a2),a3 ; segment lengths
|
||||
.AllocateLoop
|
||||
moveq.l #MEMF_PUBLIC,d1
|
||||
bsr RomFetch32
|
||||
lsl.l #2,d0
|
||||
move.l d0,(a3)+ ; segment length
|
||||
addq.l #8,d0 ; Add 8 for seglist overhead
|
||||
jsr _LVOAllocMem(a6)
|
||||
tst.l d0
|
||||
beq.s .RelocateFail
|
||||
addq.l #8,d0 ; Skip seglist overhead
|
||||
move.l d0,(a2)+ ; segment pointer
|
||||
dbra d7,.AllocateLoop
|
||||
|
||||
move.l pHunks(pc),a5
|
||||
.HunkLoop
|
||||
move.l (a5),a0 ; current hunk
|
||||
bsr RomFetch32
|
||||
|
||||
cmp.l #$3e9,d0
|
||||
beq .HunkCode
|
||||
cmp.l #$3ea,d0
|
||||
beq .HunkData
|
||||
cmp.l #$3eb,d0
|
||||
beq .HunkBSS
|
||||
cmp.l #$3ec,d0
|
||||
beq .HunkReloc32
|
||||
cmp.l #$3fc,d0
|
||||
beq .HunkReloc32Short
|
||||
cmp.l #$3f7,d0
|
||||
beq .HunkDRel32
|
||||
cmp.l #$3f0,d0
|
||||
beq .HunkSymbol
|
||||
cmp.l #$3f2,d0
|
||||
beq .HunkEnd
|
||||
|
||||
; We don't know this hunk
|
||||
.RelocateFail
|
||||
IFD HAVE_ERRNO
|
||||
; Save hunk number in rErrno as error code
|
||||
lea _rErrno(pc),a0
|
||||
move.l d0,(a0)
|
||||
ENDIF
|
||||
bsr .RelocateCleanup
|
||||
moveq.l #0,d0 ; NULL = Failure
|
||||
movem.l (sp)+,d1-d7/a0-a6
|
||||
rts
|
||||
|
||||
; ---------------------
|
||||
|
||||
.HunkData
|
||||
.HunkCode
|
||||
bsr RomFetch32
|
||||
move.l d0,d7
|
||||
subq.l #1,d7
|
||||
.CopyHunk
|
||||
bsr RomFetch32
|
||||
move.l d0,(a0)+
|
||||
dbra d7,.CopyHunk
|
||||
bra .HunkLoop
|
||||
|
||||
; ---------------------
|
||||
|
||||
.HunkBSS
|
||||
bsr RomFetch32
|
||||
move.l d0,d7
|
||||
subq.l #1,d7
|
||||
; hunk address in a0
|
||||
.ClearBSS
|
||||
move.l #$0,(a0)+
|
||||
dbra d7,.ClearBSS
|
||||
|
||||
bra .HunkLoop
|
||||
|
||||
; ---------------------
|
||||
|
||||
.HunkReloc32
|
||||
bsr RomFetch32
|
||||
|
||||
tst.l d0 ; if len is zero the reloc32 block is done
|
||||
beq .HunkLoop
|
||||
|
||||
move.l d0,d1 ; len ; number of offsets for a given hunk
|
||||
subq.l #1,d1 ; for dbra
|
||||
|
||||
bsr RomFetch32
|
||||
move.l d0,d2 ; num ; number of the hunk the offsets are to point into
|
||||
|
||||
lsl.l #2,d2 ; *4 ; offset from Hunks
|
||||
move.l pHunks(pc),a2
|
||||
add.l d2,a2 ; hunk number num
|
||||
move.l (a2),d3 ; base address of hunk
|
||||
|
||||
.Reloc32Tight
|
||||
bsr RomFetch32
|
||||
; get baseaddr + d0, add d3 to the data there.
|
||||
move.l a0,a4
|
||||
add.l d0,a4
|
||||
add.l d3,(a4)
|
||||
dbra d1,.Reloc32Tight
|
||||
|
||||
bra .HunkReloc32
|
||||
; ---------------------
|
||||
|
||||
.HunkDRel32
|
||||
.HunkReloc32Short
|
||||
bsr RomFetch16
|
||||
|
||||
tst.l d0 ; if len is zero the reloc32 block is done
|
||||
beq .HunkLoopPrep
|
||||
|
||||
move.l d0,d1 ; len ; number of offsets for a given hunk
|
||||
subq.l #1,d1 ; for dbra
|
||||
|
||||
bsr RomFetch16
|
||||
move.l d0,d2 ; num ; number of the hunk the offsets are to point into
|
||||
|
||||
lsl.l #2,d2 ; *4 ; offset from Hunks
|
||||
move.l pHunks(pc),a2
|
||||
add.l d2,a2 ; hunk number num
|
||||
move.l (a2),d3 ; base address of hunk
|
||||
|
||||
.Reloc32ShortTight
|
||||
bsr RomFetch16
|
||||
; get baseaddr + d0, add d3 to the data there.
|
||||
move.l a0,a4
|
||||
add.l d0,a4
|
||||
add.l d3,(a4)
|
||||
dbra d1,.Reloc32ShortTight
|
||||
|
||||
bra .HunkReloc32Short
|
||||
.HunkLoopPrep
|
||||
lea ReadHandle(pc),a2
|
||||
move.l (a2),d0 ; align pointer to longword
|
||||
addq.l #2,d0 ; in case we had an odd number
|
||||
and.l #$fffffffc,d0 ; of relocations
|
||||
move.l d0,(a2)
|
||||
bra .HunkLoop
|
||||
; ---------------------
|
||||
|
||||
.HunkSymbol
|
||||
bsr RomFetch32
|
||||
tst.l d0
|
||||
beq .HunkLoop
|
||||
move.l d0,d7
|
||||
.SkipSymbol
|
||||
bsr RomFetch32
|
||||
dbra d7,.SkipSymbol
|
||||
bra .HunkSymbol
|
||||
|
||||
; ---------------------
|
||||
|
||||
.HunkEnd
|
||||
addq.l #4,a5
|
||||
dbra d6,.HunkLoop
|
||||
IFD HAVE_ERRNO
|
||||
lea _rErrno(pc),a0
|
||||
move.l #0,(a0)
|
||||
ENDIF
|
||||
|
||||
bsr.s CreateSegList
|
||||
|
||||
move.l pHunks(pc),a0
|
||||
move.l (a0),d2
|
||||
subq.l #4,d2
|
||||
|
||||
bsr.s .RelocateCleanup
|
||||
move.l d2,d0
|
||||
movem.l (sp)+,d1-d7/a0-a6
|
||||
rts
|
||||
|
||||
.RelocateCleanup
|
||||
move.l pHunks(pc),a1
|
||||
moveq.l #(8*NUM_ENTRIES),d0
|
||||
jsr _LVOFreeMem(a6)
|
||||
rts
|
||||
|
||||
; ---------------------
|
||||
|
||||
; +--------------------+
|
||||
; | seg length (longs) | <-- = pHunks[x+NUM_ENTRIES]
|
||||
; +--------------------+ <-- seglist returned
|
||||
; | bptr to next seg | <-- = pHunks[x+1]
|
||||
; +--------------------+ <-- pHunks[x] points here
|
||||
; | segment data (also |
|
||||
; | first entry point) |
|
||||
; |/\/\/\/\/\/\/\/\/\/\|
|
||||
|
||||
; pHunks -+ Hunk Pointers Hunk Lengths
|
||||
; | +--+--+--+--+ +--+--+--+--+
|
||||
; +->| | | | 0| | | | | 0|
|
||||
; +--+--+--+--+ +--+--+--+--+
|
||||
CreateSegList:
|
||||
move.l pHunks(pc),a0
|
||||
|
||||
.NextSeg
|
||||
move.l (a0),a1 ; Hunks[x]
|
||||
|
||||
move.l 4*NUM_ENTRIES(a0),d0 ; length of current hunk
|
||||
addq.l #8,d0 ; add header size
|
||||
lsr.l #2,d0 ; MKBADDR
|
||||
move.l d0,-8(a1) ; write seg size
|
||||
|
||||
addq.l #4,a0
|
||||
move.l (a0),d0 ; next hunk
|
||||
tst.l d0 ; hunk addr zero?
|
||||
beq .SegListDone ; we're done
|
||||
subq.l #4,d0 ; else: point to linked list
|
||||
lsr.l #2,d0 ; MKBADDR
|
||||
move.l d0,-4(a1) ; write BPTR to next hunk
|
||||
|
||||
bra.s .NextSeg
|
||||
|
||||
.SegListDone
|
||||
move.l d0,-4(a1) ; terminate seglist
|
||||
rts
|
||||
|
||||
; ---------------------
|
||||
|
||||
; data = RomFetch32(void)
|
||||
; d0
|
||||
RomFetch16
|
||||
moveq #1,d0
|
||||
bra.s RomFetch
|
||||
RomFetch32
|
||||
moveq #3,d0
|
||||
|
||||
RomFetch
|
||||
movem.l a0-a1/d1-d3,-(sp)
|
||||
lea ReadHandle(pc),a1
|
||||
move.l (a1),a0
|
||||
|
||||
tst.l 4(a1) ; access type ZorroII?
|
||||
bne.s .RomFetchZ2
|
||||
|
||||
cmp.b #3,d0
|
||||
bne.b .RomFetchWord
|
||||
move.l (a0)+,d0 ; access type is memory
|
||||
bra.s .RomFetchDone
|
||||
.RomFetchWord
|
||||
move.w (a0)+,d0
|
||||
bra.s .RomFetchDone
|
||||
|
||||
.RomFetchZ2 ; access type is ZorroII
|
||||
move.l d0,d3
|
||||
.nextbyte
|
||||
lsl.l #8,d0
|
||||
move.b (a0),d0
|
||||
addq #2,a0
|
||||
dbra d3,.nextbyte
|
||||
|
||||
.RomFetchDone
|
||||
move.l a0,(a1)
|
||||
movem.l (sp)+,a0-a1/d1-d3
|
||||
rts
|
||||
|
||||
InitHandle
|
||||
; initialize readhandle to beginning of device driver
|
||||
; ROM_OFFSET needs to be multiplied by 4 because of the
|
||||
; nibble mapped nature of the AutoConfig ROM.
|
||||
; ROM_ADDRESS is passed in a0
|
||||
; ROM_OFFSET is passed in d0
|
||||
|
||||
;lsl.l #2,d0
|
||||
|
||||
add.l d0,a0
|
||||
lea ReadHandle(pc),a1
|
||||
move.l a0,(a1) ; memory location passed in a0
|
||||
move.l d0,4(a1) ; Set access type: 0 = memory, Z2 otherwise
|
||||
|
||||
moveq.l #(8*NUM_ENTRIES),d0
|
||||
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
|
||||
jsr _LVOAllocMem(a6)
|
||||
lea pHunks(pc),a1
|
||||
move.l d0,(a1)
|
||||
rts
|
||||
|
||||
ReadHandle
|
||||
dc.l 0 ; Current address
|
||||
dc.l 0 ; 0=memory, otherwise Z2
|
||||
|
||||
pHunks
|
||||
dc.l 0
|
||||
|
||||
IFD HAVE_ERRNO
|
||||
public _rErrno
|
||||
_rErrno
|
||||
dc.l 0
|
||||
ENDIF
|
||||
CODE
|
||||
13
iderom/rom.ld
Normal file
13
iderom/rom.ld
Normal file
@ -0,0 +1,13 @@
|
||||
SECTIONS {
|
||||
rom = .;
|
||||
.bootldr : {
|
||||
*(BOOTLDR)
|
||||
}
|
||||
.device 0x1000 : {
|
||||
*(DEVICE)
|
||||
}
|
||||
.fill : {
|
||||
FILL8(0xFF);
|
||||
RESERVE(0x8000-.);
|
||||
} =0xffff
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user