English Amiga Board


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

 
 
Thread Tools
Old 20 September 2023, 18:50   #1
fstarred
Registered User
 
fstarred's Avatar
 
Join Date: Mar 2018
Location: Rome
Posts: 173
trackdevice and other memory issues...

Hi all,

I want to run a simple SW df0: trackreader and load my program manually (no LoadSeg or naming references..).

First off, let's say I want to run a simple "SystemOff" program that show a black screen and exit on mouse click.

From AsmOne I use RO, C and WS commands to place on RAM, copy to another address (because for some reason the given address is not good to read for the WS) and then write to df0 sectors (starting from block 2 to len/512).

About the trackreader, I found two sources online, one for Amiga Assembly Language book and the other one from mc1006 (see also Mark Wrobler Letter X - Trackdisk).

By the way I have uploaded these sources on my own repository

First issue

While apparently have no problems with the latter (although it is not clear to me if so many DOS calls are necessary) I want to change the readsector.s source and replace the SendIo async function with DoIo on accdisk label so the loaded code is available before jumping on it.

However when I try to do this, the DoIo method freezes and so the program itself. I read the DoIO doc but it's not clear to me what's wrong.

Second issue

If I try to use the mc1006 trackreader, it works correctly and data is loaded on specified location (let's say $20000).
However, when I finally do the JMP $20000, altough the code is processed the screen is not black as expected.

Third issue
If I try to enable a VBlank Interrupt on the SystemOff program, Amiga crashes brutally.

Last question (for now)

What are the reasons to use trackdisk.device instead of let the program start from startup-sequence for example (unless you are in the 80 and want to protect from copy using NDOS disk)?

Below the sources:

mc1006 trackreader example
Code:
start:
;----- Library Vector Offsets
LVOAllocSignal=-330
LVOFindTask=-294
LVOOpenDevice=-444
LVODoIO=-456
;----- Node structure offsets
LN_TYPE=8
LN_PRI=9
;----- Message type for LN_TYPE
NT_MSGPORT=4
NT_MESSAGE=$05
;----- List structure offsets
LH_HEAD=0
LH_TAIL=4
LH_TAILPRED=8
;----- MsgPort structure offsets
MP_FLAGS=14
MP_SIGBIT=15
MP_SIGTASK=16
MP_MSGLIST=20
;----- Message structure offset
MN_REPLYPORT=14
;----- IOStdRequest structure offsets
IO_COMMAND=28
IO_LENGTH=36
IO_DATA=40
IO_OFFSET=44
;----- Command type for IO_COMMAND
CMD_FLUSH=$9

BLK_OFFSET=2
BLK_LEN=8	; numbers of sectors/blocks to read

;----- Begin program
	lea.l	$20000,a0  ; move buffer address into a0
	move.l	#0,d0      ; move 0 into d0 (diskStation = internal drive)
	move.l	#BLK_OFFSET,d1 ; move 0 into d1 (block = block 0)
	move.l	#BLK_LEN,d2    ; move block to read lenngth into d2
	move.l	#1,d3      ; move 1 into d3 (mode = READ)

	bsr	sector
	rts                ; return from subroutine
	  
  
sector:                          ; sector(a0=buffer,d0=diskStation,d1=block,d2=length,d3=mode)
	movem.l	d0-d7/a0-a6,-(a7)        ; push register values onto the stack
	lsl.l	#8,d1                    ; convert d1=block from blocks to offset in bytes
	add.l	d1,d1                    ; convert d1=block from blocks to offset in bytes
	lsl.l	#8,d2                    ; convert d2=length from blocks to bytes
	add.l	d2,d2                    ; convert d2=length from blocks to bytes
	move.l	d1,-(a7)                 ; push d1=block onto the stack
	move.l	d2,-(a7)                 ; push d2=length onto the stack
	move.l	a0,-(a7)                 ; push a0=buffer onto the stack
	move.l	d0,-(a7)                 ; push d0=diskStation onto the stack
	move.l	$4,a6                    ; move base of exec.library into a6
	lea.l	ws_diskport,a2           ; move ws_diskport address into a2 (MsgPort)
	moveq	#-1,d0                   ; move -1 into d0 (no preference for signal number)
	jsr	LVOAllocSignal(a6)       ; call AllocSignal. d0 = AllocSignal(d0)
	moveq	#-1,d1                   ; move -1 into d1
	move.b	d0,MP_SIGBIT(a2)         ; set signal number in MsgPort
	clr.b	MP_FLAGS(a2)             ; clear flags in MsgPort
	move.b	NT_MSGPORT,LN_TYPE(a2)   ; set message type in MsgPort.Node
	move.b	#120,LN_PRI(a2)          ; set priority in MsgPort.Node
	sub.l	a1,a1                    ; set a1 to 0 (find oneself)
	jsr	LVOFindTask(a6)          ; call FindTask. d0 = FindTask(a1)
	move.l	d0,MP_SIGTASK(a2)        ; set object to be signaled in MsgPort to result of FindTask
	lea.l	MP_MSGLIST(a2),a0        ; Initialize MsgPort.List
	move.l	a0,LH_HEAD(a0)           ; Initialize MsgPort.List
	addq.l	#LH_TAIL,(a0)            ; Initialize MsgPort.List
	clr.l	LH_TAIL(a0)              ; Initialize MsgPort.List
	move.l	a0,LH_TAILPRED(a0)       ; Initialize MsgPort.List
	lea.l	ws_diskreq,a1            ; move ws_diskreq address into a1 (IOStdReq)
	move.b	#NT_MESSAGE,LN_TYPE(a1)  ; set node type in IOStdReq.Message.Node
	move.l	a2,MN_REPLYPORT(a1)      ; set reply port a2 in IOStdReq.Message
	lea.l	ws_devicename,a0         ; set a0=devName
	move.l	(a7)+,d0                 ; set d0=diskStation by popping stack
	clr.l	d1                       ; set d1=flags (0 for opening)
	jsr	LVOOpenDevice(a6)        ; call OpenDevice. (d0=returnCode) = OpenDevice(a0=devName,d0=unitNumber,a1=IORequest,d1=flags)
	move.l	(a7)+,IO_DATA(a1)        ; set data in IOStdReq.Data to buffer by popping stack
	andi.l	#3,d3                    ; convert subroutine input mode to command 
	addq.w	#1,d3                    ; convert subroutine input mode to command 
	move.w	d3,IO_COMMAND(a1)        ; set IOStdReq.Command to d3
	move.l	(a7)+,IO_LENGTH(a1)      ; set IOStdReq.Length to length by popping stack
	move.l	(a7)+,IO_OFFSET(a1)      ; set IOStdReq.Offset to block by popping stack
	jsr	LVODoIO(a6)              ; call DoIO. (d0=returnCode) = DoIO(a1=IORequest)
	move.l	d0,d7                    ; move d0=returnCode into d7
	move.l	#0,IO_LENGTH(a1)         ; set IOStdReq.Length to 0
	move.w	#CMD_FLUSH,IO_COMMAND(a1); set IOStdReq.Command to CMD_FLUSH
	jsr	LVODoIO(a6)              ; call DoIO. (d0=returnCode) = DoIO(a1)
	movem.l	(a7)+,d0-d7/a0-a6        ; pop values from the stack into the registers

	jmp	$20000

	rts                              ; return from subroutine
ws_diskport:  
	blk.l	100,0  
ws_diskreq:
	blk.l	15,0
ws_devicename:
	dc.b	"trackdisk.device",0,0
trackreader from amiga assembly language book
Code:
***************************************************
*
*	example from AMIGA MACHINE LANGUAGE
*
***************************************************


* read sectors from df0 and wait for char before quit
*
* hint: run the program in debug mode and place mark before
* end of the program.
*
* Press any key to continue until the end


;***** Track disk-Basic function  10/86 S.D. *****

;               ILABEL ASSEMPRO:includes/Amiga.l   :AssemPro only

openlib      =-408
closelib     =-414
execbase    = 4                    ;defined in INIT_AMIGA

        * calls to amiga dos:

open         =-30
close        =-36
opendevice   =-444
closedev     =-450
doIo         =-456
sendIo       =-462
read         =-42
write        =-48
waitforchar  =-204

; 1005	Open existing file read/write positioned at beginning of file.
; 1006	Open freshly created file (delete old file) read/write, exclusive lock.
; 1004	Open old file w/shared lock, creates file if doesn't exist.
mode_old     = 1005
block_len    = 4
block_offset = 2

dest = $70000

;No    Name          Function
;-----------------------------------------------------------------
;2     READ          Read one or more sectors
;3     WRITE         Write sectors
;4     UPDATE        Update the track buffer
;5     CLEAR         Erase track buffer
;9     MOTOR         Turn motor on/off
;10    SEEK          Search for a track
;11    FORMAT        Format tracks
;12    REMOVE        Initialize routine that is called when you
;					remove the disk
;13    CHANGENUM     Find out number of disk changes
;14    CHANGESTATE   Test if disk is in drive
;15    PROTSTATUS    Test if disk is write protected


;              INIT_AMIGA                   ;AssemPro only

run:
	bsr     init
	bra     test		;system test

init:					;system initialization and open 
	move.l  execbase,a6		;pointer to exec-library
	lea     dosname,a1
	moveq   #0,d0
	jsr     openlib(a6)		;open dos-library
	move.l  d0,dosbase
	beq     error

	lea     diskio,a1
	move.l  #diskrep,14(a1)
	moveq   #0,d0
	moveq   #0,d1
	lea     trddevice,a0
	jsr     opendevice(a6)		;open trackdisk.device
	tst.l   d0
	bne     error
	rts
	
bp:
	lea     consolname(pc),a1	;console-definition
	move.l  #mode_old,d0
	bsr     openfile		;console open
	beq     error
	move.l  d0,conhandle

	rts

test:
	bsr     accdisk

;	bsr     getchr			;wait for character
	bra     qu

error:
	move.l  #-1,d7			;flag

qu:
	move.l  execbase,a6
	lea     diskio,a1
	move    #9,28(a1)		;command:MOTOR (0=off,1=on)
	move.l  #0,36(a1)		;motor off
	jsr     sendio(a6)

;	move.l  conhandle,d1		;window close
;	move.l  dosbase,a6
;	jsr     close(a6)

	move.l  dosbase,a1		;dos.lib close
	move.l  execbase,a6
	jsr     closelib(a6)

	lea     diskio,a1
	move.l  32(a1),d7
	jsr     closedev(a6)

	jmp	dest

	rts

;               EXIT_AMIGA                   ;AssemPro only

openfile:				;open file
	move.l  a1,d1			;pointer to the I/O-definition text
							
	move.l  d0,d2
	move.l  dosbase,a6
	jsr     open(a6)
	tst.l   d0
	rts

scankey:				;test for key
	move.l  conhandle,d1                      
	move.l  #500,d2			;wait value
	move.l  dosbase,a6
	jsr     waitforchar(a6)
	tst.l   d0
	rts

getchr:					;get one character from keyboard
	move.l  #1,d3			;1 character
	move.l  conhandle,d1
	lea     inbuff,a1		;buffer-address
	move.l  a1,d2
	move.l  dosbase,a6
	jsr     read(a6)
	moveq   #0,d0
	move.b  inbuff,d0
	rts

accdisk:
	lea     diskio,a1
	move    #2,28(a1)			;command:READ                 
	move.l  #dest,40(a1)		;buffer
	move.l  #block_len*512,36(a1)		;length: n sectors
	move.l  #block_offset*512,44(a1)	;offset: n sectors
	move.l  execbase,a6
	jsr     sendIo(a6) ; the DoIo freezes :(
	rts

dosname:       dc.b 'dos.library',0,0
	even
dosbase:       dc.l 0
consolname:    dc.b 'RAW:0/100/640/100/** Test-Window S.D.V0.1',0
trddevice:     dc.b 'trackdisk.device',0
	even
conhandle:     dc.l 0
inbuff:        ds.b 8                                             
diskio:        ds.l 20
diskrep:       ds.l 8                                           
;diskbuff:      ds.b 512*block_len
end
SystemOff code
Code:
;************************************************
;*	Friendly non-system startup routine	*
;*	
;************************************************

;*****************
;*   Constants   *
;*****************

OldOpenLibrary	= -408
CloseLibrary	= -414

DMASET=	%1000000111000000
;	 -----a-bcdefghij

;	a: Blitter Nasty
;	b: Bitplane DMA (if this isn't set, sprites disappear!)
;	c: Copper DMA
;	d: Blitter DMA
;	e: Sprite DMA
;	f: Disk DMA
;	g-j: Audio 3-0 DMA

START:
	MOVEM.L	D0-D7/A0-A6,-(A7)	; Put registers on stack

;***********************************
;*   CLOSE ALL SYSTEM INTERRUPTS   *
;*                                 *
;*      START DEMO INTERRUPTS      *
;***********************************

	MOVE.L	$4.W,A6			; Exec pointer to A6
	LEA.L	GfxName(PC),A1		; Set library pointer
	MOVEQ	#0,D0
	JSR	OldOpenLibrary(A6)	; Open graphics.library
	MOVE.L	D0,A1			; Use Base-pointer
	MOVE.L	$26(A1),OLDCOP1		; Store copper1 start addr
	MOVE.L	$32(A1),OLDCOP2		; Store copper1 start addr
	JSR	CloseLibrary(A6)	; Close graphics library

	LEA	$DFF000,A6
	MOVE.W	$1C(A6),INTENA		; Store old INTENA
	MOVE.W	$2(A6),DMACON		; Store old DMACON
	MOVE.W	$10(A6),ADKCON		; Store old ADKCON
	
	MOVE.L  #SCREEN,D0  ; POINT TO BITPLANE
    LEA BPLPOINTERS,A1  ; 
	
	MOVE.W  D0,6(A1)    ; COPY LOW WORD OF PIC ADDRESS TO PLANE
    SWAP    D0          ; SWAP THE THE TWO WORDS
   	MOVE.W  D0,2(A1)    ; COPY THE HIGH WORD OF PIC ADDRESS TO PLANE

	MOVE.W	#$7FFF,$9A(A6)		; Clear interrupt enable

	BSR.L	Wait_Vert_Blank

	MOVE.W	#$7FFF,$96(A6)		; Clear DMA channels
	MOVE.L	#COPLIST,$80(A6)	; Copper1 start address
	MOVE.W	#DMASET!$8200,$96(A6)	; DMA kontrol data
	MOVE.L	$6C.W,OldInter		; Store old inter pointer
;	MOVE.L	#INTER,$6C.W		; Set interrupt pointer

	MOVE.W	#$7FFF,$9C(A6)		; Clear request
;	MOVE.W	#$C020,$9A(A6)		; Interrupt enable
	MOVE.W	#$7FFF,$9A(A6)		; Disable interrupt

;****       Your main routine      ****


;**** Main Loop  Test mouse button ****

LOOP:
	BTST	#6,$BFE001		; Test left mouse button
	BNE.S	LOOP

;*****************************************
;*					 *
;*   RESTORE SYSTEM INTERRUPTS ECT ECT   *
;*					 *
;*****************************************

	LEA	$DFF000,A6

	MOVE.W	#$7FFF,$9A(A6)		; Disable interrupts

	BSR.S	Wait_Vert_Blank

	MOVE.W	#$7FFF,$96(A6)
	MOVE.L	OldCop1(PC),$80(A6)	; Restore old copper1
	MOVE.L	OldCop2(PC),$84(A6)	; Restore old copper1
	MOVE.L	OldInter(PC),$6C.W	; Restore inter pointer
	MOVE.W	DMACON,D0		; Restore old DMACON
	OR.W	#$8000,D0
	MOVE.W	D0,$96(A6)		
	MOVE.W	ADKCON,D0		; Restore old ADKCON
	OR.W	#$8000,D0
	MOVE.W	D0,$9E(A6)
	MOVE.W	INTENA,D0		; Restore inter data
	OR.W	#$C000,D0
	MOVE.W	#$7FFF,$9C(A6)
	MOVE.W	D0,$9A(A6)
	MOVEM.L	(A7)+,D0-D7/A0-A6	; Get registers from stack
	RTS

;*** WAIT VERTICAL BLANK ***

Wait_Vert_Blank:
	BTST	#0,$5(A6)
	BEQ.S	Wait_Vert_Blank
.loop	BTST	#0,$5(A6)
	BNE.S	.loop
	RTS

;*** DATA AREA ***

GfxName		DC.B	'graphics.library',0
		even
DosBase		DC.L	0
OldInter	DC.L	0
OldCop1		DC.L	0
OldCop2		DC.L	0
INTENA		DC.W	0
DMACON		DC.W	0
ADKCON		DC.W	0

;**********************************
;*				  *
;*    INTERRUPT ROUTINE. LEVEL 3  *
;*				  *
;**********************************

;INTER:
;	MOVEM.L	D0-D7/A0-A6,-(A7)	; Put registers on stack
;	LEA.L	$DFF000,A6
;	MOVE.L	#SCREEN,$E0(A6)

;---  Place your interrupt routine here  ---

;	MOVE.W	#$4020,$9C(A6)		; Clear interrupt request
;	MOVEM.L	(A7)+,D0-D7/A0-A6	; Get registers from stack
;	RTE

;*****************************
;*			     *
;*      COPPER1 PROGRAM      *
;*			     *
;*****************************

	SECTION	Copper,DATA_C

COPLIST:
	DC.W	$0100,$1200	; Bit-Plane control reg.
	DC.W	$0102,$0000	; Hor-Scroll
	DC.W	$0104,$0010	; Sprite/Gfx priority
	DC.W	$0108,$0000	; Modolu (odd)
	DC.W	$010A,$0000	; Modolu (even)
	DC.W	$008E,$2C81	; Screen Size
	DC.W	$0090,$2CC1	; Screen Size
	DC.W	$0092,$0038	; H-start
	DC.W	$0094,$00D0	; H-stop
BPLPOINTERS:
	dc.w	$00E0,$0000 ; BITPLANE 0
	dc.w	$00E2,$0000 ; BITPLANE 0

	DC.W	$0180,$0000	; Color #0 = 000
	DC.W	$0182,$0FFF	; Color #1 = fff
	DC.L	$FFFFFFFE

;*****************************
;*			     *
;*      SCREEN DATA AREA     *
;*			     *
;*****************************

	SECTION	Screen,DATA_C

SCREEN	
	DCB.B	40,$ff
	DS.B	40*256-80
	DCB.B	40,$ff
fstarred is offline  
Old 22 September 2023, 13:56   #2
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,510
Quote:
Originally Posted by fstarred View Post
I want to run a simple SW df0: trackreader and load my program manually (no LoadSeg or naming references..).
For what reason? See below...

Quote:
First off, let's say I want to run a simple "SystemOff" program that show a black screen and exit on mouse click.
Your "SystemOff" suggests that you want to take over the system and kill the OS. Are you doing that before or after using the OS to read some blocks from the disk?

Quote:
From AsmOne I use RO, C and WS commands to place on RAM, copy to another address (because for some reason the given address is not good to read for the WS)
Did you allocate this memory properly? Otherwise you may easily corrupt something important.

Quote:
What are the reasons to use trackdisk.device instead of let the program start from startup-sequence for example (unless you are in the 80 and want to protect from copy using NDOS disk)?
Good question! In fact, there is not much reason to use it. It will mainly be used by AmigaDOS handlers, like the FastFileSystem.
If your intention is to write a game or a demo, then you will either use the OS and its file system, or you will take over the whole system out of the boot block and implement your own trackdisk routines, accessing the hardware directly. Everything in between is dirty and calling for trouble.
A special case is when your game/demo and all of its data fits into a single file. Then you can still start it with the OS and take over the hardware later.
phx is offline  
Old 22 September 2023, 23:40   #3
fstarred
Registered User
 
fstarred's Avatar
 
Join Date: Mar 2018
Location: Rome
Posts: 173
Quote:
Your "SystemOff" suggests that you want to take over the system and kill the OS. Are you doing that before or after using the OS to read some blocks from the disk?
SystemOff (or any other program I would like to run) should be called (JMP) after I allocate it on a specified memory (let's say $70000)

About the reasons:
I just want to check with a bit more depth how amiga FS works and how old - and often bad programmed - games used it.


However there's an update;
by looking on some example on the pub repos, I have noticed that by using trackdevice on bootblock I don't even need to load it.

Here's the minimal code:

trackloader
Code:
MAIN_ADDRESS = $70000

Writeflag = 1

	If WriteFlag = 1
	AUTO	WS\BOOTBLOCK\0\3\CC\
	EndC

bootblock:
	dc.b	'DOS',0
	dc.l	0
	dc.l	880

bootEntry:

	lea	MAIN_ADDRESS,a5

	move.l	#(end-mainStart),36(a1)
	move.l	a5,40(a1)
	move.l	#mainStart-bootblock,44(a1)
	jsr	-456(a6)	;doIo

	move.l	#0,36(a1)
	move.w	#9,28(a1)
	jsr	-456(a6)

	jmp	(a5)

bootEnd:

	ds.b	(1024-(bootEnd-bootblock))

mainStart:
	incbin	"dh1:/nsys"
mainEnd:
;	dcb.w	(512-(mainEndNoNop-mainStart))/2,$4e71
	ds.b	512-(mainEnd-mainStart)
End:
nsys source
Code:
DMASET=		%1000000110000000
;		 -----a-bcdefghij

;		a: Blitter Nasty
;		b: Bitplane DMA (if this isn't set sprites disapear!)
;		c: Copper DMA
;		d: Blitter DMA
;		e: Sprite DMA
;		f: Disk DMA
;	      g-j: Audio 3-0 DMA

OpenLibrary=	-408
CloseLibrary=	-414
AllocRaster=	-492
FreeRaster=	-498

	SECTION	FIRST,CODE_C

START:
	RSRESET

OldCopper	RS.L	1
ScreenPtr	RS.L	1
	
	MOVEM.L	D0-D7/A0-A6,-(A7)
	LEA.L	START(PC),A4
	MOVE.L	$4.W,A6
	LEA.L	GRAPNAME(PC),A1		; Gfx Name
	MOVEQ	#0,D0
	JSR	OPENLIBRARY(A6)
	MOVE.L	D0,A6			; Gfx Base
	MOVE.L	$26(A6),OldCopper(A4)	; Get old Copper Ptr.

;---  Allocate Raster  ---

	MOVE.W	#320,D0			; Width
	MOVE.W	#260,D1			; Higth
	JSR	AllocRaster(A6)
	MOVE.L	D0,ScreenPtr(A4)

;--- Clear screen  ---

	MOVE.L	D0,A0
	MOVE.W	#320/8*260/4-1,D1	; Clear 320/8 bytes wide
	MOVEQ	#0,D2			; times 260 bytes high
.LOOPC	
	MOVE.L	D2,(A0)+		; in longwords / 4
	DBF	D1,.LOOPC

;---  Set BPL ptrs  ---

	LEA.L	BITPLANES+2(PC),A0
	MOVEQ	#40,D1
	ADD.L	D0,D1
	SWAP	D0		; High word of pointer
	MOVE.W	D0,(A0)		; Store high 1
	ADDQ.W	#4,A0
	SWAP	D0		; Low word of pointer
	MOVE.W	D0,(A0)		; Store low 1

	MOVE.L	A6,-(A7)	; Store Graphics library base

;---  Set DMA registers  ---

	MOVE.L	#$DFF000,A6
	MOVE.W	$1C(A6),-(A7)		; Store old inter data
	MOVE.W	$02(A6),-(A7)		; Store old DMA data
	MOVE.L	#$7FFF7FFF,$9A(A6)	; Disable interrupts
	MOVE.W	#$7FFF,$96(A6)		; Disable all DMA's

	LEA	COPLIST(PC),A0
	MOVE.L	A0,$80(A6)		; Copper1 start adress
	MOVE.W	#DMASET!$8200,$96(A6)	; Enable DMA's
	CLR.W	$88(A6)			; Start copper1

.END	
	BTST	#6,$BFE001		; Wait mouse
	BNE.S	.END			; Pressed ???

;---  The End  ---

	MOVE.L	#$7FFF7FFF,$9A(A6)	; Disable interrupts
	OR.L	#$8000C000,(A7)		; Set enable bits
	MOVE.W	(A7)+,$96(A6)		; Enable interruptr
	MOVE.W	(A7)+,$9A(A6)		; Restore old inter data
	MOVE.L	OldCopper(A4),$80(A6)	; Restore old copper ptr
	CLR.W	$88(A6)			; Start Copper

;---  DeAllocate Raster  ---

	MOVE.L	(A7)+,A6
	MOVE.L	ScreenPtr(A4),A0
	MOVE.W	#320,D0			; Width
	MOVE.W	#260,D1			; Higth
	JSR	FreeRaster(A6)

	MOVE.L	A6,A1			; Close graphics library
	MOVE.L	$4.W,A6
	JSR	CLOSELIBRARY(A6)

	MOVEM.L	(A7)+,D0-D7/A0-A6
	
	RTS


GRAPNAME:	DC.B	'graphics.library',0
	EVEN	
;*****************************
;*			     *
;*      COPPER1 PROGRAM      *
;*			     *
;*****************************

COPLIST:
	DC.L	$0182057C
	DC.L	$01840D85
	DC.L	$01860FA7
	DC.L	$01A20AAA
	DC.L	$01A40666
	DC.L	$01A60FFF
BITPLANES:
	DC.L	$00E00000
	DC.L	$00E20000
	DC.L	$00E40000
	DC.L	$00E60000
	DC.L	$01001200
	DC.L	$01020000
	DC.L	$01040000
	DC.L	$01080000
	DC.L	$010A0000
	DC.L	$008E2C78
	DC.L	$00902CC8
	DC.L	$00920038
	DC.L	$009400D0

	DC.L	$01800000
	
END
Now nsys start well, unfortunately after it end for some reason amiga crashes (instead of back to workbench screen).

Steps to assemble it all with AsmOne:

1. Load nsys source, assemble, then WB/[file]/START/END
2. Load trackloader source, assemble and AsmOne auto assemble it all to df0

Last edited by fstarred; 23 September 2023 at 12:28.
fstarred is offline  
Old 23 September 2023, 15:02   #4
hooverphonique
ex. demoscener "Bigmama"
 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,631
You can't exit to workbench from code trackloaded from the bootblock.
The only option is to reset the amiga and boot again..
hooverphonique is offline  
Old 30 September 2023, 22:31   #5
fstarred
Registered User
 
fstarred's Avatar
 
Join Date: Mar 2018
Location: Rome
Posts: 173
Now I have managed to work I simple demo that alloc screen memory and write an horizontal line in which movement is handled inside a VBLANK interrupt.
This code is loaded as a binary object (no hunk file) from the trackdevice program above; I realized that from the only way to correctly refer an address is to use the relative (i.e. PC) mode instead of the absolute, which won't work.

Just a question, by using trackdevice I cannot use the header of the hunk file, is it correct ?

Code:
***********************************
*
*
*	VERTICAL LINE MOOVER
*
*
***********************************

; attached with bblocktrd code
; note: all addresses must be relative referenced (i.e. with PC)


WriteFlag=1

	IF WriteFlag=1
	AUTO	WB\START\END\
	ENDC

OldOpenLibrary = -408
CloseLibrary = -414
AllocRaster=	-492
FreeRaster=	-498

; A = AGNUS, D = DENISE, P = PAULA

;DMACON     096      W     A D P   DMA control write (clear or set)
;DMACONR    002      R     A   P   DMA control (and blitter status) read
DMASET=	%1000001110000000 ($8380)
;	 fedcba9876543210

;	f: Set/Clear control bit
;	e: Blitter busy status bit (read only)
;	d: Blotter logic zero status bit (read only)
;	c: X
;	b: X
;	a: Blitter DMA priority (blitter nasty)
;	9: Enable all DMA below
;	8: Bitplane DMA enable
;	7: Copper DMA enable
;	6: Blitter DMA enable
;	5: Sprite DMA enable
;	4: Disk DMA enable
;	3: Audio channel 3 DMA enable
;	2: Audio channel 2 DMA enable
;	1: Audio channel 1 DMA enable
;	0: Audio channel 0 DMA enable
			

;INTENA     09A      W       P    Interrupt enable bits (clear or set bits)
;INTENAR    01C      R       P    Interrupt enable bits (read)
INTENA=	%1100000000100000 ($C020)
;	 fedcba9876543210

;	f: Set/Clear control bit 
;	e: Master interrupt
;	d: External interrupt
;	c: Disk sync register ( DSKSYNC ) matches disk data
;	b: Serial port receive buffer full
;	a: Audio channel 3 block finished
;	9: Audio channel 2 block finished
;	8: Audio channel 1 block finished
;	7: Audio channel 0 block finished
;	6: Blitter finished
;	5: Start of vertical blank
;	4: Copper
;	3: I/O ports and timers
;	2: Reserved for software -initalited interrupt
;	1: Disk block finished
;	0: Serial port transmit buffere empty

SCR_WIDTH=320
SCR_HEIGHT=256

START:

	MOVE.L	$4.W,A6
	LEA	GFXNAME(PC),A1
	JSR	OldOpenLibrary(A6)	; load graphics library
	MOVE.L	D0,A6
	
;---  Allocate Raster  ---

	MOVE.L	#SCR_WIDTH,D0		; Width
	MOVE.L	#SCR_HEIGHT,D1		; Higth
	JSR	AllocRaster(A6)		; Allocate memory for bitplane WxH
	LEA	ScreenPtr(PC),A0	
	MOVE.L	D0,(A0)			; Write btpl ptr on ScreenPtr
	
;--- Clear screen  ---

	MOVE.L	(A0),A0			; Point A0 to bitplane address
	MOVE.W	#SCR_WIDTH/8*SCR_HEIGHT/4-1,D1	; Clear 320/8 bytes wide
	MOVEQ	#0,D2			; times 260 bytes high
	
.LOOPC	
	MOVE.L	D2,(A0)+		; in longwords / 4
	DBF	D1,.LOOPC

;---  Set BPL ptrs  ---

	LEA.L	BITPLANES+2(PC),A0
	MOVEQ	#40,D1
	ADD.L	D0,D1
	SWAP	D0		; High word of pointer
	MOVE.W	D0,(A0)		; Store high 1
	ADDQ.W	#4,A0
	SWAP	D0		; Low word of pointer
	MOVE.W	D0,(A0)		; Store low 1

	LEA	$DFF000,A6

;--- Disable Interrupt

	MOVE.W	#$7FFF,$9A(A6)		; Clear interrupt enable
	BSR.L	WAITVB			; Wait for VBLANK
	
;--- Set Interrupt request ---

	LEA	INTER(PC),A0
	MOVE.L	A0,$6C.W

;--- Set Interrupt

	MOVE.W	#$7FFF,$9C(A6)		; Clear request
	MOVE.W	#INTENA,$9A(A6)		; Interrupt enable

;--- Set copperlist ---

	LEA	COPPERLIST(PC),A0	
	MOVE.L	A0,$80(A6)		; write our copperlist to COP1 loc reg
	MOVE.W	$88(A6),D0		; Launch COPJMP1

;--- Set Dma ---

	MOVE.W	#DMASET,$96(A6)		; set bits of DMACON state

.LEFTMOUSE
	BTST	#6,$BFE001
	BNE.S	.LEFTMOUSE
	
	LEA	COLOR01+2(PC),A0
	MOVE.W	(A0),D0			; read $0182 (COLOR1) 
	ROR	#4,D0			; change color
	MOVE.W	D0,(A0)			; write color to $0182
	BRA.S	.LEFTMOUSE
	
	RTS

WAITVB:
	TST.B	$DFF005
	BEQ.B	WAITVB
.LOOP
	TST.B	$DFF005
	BNE.S	.LOOP
	RTS

INTER:
	MOVEM.L	D0-D7/A0-A6,-(SP)
	
	MOVE.L	ScreenPtr(PC),A0
	LEA	LinePos(PC),A1
	
	MOVEQ	#0,D1
	MOVE.B	(A1),D1
	MOVE.L	D1,D2			; Set vline position to D2

	MULU.W	#40,D1
	ADD.L	D1,A0			; Point to screen according to line pos

	MOVEQ	#10-1,D0
.DELLINE
	MOVE.L	#$00000000,(A0)+
	DBF	D0,.DELLINE		; Delete line at screen position
	
	MOVEQ	#10-1,D0
.WRTLINE
	MOVE.L	#$FFFFFFFF,(A0)+
	DBF	D0,.WRTLINE		; Write line at screen position

	ADDQ	#1,D2
	MOVE.B	D2,(A1)			; Update LinePos+1
	
	MOVE.W	#$4020,$9C(A6)		; Clear interrupt request
	MOVEM.L	(SP)+,D0-D7/A0-A6
	
	RTE
	
ScreenPtr:	
	DC.L	0
LinePos:	
	DC.B	$FF
	EVEN
GFXNAME:
	DC.B	'graphics.library',0
	EVEN
COPPERLIST:
	DC.L	$01800000
COLOR01:
	DC.L	$01820FFF
BITPLANES:
	DC.L	$00E00000	; Bitplane 1 pointer high bits
	DC.L	$00E20000	; Bitplane 1 pointer low bits
	DC.L	$00E40000	; Bitplane 2 pointer hight bits
	DC.L	$00E60000	; Bitplane 2 pointer low bits
	DC.L	$01001200	; BPLCON0 Bitplane control register
	DC.L	$01020000	; BPLCON1
	DC.L	$01040000	; BPLCON2
	DC.L	$01080000	; Bitplane modulo (odd planes)
	DC.L	$010A0000	; Bitplane modulo (even planes)
	DC.L	$008E2C78	; DIWSTRT
	DC.L	$00902CC8	; DIWSTOP
	DC.L	$00920038	; DDFSTRT
	DC.L	$009400D0	; DDFSTOP
	DC.L	$FFFFFFFE

END
fstarred is offline  
Old 01 October 2023, 04:34   #6
Bruce Abbott
Registered User
 
Bruce Abbott's Avatar
 
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 2,655
Quote:
Originally Posted by fstarred View Post
Just a question, by using trackdevice I cannot use the header of the hunk file, is it correct ?
No. You can use a custom loadseg routine to relocate the executable. If you keep it simple (eg. just one CODE hunk and one RELOC32 hunk) the loadseg code can be simple too.

However if you make all code references PC relative and dedicate a 'base' address register (eg. A5) to data, then you don't need to relocate anything and the code is smaller and faster. Relative addressing range is +-32k on 68000 so this works well if your data+bss is less than 64k. Larger code can be accomodated by branching in 2 or more hops, or by using the 'base' register to call/jmp to code that is close to the data.
Bruce Abbott is offline  
Old 01 October 2023, 15:06   #7
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,510
Quote:
Originally Posted by Bruce Abbott View Post
You can use a custom loadseg routine to relocate the executable.
Yes, this is is a good solution, as the hunk-format is not too complicated.

When using vlink as a linker, the binary relocation can even be easier, because with option -q the linker can be instructed to append a simple relocation table to a binary. Its format is described in the vlink documention for the
rawbin
output format:
Quote:
When option
-q
(keep relocs) has been specified, the linker will not execute absolute address relocations, but append a relocation offset table at the end of the file. The width of a word in this table matches the target's address size and uses the target's endianness.
The first word defines the size of the following table. You may reference it by using the
__end
symbol, which marks the end of the bss section. It follows a byte-stream for the reloction offsets.
A byte between 1 and 255 represents the distance in bytes to the next relocation offset (starts at zero).
A 0-byte indicates that the following word contains a distance greater than 255. Your startup code has to add the program's start address to the address values in all these locations.
It follows a short example source. The program starts by relocating itself. Note, that you must use PC-relative addressing to the find the program's start and end address.
Code:
        xref    __end                   ; from linker
        code
start:
        ; Relocate ourselves!
        lea     __end(pc),a0
        lea     start(pc),a1
        move.l  a1,d1
        move.l  (a0)+,a2                ; reloc table size
        add.l   a0,a2                   ; ptr to end of relocation list
        bra     .3
.1:     moveq   #0,d0
        move.b  (a0)+,d0
        bne     .2
        move.b  (a0)+,d0
        lsl.l   #8,d0
        move.b  (a0)+,d0
        lsl.l   #8,d0
        move.b  (a0)+,d0
        lsl.l   #8,d0
        move.b  (a0)+,d0
.2:     add.l   d0,a1
        add.l   d1,(a1)
.3:     cmp.l   a2,a0
        blo     .1

        ; main program
        move.l  foo,bar
loop:   bra     loop

        data
foo:    dc.l    -1

        bss
bar:    ds.l    1
Assemble and link it like this:
Code:
frank@altair vasmm68k_mot -Fhunk -o reloctest.o reloctest.asm 
vasm 1.9e (c) in 2002-2023 Volker Barthelmann
vasm M68k/CPU32/ColdFire cpu backend 2.6b (c) 2002-2023 Frank Wille
vasm motorola syntax module 3.18 (c) 2002-2023 Frank Wille
vasm hunk format output module 2.14c (c) 2002-2022 Frank Wille

CODE(acrx2):              56 bytes
DATA(adrw1):               4 bytes
BSS(aurw1):                4 bytes
frank@altair vlink -brawbin1 -o reloctest -q -minalign 2 reloctest.o
The object files can be in any format you like. It's just important to select the
rawbin
output format with vlink and the
-q
option to append a small relocation table in the documented format.
Here the default linker script is used, but you can also provide your own with
-T
.
-minalign 2
tells the linker to align sections to longword bounaries (least significant 2 bits should be zero), as the default script doesn't specify alignments.
The raw binary output looks like this:
Code:
frank@altair hexdump -C reloctest
00000000  41 fa 00 3e 43 fa ff fa  22 09 24 58 d5 c8 60 18  |A..>C...".$X..`.|
00000010  70 00 10 18 66 0e 10 18  e1 88 10 18 e1 88 10 18  |p...f...........|
00000020  e1 88 10 18 d3 c0 d3 91  b1 ca 65 e4 23 f9 00 00  |..........e.#...|
00000030  00 38 00 00 00 3c 60 fe  ff ff ff ff 00 00 00 00  |.8...<`.........|
00000040  00 00 00 02 2e 04                                 |......|
In the last line you see the automatically generated relocation table. A longword with its size (2) and two 8-bit distances to the next relocation offset ($2e and $04).

For more complex binary relocation scenarios vlink provides the
rawseg
format, which has relocation tables for mulitple segments. I'm using the format in all of my games.
phx is offline  
Old 02 October 2023, 10:39   #8
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by Bruce Abbott View Post
No. You can use a custom loadseg routine to relocate the executable. If you keep it simple (eg. just one CODE hunk and one RELOC32 hunk) the loadseg code can be simple too.
Yes, and you don't even have to write that code yourself because Commodore had already done the work for you back in 1987/1988. The attached "loadseg.txt" comes from the 1988 DevCon in Washington, in support of the then new AutoBoot feature of Kickstart 1.3.

This implementation was originally used in the A590 boot ROM and should see you through. You will have to replace the code which invokes dos.library/Read with your own block read code, etc.
Attached Files
File Type: txt loadseg.txt (12.5 KB, 39 views)
Olaf Barthel 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
Board/Memory issues? Gavster29 support.Hardware 2 28 September 2020 08:58
A500 memory issues Vypr support.Hardware 17 14 November 2019 00:33
Apollo 4060 memory issues roomeo support.Hardware 0 16 March 2017 19:47
Memory Issues Daedalus support.FS-UAE 4 26 December 2016 02:03
PCMCIA Memory Issues moora support.Hardware 8 25 January 2012 18:59

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 00:26.

Top

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