20 September 2023, 18:50 | #1 |
Registered User
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 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 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 |
22 September 2023, 13:56 | #2 | ||||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,510
|
Quote:
Quote:
Quote:
Quote:
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. |
||||
22 September 2023, 23:40 | #3 | |
Registered User
Join Date: Mar 2018
Location: Rome
Posts: 173
|
Quote:
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: 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 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. |
|
23 September 2023, 15:02 | #4 |
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.. |
30 September 2023, 22:31 | #5 |
Registered User
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 |
01 October 2023, 04:34 | #6 | |
Registered User
Join Date: Mar 2018
Location: Hastings, New Zealand
Posts: 2,655
|
Quote:
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. |
|
01 October 2023, 15:06 | #7 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,510
|
Quote:
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 rawbinoutput format: Quote:
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 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 rawbinoutput format with vlink and the -qoption 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 2tells 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 |......| For more complex binary relocation scenarios vlink provides the rawsegformat, which has relocation tables for mulitple segments. I'm using the format in all of my games. |
||
02 October 2023, 10:39 | #8 | |
Registered User
Join Date: Aug 2010
Location: Germany
Posts: 532
|
Quote:
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. |
|
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 |
|
|