Jump to content
IGNORED

startup.s code used for Hello World!


JagChris

Recommended Posts

I know almost NO assembly. Good luck.

 

.include    "jaguar.inc"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Begin STARTUP PICTURE CONFIGURATION -- Edit this to change startup picture
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PPP     	.equ    8      			; Pixels per Phrase (1-bit)
BMP_WIDTH   	.equ    320      		; Width in Pixels
BMP_HEIGHT  	.equ    200    			; Height in Pixels

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; End of STARTUP PICTURE CONFIGURATION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Globals
	.globl	gSetOLP
	.globl	olp2set
	.globl	ticks

	.globl  a_vdb
	.globl  a_vde
	.globl  a_hdb
	.globl  a_hde
	.globl  width
	.globl  height
               .globl  _vidmem
; Externals
	.extern	___main
               .extern _SetPallete

BMP_PHRASES 	.equ    (BMP_WIDTH/PPP) 	; Width in Phrases
BMP_LINES   	.equ    (BMP_HEIGHT*2)  	; Height in Half Scanlines
BITMAP_OFF  	.equ    (2*       		; Two Phrases
LISTSIZE    	.equ    5       		; List length (in phrases)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Program Entry Point Follows...

	.text

	move.l  #$70007,G_END		; big-endian mode
	move.l  #$70007,D_END
	move.w  #$FFFF,VI       	; disable video interrupts

	move.l  #INITSTACK,a7   	; Setup a stack
		
	jsr 	InitVideo      		; Setup our video registers.
	jsr 	InitLister     		; Initialize Object Display List
	jsr 	InitVBint      		; Initialize our VBLANK routine

;;; Sneaky trick to cause display to popup at first VB

	move.l	#$0,listbuf+BITMAP_OFF
	move.l	#$C,listbuf+BITMAP_OFF+4

	move.l  d0,olp2set      	; D0 is swapped OLP from InitLister
	move.l  #gSetOLP,G_PC   	; Set GPU PC
	move.l  #RISCGO,G_CTRL  	; Go!
waitforset:
	move.l  G_CTRL,d0   		; Wait for write.
	andi.l  #$1,d0
	bne 	waitforset

	move.w  #$6C7,VMODE     	; Configure Video

    jmp 	___main			; Jump to main code

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Procedure: gSetOLP
;            Use the GPU to set the OLP and quit.
;
;    Inputs: olp2set - Variable contains pre-swapped value to stuff OLP with.
;
; NOTE!!!: This code can run in DRAM only because it contains no JUMP's or
;          JR's. It will generate a warning with current versions of MADMAC
;          because it doesn't '.ORG'.
;
	.long
	.gpu
gSetOLP:
	movei   #olp2set,r0   		; Read value to write
	load    (r0),r1

	movei   #OLP,r0       		; Store it
	store   r1,(r0)

	moveq   #0,r0         		; Stop GPU
	movei   #G_CTRL,r1
	store   r0,(r1)
	nop             		; Two "feet" on the brake pedal
	nop

	.68000
	.bss
	.long

olp2set:    	.ds.l   1           		; GPU Code Parameter

	.text

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Procedure: InitVBint
; Install our vertical blank handler and enable interrupts
;

InitVBint:
	move.l  d0,-(sp)

	move.l  #UpdateList,LEVEL0	; Install 68K LEVEL0 handler

	move.w  a_vde,d0        	; Must be ODD
	ori.w   #1,d0
	move.w  d0,VI

	move.w  #C_VIDENA,INT1         	; Enable video interrupts

	move.w  sr,d0
	and.w   #$F8FF,d0       	; Lower 68k IPL to allow
	move.w  d0,sr           	; interrupts

	move.l  (sp)+,d0
	rts
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Procedure: InitVideo (same as in vidinit.s)
;            Build values for hdb, hde, vdb, and vde and store them.
;
					
InitVideo:
	movem.l d0-d6,-(sp)
		
	move.w  CONFIG,d0      		 ; Also is joystick register
	andi.w  #VIDTYPE,d0    		 ; 0 = PAL, 1 = NTSC
	beq 	palvals

	move.w  #NTSC_HMID,d2
	move.w  #NTSC_WIDTH,d0

	move.w  #NTSC_VMID,d6
	move.w  #NTSC_HEIGHT,d4

	bra 	calc_vals
palvals:
	move.w  #PAL_HMID,d2
	move.w  #PAL_WIDTH,d0

	move.w  #PAL_VMID,d6
	move.w  #PAL_HEIGHT,d4

calc_vals:
	move.w  d0,width
	move.w  d4,height

	move.w  d0,d1
	asr 	#1,d1         	 	; Width/2

	sub.w   d1,d2         	  	; Mid - Width/2
	add.w   #4,d2         	  	; (Mid - Width/2)+4

	sub.w   #1,d1         	  	; Width/2 - 1
	ori.w   #$400,d1      	  	; (Width/2 - 1)|$400
	
	move.w  d1,a_hde
	move.w  d1,HDE

	move.w  d2,a_hdb
	move.w  d2,HDB1
	move.w  d2,HDB2

	move.w  d6,d5
	sub.w   d4,d5
	
	move.w  d5,a_vdb

	add.w   d4,d6
	move.w  d6,a_vde
	move.w  a_vdb,VDB
	move.w  #$FFFF,VDE
		
	move.l  #0,BORD1        	; Black border
	move.w  #0,BG           	; Init line buffer to black
		
	movem.l (sp)+,d0-d6
	rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitLister: Initialize Object List Processor List
;
;    Returns: Pre-word-swapped address of current object list in d0.l
;
;  Registers: d0.l/d1.l - Phrase being built
;             d2.l/d3.l - Link address overlays
;             d4.l      - Work register
;             a0.l      - Roving object list pointer
	
InitLister:
	movem.l d1-d4/a0,-(sp)		; Save registers
		
	lea     listbuf,a0
	move.l  a0,d2           	; Copy

	add.l   #(LISTSIZE-1)*8,d2  	; Address of STOP object
	move.l	d2,d3			; Copy for low half

	lsr.l	#8,d2			; Shift high half into place
	lsr.l	#3,d2
	
	swap	d3			; Place low half correctly
	clr.w	d3
	lsl.l	#5,d3

; Write first BRANCH object (branch if YPOS > a_vde )

	clr.l   d0
	move.l  #(BRANCHOBJ|O_BRLT),d1  ; $4000 = VC < YPOS
	or.l	d2,d0			; Do LINK overlay
	or.l	d3,d1
							
	move.w  a_vde,d4                ; for YPOS
	lsl.w   #3,d4                   ; Make it bits 13-3
	or.w    d4,d1

	move.l	d0,(a0)+
	move.l	d1,(a0)+

; Write second branch object (branch if YPOS < a_vdb)
; Note: LINK address is the same so preserve it

	andi.l  #$FF000007,d1           ; Mask off CC and YPOS
	ori.l   #O_BRGT,d1      	; $8000 = VC > YPOS
	move.w  a_vdb,d4                ; for YPOS
	lsl.w   #3,d4                   ; Make it bits 13-3
	or.w    d4,d1

	move.l	d0,(a0)+
	move.l	d1,(a0)+

; Write a standard BITMAP object
	move.l	d2,d0
	move.l	d3,d1

	ori.l  #BMP_HEIGHT<<14,d1       ; Height of image

	move.w  height,d4           	; Center bitmap vertically
	sub.w   #BMP_HEIGHT,d4
	add.w   a_vdb,d4
	andi.w  #$FFFE,d4               ; Must be even
	lsl.w   #3,d4
	or.w    d4,d1                   ; Stuff YPOS in low phrase

	move.l	#_vidmem,d4
	lsl.l	#8,d4
	or.l	d4,d0

	move.l	d0,(a0)+
	move.l	d1,(a0)+
	movem.l	d0-d1,bmpupdate

; Second Phrase of Bitmap
	move.l	#BMP_PHRASES>>4,d0	; Only part of top LONG is IWIDTH
	move.l  #O_DEPTH8|O_NOGAP,d1   ; Bit Depth = 16-bit, Contiguous data

	move.w  width,d4            	; Get width in clocks
	lsr.w   #2,d4               	; /4 Pixel Divisor
	sub.w   #BMP_WIDTH,d4
	lsr.w   #1,d4
	or.w    d4,d1

	ori.l	#(BMP_PHRASES<<18)|(BMP_PHRASES<<28),d1	; DWIDTH|IWIDTH

	move.l	d0,(a0)+
	move.l	d1,(a0)+

; Write a STOP object at end of list
	clr.l   (a0)+
	move.l  #(STOPOBJ|O_STOPINTS),(a0)+

; Now return swapped list pointer in D0

	move.l  #listbuf,d0
	swap    d0

	movem.l (sp)+,d1-d4/a0
	rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Procedure: UpdateList
;        Handle Video Interrupt and update object list fields
;        destroyed by the object processor.

UpdateList:
	move.l  a0,-(sp)

	move.l  #listbuf+BITMAP_OFF,a0

	move.l  bmpupdate,(a0)      	; Phrase = d1.l/d0.l
	move.l  bmpupdate+4,4(a0)

	add.l	#1,ticks		; Increment ticks semaphore

	move.w  #$101,INT1      	; Signal we're done
	move.w  #$0,INT2

	move.l  (sp)+,a0
	rte

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	.data
	.phrase

	.bss
	.dphrase

listbuf:    	.ds.l   LISTSIZE*2  		; Object List
bmpupdate:  	.ds.l   2       		; One Phrase of Bitmap for Refresh
ticks:		.ds.l	1			; Incrementing # of ticks
a_hdb:  	.ds.w   1
a_hde:      	.ds.w   1
a_vdb:      	.ds.w   1
a_vde:      	.ds.w   1
width:      	.ds.w   1
height:     	.ds.w   1
_vidmem:
               .ds.b   64000
vidend:       
	.end

Link to comment
Share on other sites

  • 2 years later...

is there a well documented version of this startup.s?

in my opinion a jagcoder should now about every single line of this startup and what happens there and why it is there

 

without.. i think no real programming is possible

 

all the libraries and soundengines are cool, but who should use it without knowing the jag

first of all this startup is most important

 

knowing why updating list, what is an objectlist, why its in "phrases" and "dphrases" why there is a "sneaky trick" and how it works, what about ticks, why the image is shown 5 sec, and and and...

 

would be nice to have after each source line 5 lines of description why and what happens !!!!

 

this would help standardcoders much easyer become a jaguar / asm coder

 

greets to all

Link to comment
Share on other sites

To be really honest, any seasoned programmer with a copy of the Jaguar reference manual by his side should be able to decipher what most of startup.s does. Personally I haven't written any Jaguar specific code, but I've used that startup source twice and changed it to my needs with not much effort (a boring afternoon on both occasions).

 

Now, anyone who's done the above homework and still has questions regarding startup.s can of course ask questions - I'm sure a few people will answer. But asking for what essentially is a full blown tutorial from a community with so few active developers is a bit too far fetched IMHO :).

  • Like 1
Link to comment
Share on other sites

BTW, this bit is a big load of horse ****.

 

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Procedure: gSetOLP

; Use the GPU to set the OLP and quit.

;

; Inputs: olp2set - Variable contains pre-swapped value to stuff OLP with.

;

; NOTE!!!: This code can run in DRAM only because it contains no JUMP's or

; JR's. It will generate a warning with current versions of MADMAC

; because it doesn't '.ORG'.

;

.long

.gpu

gSetOLP:

movei #olp2set,r0 ; Read value to write

load (r0),r1

 

movei #OLP,r0 ; Store it

store r1,(r0)

 

moveq #0,r0 ; Stop GPU

movei #G_CTRL,r1

store r0,(r1)

nop ; Two "feet" on the brake pedal

nop

 

.68000

.bss

.long

 

Just use the 68000 and MOVE.L #$WHATEVER,OLP. There is no need to update it via the GPU.

  • Like 1
Link to comment
Share on other sites

BTW, this bit is a big load of horse ****.

 

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Procedure: gSetOLP

; Use the GPU to set the OLP and quit.

;

; Inputs: olp2set - Variable contains pre-swapped value to stuff OLP with.

;

; NOTE!!!: This code can run in DRAM only because it contains no JUMP's or

; JR's. It will generate a warning with current versions of MADMAC

; because it doesn't '.ORG'.

;

.long

.gpu

gSetOLP:

movei #olp2set,r0 ; Read value to write

load (r0),r1

 

movei #OLP,r0 ; Store it

store r1,(r0)

 

moveq #0,r0 ; Stop GPU

movei #G_CTRL,r1

store r0,(r1)

nop ; Two "feet" on the brake pedal

nop

 

.68000

.bss

.long

 

Just use the 68000 and MOVE.L #$WHATEVER,OLP. There is no need to update it via the GPU.

 

Is this where the 'GPU outside of range' error comes from?

Link to comment
Share on other sites

remove...

 

 

move.l d0,olp2set ; D0 is swapped OLP from InitLister

move.l #gSetOLP,G_PC ; Set GPU PC

move.l #RISCGO,G_CTRL ; Go!

waitforset:

move.l G_CTRL,d0 ; Wait for write.

andi.l #$1,d0

bne waitforset

 

and replace it with:

 

move.l d0,OLP

 

then delete all this....

 

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Procedure: gSetOLP

; Use the GPU to set the OLP and quit.

;

; Inputs: olp2set - Variable contains pre-swapped value to stuff OLP with.

;

; NOTE!!!: This code can run in DRAM only because it contains no JUMP's or

; JR's. It will generate a warning with current versions of MADMAC

; because it doesn't '.ORG'.

;

.long

.gpu

gSetOLP:

movei #olp2set,r0 ; Read value to write

load (r0),r1

 

movei #OLP,r0 ; Store it

store r1,(r0)

 

moveq #0,r0 ; Stop GPU

movei #G_CTRL,r1

store r0,(r1)

nop ; Two "feet" on the brake pedal

nop

 

.68000

.bss

.long

 

... because it's pointless.

  • Like 1
Link to comment
Share on other sites

IMHO it's a waste of time to set the OP list pointer with the GPU.
There's a discussion about it here : http://www.jagware.org/index.php?showtopic=1041 (in the later posts).

 

In theory there's a low probability that using the 68000 will cause a failure, and the latest docs from Atari tell you not to do it.

But in practice, I don't think I've ever seen it happen.

  • Like 4
Link to comment
Share on other sites

  • 1 month later...

When can we expect the first version releasde of RAPTOR ?

 

I'll have a chat with all involved (Myself [yes, I often talk to myself], Matmook, Linkovitch, sh3 and Groovybee) and see what we come up with. I think the main problem is going to be support, ie, we don't have enough time to do much of it.

 

As sh3 said in another thread, the choice is... hours and hours of work into supporting this library for, what? realistically 5 or so people to use (if that!) - or put those hours into making games using it for many more to have fun with.

  • Like 1
Link to comment
Share on other sites

  • 9 months later...

I noticed few times before that you want to try to develop something for Jag. Why don't you go for the C environment (It's from Belboz, I think?) under Windows ? It has a functional "hello world" example which renders a text into the framebuffer. It works nicely in the VJ too.

 

That's all you need to start playing with the system, really. That's exactly how I started. There's a whole lot of stuff that can be done just with 68k in C.

You don't even need the reference manuals till you need sound/input functionality. Self-running in-game scripts demonstrating the game with final art assets are completely doable just in C.

 

Worry about the performance (e.g. Blitter, OP, DSP, GPU, ...) later, when you already have something up&running under VJ...

 

If you want, I can give you scripts, that build the C code, call Jiffy on it, and move the executable to VJ's directory. Thus, upon a single key-stroke in Notepad++, I just alt-tab to VJ, hit Ctrl+I to reload the binary and can test right away - all within few seconds of editing the C code...

 

If you really want, I could give you the VRBasic Beta and you could do stuff in Basic for Jag (though, I still did not finish audio/input functionality) - but again - it's great for playing and I even have like 7 samples with it and there is even some early documentation from Stephen. Though, I adhere to Microsoft's syntax of Visual Basic, so all syntax is easily googlable anyway...

Link to comment
Share on other sites

Not really, since right now I'm working on the PC game right now (and only switched - see the other Klax thread - to jag coding for 2 weekends), for next 3-4 months. Only then I can go and do a switch back to jag coding (as I already did 4 times in last 3 yrs - though the last switch had been definitely the most productive).

Link to comment
Share on other sites

okay.. thats logical,

but i searched every doc without finding something

 

What were you searching for? If you were looking for what was meant by an external, hopefully I can help describe its use?

 

When you assemble a chunk of code into an object (.o file) the assembler doesn't put any memory addresses into the code unless they have literally been specified in teh code. so a jsr label in the code points to a label defined somewhere within that code. The assembler doesn't know what the address of "label" is so leaves it blank and creates a table of labels at the end of the object.

 

When you then pass the object through the linker, it knows what the memory address for the code is, and can then compute all the label's actual addresses and goes through filling in the blanks that the assembler left.

 

If There is a label such as _start:: then this is saying that this memory address may be referenced from outside of this paticular object. So another assembly object may want to branch to it. This allows you to write code without having to include all other code/source as well. Which can lead to faster assemble times as there is no need to re-assemble the whole thing, just the bits that have changed (if you had say 10 source files, you could produce 10 objects, you change one source file, you would only need to re-assemble that one object file).. However if a source file references a label not found in that source file the assembler will assume this to by an error, by telling it that it is an external the assembler knows it won't be in this source and to ignore it for now. When the linker comes along and loads all the objects up, it should then be able to find all the external labels and fill in all the blanks throughout all the object files making a single binary.

 

In the deffintion source you might have

 

label::

code

....

 

and in the calling source

 

.EXTERN label

jsr label

 

 

Hope that helps

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...