15 May 2022, 18:29 | #21 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,537
|
Quote:
Quote:
t_rawseg.c. Here it is: Code:
static const char defaultscript[] = "PHDRS {\n" " text PT_LOAD;\n" " data PT_LOAD;\n" "}\n" "SECTIONS {\n" " .text: { *(.text*) *(CODE*) *(text*) *(seg*) } :text\n" " .data: { *(.data*) *(DATA*) *(data*) } :data\n" " .bss: { *(.bss*) *(BSS*) *(bss*) }\n" "}\n"; |
||
15 May 2022, 20:35 | #22 |
Registered User
Join Date: Apr 2019
Location: UK
Posts: 228
|
Thanks. I should have thought of looking in there.
I have used your game.ld linker script (as posted in other threads) and - despite not understanding it fully - it seems to be working fine and does just what I want. I haven't tried handling BSS sections yet, but working fine for my test case of a single "fast" (public) code section and single "chipmem" data section. The loader is: Code:
INCLUDE "exec/execbase.i" ; AttnFlags, CACR INCLUDE "exec/io.i" ; STRUCTURE IO INCLUDE "exec/memory.i" INCLUDE "devices/trackdisk.i" INCLUDE "lvo/exec_lib.i" ; --------------------------------------------------------------------------- MIN_SUPPORTED_OS_VERSION EQU 34 ; Want this to work on Kickstart 1.3 ; --------------------------------------------------------------------------- SECTOR_SIZE_BYTES EQU 512 ; $200 TD_SECTOR from devices/trackdisk.i SECTORS_PER_TRACK EQU 11 ; NUMSECS from devices/trackdisk.i TRACK_SIZE_BYTES EQU SECTOR_SIZE_BYTES*SECTORS_PER_TRACK ; $1600 BOOTBLOCK_SIZE_BYTES EQU 2*SECTOR_SIZE_BYTES ; 1024 = $400 ; --------------------------------------------------------------------------- ORG 0 ; BB Header DC.B 'DOS',0 ; BB_ID - Always has to be DOS\0 DC.L $0 ; BB_CHKSUM - Fix up with FixBootblockChecksum after assembling DC.L 880 ; BB_DOSBLOCK - Rootblock location for DOS disks ; --------------------------------------------------------------------------- ; BB_ENTRY (start of executable code) ; A6 = ExecBase ; A1 = Trackdisk IOStdReq (open and ready to use) movea.l a1,a2 ; A2 <- IOStdReq because system calls (AllocMem) can trash A0 and A1 ; Allocate temp Chip RAM IO buffer to trackdisk read of "fast" segement move.l #fastSegmentDiskSizeBytes,d0 ; D0 <- bytesize move.l #MEMF_CHIP,d1 ; KS1.3 required trackdisk buffer to be in Chip RAM jsr _LVOAllocMem(a6) tst.l d0 beq error movea.l d0,a3 ; A3 <- temp Chip RAM IO buffer ; Trackdisk IO read "fast" segment into buffer ; n.b. Next instruction really redundant because IOStdReq IO_COMMAND already equals 2 from the OS loading the bootblock movea.l a2,a1 ; A1 <- IOStdReq move.w #CMD_READ,IO_COMMAND(a1) ; CMD_READ = 2, IO_COMMAND = $1C = 28 move.l #fastSegmentDiskOffsetBytes,IO_OFFSET(a1) ; IO_OFFSET = $2c = 44 move.l #fastSegmentDiskSizeBytes,IO_LENGTH(a1) ; IO_LENGTH = $24 = 36 move.l d0,IO_DATA(a1) ; IO_DATA = $28 = 40 jsr _LVODoIO(a6) ; -456 tst.l d0 ; 0 means OK bne error ; Allocate permanent buffer for "fast" segment or best memory type (Fast or Chip RAM depending on machine) move.l #fastSegmentSizeBytes,d0 ; D0 <- bytesize move.l #0,d1 ; Allocate the best available memory jsr _LVOAllocMem(a6) tst.l d0 beq error movea.l d0,a4 ; A4 <- "fast" segment buffer ; Copy "fast" segment into "public" memory, which could be either Chip or Fast depending on machine movea.l a3,a0 ; temp Chip RAM IO buffer movea.l a4,a1 ; dest move.l #fastSegmentSizeBytes,d0 jsr _LVOCopyMem(a6) ; CopyMem(A0=source:APTR, A1=dest:APTR, D0=sizeBytes:ULONG ) ; Free temp Chip RAM IO buffer movea.l a3,a1 move.l #fastSegmentDiskSizeBytes,d0 jsr _LVOFreeMem(a6) ; FreeMem(A1=memoryBlock:APTR, D0=byteSize:ULONG) ; Allocate permanent Chip RAM buffer for "chip" segment. Trackdisk can read directly into this buffer on KS1.x move.l #chipSegmentDiskSizeBytes,d0 ; D0 <- bytesize move.l #MEMF_CHIP,d1 jsr _LVOAllocMem(a6) tst.l d0 beq error movea.l d0,a3 ; A3 <- "chip" segment buffer ; Trackdisk IO read "chip" segment into buffer ; n.b. Next instruction really redundant because IOStdReq IO_COMMAND already equals 2 from the OS loading the bootblock movea.l a2,a1 ; A1 <- IOStdReq move.w #CMD_READ,IO_COMMAND(a1) ; CMD_READ = 2, IO_COMMAND = $1C = 28 move.l #chipSegmentDiskOffsetBytes,IO_OFFSET(a1) ; IO_OFFSET = $2c = 44 move.l #chipSegmentDiskSizeBytes,IO_LENGTH(a1) ; IO_LENGTH = $24 = 36 move.l d0,IO_DATA(a1) ; IO_DATA = $28 = 40 jsr _LVODoIO(a6) ; -456 tst.l d0 ; 0 means OK bne error ; Turn off drive motor ; Reading from disk automatically turns the motor on, but the use must turn it off movea.l a2,a1 ; Restore A1 <- IOStdReq which could have been corrupted by _LVODoIO move.w #TD_MOTOR,IO_COMMAND(a1) ; TD_MOTOR = 9, IO_COMMAND = $1C = 28 move.l #0,IO_LENGTH(a1) ; 0 = off, IO_LENGTH = $24 = 36 jsr _LVODoIO(a6) ; -456 tst.l d0 ; 0 means OK bne error ; relocate "fast" section references to "chip" section movea.l a4,a0 ; A0 <- "fast" segment movea.l a3,a1 ; A1 <- "chip" segment lea fast_relchip(pc),a2 bsr.b relocateFastSegment ; relocate "fast" section references to "fast" section (internal references) movea.l a4,a0 ; A0 <- "fast" segment movea.l a4,a1 ; A1 <- "fast" segment lea fast_relfast(pc),a2 bsr.b relocateFastSegment ; n.b. There is no need to relocate the "chip" segment because is should contain no code or internal references ; Invalidate the instruction cache for 68020+ CPUs ; Required in case any of the relocated (modified) code cached on CPU and needs to be refetched from RAM ; https://eab.abime.net/showthread.php?t=108920 IF MIN_SUPPORTED_OS_VERSION>=37 jsr _LVOCacheClearU(a6) ; V37 (Kickstart 2.04) Cannot be called on KS1.3 ELSE btst #AFB_68020,AttnFlags+1(a6) ; 68020+ ? beq executeFastSegment ; No? No caches to invalidate lea invalidateInstructionCache(pc),a5 ; Supervisor userfunc jsr _LVOSupervisor(a6) ENDIF executeFastSegment jmp (a4) error moveq #$FFFFFFFF,d0 ; boot failure code rts ; --------------------------------------------------------------------------- ; Applies relocations to the "fast" segment ; ; A1 = address of segment containing referenced data ("chip" or "fast") ; A2 = address of rawseg -q relocation table ; A4 = address of fast semgent ; Modifies: D0,A0,A1 ; relocateFastSegment: move.l (a2)+,d1 ; D1 <- reloc table entry count (each is one longword). A1 <- address of first offset in table .loop tst.l d1 ; finished? beq.b .end ; yes? subq.l #1,d1 ; dec reloc count ; read offset move.l (a2)+,d0 ; D0 <- offset to relocate movea.l a4,a0 ; A0 <- address of "fast" segment adda.l d0,a0 ; A0 <- address of longword in "fast" segment to relocate move.l (a0),d0 ; D0 <- segment-relative address ; transform segment-relative address to absolute address add.l a1,d0 ; Add segment base address. D0 <- absolute address move.l d0,(a0) ; store absolute address bra.b .loop ; next offset .end rts ; --------------------------------------------------------------------------- ; Invalidates instruction cache on 68020+ CPUs ; This is a Userfunc called by Exec Supervisor() so must return with RTE ; Only call on 68020+ CPUs (check AttnFlags before calling) else guru ; See: ; - http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node000C.html ; - https://eab.abime.net/showthread.php?t=108920 ; - https://eab.abime.net/showpost.php?p=1377521&postcount=7 ; invalidateInstructionCache: MC68020 ; VASM M68K CPU module extension to generate code for 68020+ (allow movec cacr,d0) movec cacr,d0 btst #15,d0 ; 68040/060 bit 15 IE = Enable Instruction Cache bne .68040 or.w #CACRF_ClearI|CACRF_ClearD,d0 ; Clear (invalidate) instruction cache and data cache if exists (68030+) movec d0,cacr MC68000 bra .exit .68040 MC68040 CPUSHA BC MC68000 .exit rte ; n.b. Supervisor() userfunc must end with RTE ; --------------------------------------------------------------------------- ; "fast" section relocation table ; Just include the relocation table directly in the bootblock for now. ; TODO: If relocation tables grow too big for bootblock, then move out of bootblock, load dynamically ; and dispose of when done EVEN fast_relchip INCBIN "vasm_rawseg_loadfile.rawseg.fast.relchip" fast_relchip_end EVEN fast_relfast INCBIN "vasm_rawseg_loadfile.rawseg.fast.relfast" fast_relfast_end ; --------------------------------------------------------------------------- ; Bootblock end PRINTT "Bootblock size (bytes):" PRINTV * ASSERT *<=BOOTBLOCK_SIZE_BYTES,"Bootblock code exceeds max bootblock size (1024 bytes)" ; Requires pre-release version of VASM. See https://eab.abime.net/showpost.php?p=1542732&postcount=14 ; --------------------------------------------------------------------------- ; Write load file segments to disk starting from track 1 ; Track 1 ($1600) ORG 1*TRACK_SIZE_BYTES ; The "fast" segment is really "public" i.e. it could reside in either Chip or Fast RAM. ; It contains the code entry point that will be jumped to by bootblock ; This could be pre-assembled and position independent, not requiring any relocations ; after loading, but more than likely the fast.relfast and fast.relchip relocation tables will ; be applied. fastSegmentDiskOffsetBytes INCBIN "vasm_rawseg_loadfile.rawseg.fast" fastSegmentSizeBytes EQU *-fastSegmentDiskOffsetBytes CNOP 0,SECTOR_SIZE_BYTES ; Pad to end of sector for trackdisk loading fastSegmentDiskOffsetBytes_end fastSegmentDiskSizeBytes EQU fastSegmentDiskOffsetBytes_end-fastSegmentDiskOffsetBytes ; The "chip" segment must be loaded into Chip RAM. It usually just contains data and no code. chipSegmentDiskOffsetBytes INCBIN "vasm_rawseg_loadfile.rawseg.chip" CNOP 0,SECTOR_SIZE_BYTES ; Pad to end of sector for trackdisk loading chipSegmentDiskOffsetBytes_end chipSegmentDiskSizeBytes EQU chipSegmentDiskOffsetBytes_end-chipSegmentDiskOffsetBytes END Last edited by hop; 15 May 2022 at 20:35. Reason: Clarification |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Anyone help with a pic of wb 3.1 on 4:3 tv? | cypher007 | support.Hardware | 14 | 30 June 2020 08:18 |
Wave Pic | pmc | Coders. Tutorials | 18 | 03 June 2009 18:37 |
It's... Request-a-pic! | Shoonay | EAB's competition | 42 | 05 July 2008 15:03 |
This may be handy for some ( BIG PIC ) | synchro | Amiga scene | 27 | 27 June 2004 22:00 |
|
|