English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 15 May 2022, 18:29   #21
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,537
Quote:
Originally Posted by hop View Post
I have a first pass rawseg loader working now.


Quote:
I'd like to look at this script for reference. The vlink website seems to be down and couldn't see it on the GitHub.
Indeed. I guess the server crashed last night. Will have to restart it tomorrow, when I'm in the office again.

Quote:
Where can it be found?
The default script for "rawseg" is in vlink's
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";
phx is offline  
Old 15 May 2022, 20:35   #22
hop
Registered User
 
Join Date: Apr 2019
Location: UK
Posts: 228
Quote:
Originally Posted by phx View Post
The default script for "rawseg" is in vlink's
t_rawseg.c
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
Many thanks for all your help. Attached zip contains load file and build script.
Attached Files
File Type: 7z vasm_rawseg.7z (5.4 KB, 24 views)

Last edited by hop; 15 May 2022 at 20:35. Reason: Clarification
hop is offline  
 


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

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 22:46.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.07177 seconds with 15 queries