Explode routine

Hardware Hacking, Programming and Game Solutions/Cheats
Post Reply
devo
Posts: 30
Joined: Mon May 13, 2013 10:19 am
Location: Canberra, Australia

Explode routine

Post by devo »

Here is a .cas file of an "explode" routine I typed in from p178 of the book "Dragon Machine Language For The Absolute Beginner", John Vander Reyden, 1983. See Dragon archive http://archive.worldofdragon.org/archiv ... nguage.zip.

Tested on Xroar using CLOADM (Ctrl-Shift-L) and then "EXEC &H4000".

Maybe useful to others wanting learn about random number generation, sound and display routines.

The book has the full assembly listing for reference. I could not get the assembly code to work perhaps because I could not understand the use of some ORG directives which seem specific to the assembler the author used.

Hoping to code something useful myself eventually!
Attachments
explode.cas
(888 Bytes) Downloaded 321 times
User avatar
snarkhunter
Posts: 241
Joined: Fri Apr 03, 2009 7:16 pm
Location: France

Re: Explode routine

Post by snarkhunter »

devo wrote:... I could not understand the use of some ORG directives which seem specific to the assembler the author used.
Hello,

Could you please explain the above statement?! To me, 'ORG' was quite a straightforward instruction aimed at the compiler (i.e. ORG addr = code to be generated as if starting from absolute address addr, which was quite useful for some programs using absolute addressing).

And 'ORG' was often used along with the 'PUT' directive.
sixxie
Posts: 1346
Joined: Fri Jul 18, 2008 8:36 am
Location: Hertfordshire
Contact:

Re: Explode routine

Post by sixxie »

The book examples do seem to include use of "RZORG" and "REORG" pseudo-ops, which I've never seen before. Unless one of them is just a typo, my best guess would be that the assembler they used required "REORG" before a second "ORG", and that maybe "RZORG" instructed it to pad from the current position to the new address with zeroes.

No idea what assembler that would be, though!
devo
Posts: 30
Joined: Mon May 13, 2013 10:19 am
Location: Canberra, Australia

Re: Explode routine

Post by devo »

I appreciate your suggestions - they've prompted me to have another look. What I find is that when assembling the listing below with ./asm6809.pl -v -D -o produces "cannot find opcode" error for 'end' in line 18, and a little further down with 'reorg'. Commenting these out, asm6809 reports a long list of errors that suggest some problem with aligning the relative position correctly - see second listing further down. Finally, the fragment of the first part of the program listed from asm6809 can be compared with the book. This shows the memory addresses don't appear to match. What did work was simply typing in the machine code directly with Dream Bug. I expect all would be relatively trivial to fix with a bit more knowledge. Just a novice anxious to learn.

Code: Select all

* explode - Dragon M/L for Abs Beginner - p178
*
* program to produce an explosion effect.
* EORS spots onto the screen randomly
* into a growing boundary while generating
* noise using the DAC

	org $4000

* Device addresses

pia1ca	equ	$FF01	;PIA1 control reg
pia1cb	equ	$FF03	;PIA1 control reg
dac	equ	$FF20	;PIA2 data A =
devpia	equ	$FF22	;PIA2 data B =
pia2cb	equ	$ff23	;PIA2 control reg
devsam	equ	$FFC0	;SAM-RAM
*	end

* Screen variables in direct page

	org	0
start	rmb	2	;start of graphics screen
length	rmb	2	;YMAX*32
sam	rmb	1	;value for display mode reg
pia	rmb	1	;value for PIA
lowbit	rmb	1	;mask for last 3 bits of xcoord
ymax	rmb	1	;number of lines in screen
*	reorg

* Constant for screen variables
gstart	equ	$600	;start of graphics pages

* values of YMAX for modes 1, 3 and 4

ymax1 	equ 	96
ymax3	equ	192
ymax4	equ	192

* values of SAM for modes 1, 3 and 4
sam1	equ	4
sam3	equ	6
sam4	equ	6

* values of PIA for modes 1, 3 and 4
* add CSET0/1 for colour set 0/1
pia1	equ	$c0
pia3	equ	$e0
pia4	equ	$f0
cset0	equ	0
cset1	equ	8

* values of LOWBIT for modes 1,3 and 4
* mask last 3 bits of xcoordinate
* also force xcoord. even if 4 colour mode
lowb1	equ	6
lowb3	equ	6
lowb4	equ	7
*	end

* Random number generator
	org	$30
rand1n	rmb	2	;random number 1
rand2n	rmb	4	;random number 2 - must not be 0

* Variables for spotty

sdelay	rmb	1	;delay quantity
volume	rmb	1	;sound volume
size	rmb	1	;size of spot boundary
ycoord	rmb	1
xcoord	rmb	1
temp	rmb	2
sizini	rmb	1	;initial size of explosion
sizlim	rmb	1	;limit to size of explosion
sizinc	rmb	1	;increment in size of explosion
nspots	rmb	2	;number of spots at each size
vdecay	rmb	1	;rate of decay of volume
*	reorg

	org	$4000	;begin	equ	*
	lda 	#$04	;direct page = text screen
	tfr	a,dp	;direct page
	ldd	#$0460	
	sta	sizini	;initial size
	sta	sizinc	;size increment
	stb	sizlim	;limit size
	ldd	#60
	std	nspots	;spots per size
	lda	#$e0
	sta	vdecay	;volume decay rate
	ldd	#ymax3*256+sam3	;set screen variables
	sta	ymax	;for mode 3
	sta	rand2	;make sure rand2 is not zero
	stb	sam
	lda	#pia3+cset1	;colour set 1
	sta	pia
	lda	#lowb4	;allow odd x-coords
	sta	lowbit	;to get multicoloured effect
	ldd	#gstart
	std	start
	ldd	#ymax3*32
	std	length
	ldd	#0	;clear screen
	lbsr	clear	
	lbsr	screen	;display screen
	lbsr	setup	;enable sound
loop	equ	*
	lbsr	rand2	;initial coords
	cmpa	ymax	;check if valid
	bhs	loop
	std	ycoord	;& xcoord
	ldd	#$ff80	;initial amplitude & delay
	bsr	explod	;put on spots slowly
	ldd	#$0001	;take them off quickly
	bsr	explod	;and silently
	bra	loop

* Explod
*
* Subroutine to simulate an explosion. Spots are placed
* randomly onto the screen around the centre of the 
* explosion (at xcood ycood) within a boundar. The boundary
* increases in size from sizini to sizlim in steps of 
* sizinc. The volume of the noise starts at A and decays at
* a rate given by vdecay. B determines the speed of the 
* explosion.

explod	equ	*
	sta	volume	;store initial volume
	stb	sdelay	;store delay constant
	clr	rand1n	;initialise random number
	clr	rand1n+1
	lda	sizini	;set initial size
	sta	size	
expl1	ldy	nspots	;number of spots to do
expl2	equ	*
	ldb	sdelay
	bsr	spotty	;put on one spot
	leay	-1,y	;loop until y=0
	bne	expl2
	lda 	volume	;decrease volume of noise
	ldb	vdecay	
	mul
	sta	volume
	lda	sizinc	;increase size
	adda	size
	sta	size
	cmpa	sizlim	;check if big enough
	bls	expl1
	rts

*Spotty
*subroutine to EOR on spot randomly onto screen no further
* away from the centree xcoord ycoord. Random noise is
* produced with volume given by volume.

spotty	equ	*
	decb		;delay for a while 
	bne	spotty
	bsr	rand2	;make noise
	lda	volume	;of correct volume
	mul
	anda	#damask	;and put to dac
	sta	dac
	bsr	rand1	;get random number
	adda	rand1n+1	;add two random bytes
	rora		;and halve (gives a bit more central
	ldb	size	;distribution)
	mul		;range 0 to size-1
	aslb
	rola		;range 0 to size-2
	suba	size	;range -(size-1)to size-1
	sta	temp	;save it
	bsr	rand1	;do the same for the x coord
	adda	rand1n+1
	rora
	ldb	size
	mul
	aslb
	rola
	suba	size
	sta	temp+1
	ldd 	ycoord	;convert ycoord to signed number
	suba	#$80
	adda	temp	;so that we can check
	bvs	nogo	;for overlow off scren
	adda	#$80	;convert it back to unsigned
	cmpa	ymax	;check if off bottom
	bhs	nogo
	subb	#$80	;do the same for xcoord
	addb	temp+1
	bvs	nogo
	addb	#$80
	bsr	convrt	;convert to address
	eorb	,x	;put spot
	stb	,x
nogo	rts

*random number generators
*
*rand1
*
rand1	equ	*
	ldd	rand1n
	adda	rand1n+1
	aslb
	rola
	adda	rand1n+1
	aslb
	rola
	addd	rand1n
	addd	#13849
	std	rand1n
	rts
*
*rand2
*
rand2	equ	*
	lda	rand2n+3
	rora
	eora	rand2n+2
	rora
	rora
	ror	rand2n
	ror	rand2n+1
	ror	rand2n+2
	ror	rand2n+3
	ldd	rand2n
	rts
*****************************
*convrt
*
*convert A=y coordinate, B=x coordinate into x=address of
*byte on screen and B has the corresponding bit set. Position
*independent code X B modified.
*
convrt	equ	*
	pshs	d,y	;save D and Y
	lsra		;shift D right 3 bits
	rorb		;to get offset from
	lsra		;start of screen
	rorb
	lsra
	rorb
	addd	start	;gives address of byte
	tfr	d,x	;put in X reg
	puls	d	;get coordinates agains
	andb	lowbit	;select last 3 bits
	leay	contab,pcr ;get Bth byte from table
	ldb	b,y
	puls	y,pc	;restore y and return
contab	fcb	$80
	fcb	$08
*end of convrt

*screen
*
*displays screen as specified by screen variables
*position independent code
*no registers modified

screen	equ	*
	pshs	d,x
	lda	devpia	;maks pia onto high
	anda	#7	;5 bits of devpia
	ora	pia
	sta	devpia
	lda	sam	;set 3 bit of 
	ldb	#3	;vdg register to
	ldx	#devsam	;sam
	bsr	sbits	
	lda	start	;A=start address/256
	lsra		;A=start address/128
	ldb	#7s	;set 7 bits of page select reg
	bsr	sbits
	puls	d,x,pc
*set b bits of sam
sbits	equ	*	;set b bit from x
	sta	,x++	;assume last bit zero
	lsra		;take last bit
	bcc	sb0	;branch if it was 0
	sta	-1,x	;it was 1 so fix it!
sb0	decb		;loop b time
	bne	sbits
	rts
*end of screen

*clear
*
*fills screen with pairs of bytes given in D
*position independent code
*no registers modified
clear	equ	*
	pshs	x,y
	ldx	start	;pointer to start of screen
	ldy	length	;number of bytes to clear
clearx	std	,x++	;clear 2 bytes
	leay	-2,y	;loop y/2 times
	bne	clearx
	puls	x,y,pc
*end of clear

*end of explod setup
*
*enable sound output from the dac
*must be called before using the dac
*position  independent code
*no registers modified
setup	equ	*
	pshs	d
	ldd	#$b435	;set sound output from dac
	sta	pia1ca	;disable 64 microsecond int.
	stb	pia1cb	;and enable 50hz int.
	lda	#$3f	;enable dac sound
	sta 	pia2cb
	puls	d,pc
*end of setup

*mask for data to store to dac
*AND data with damask before storing to DAC
damask	equ	%11111100

Assembler output when removing 'end' and 'reorg' directives:

Code: Select all

=== Reading file 'explode.asm'
=== Pass 3
=== Pass 4
*** line 95: $4023 != $4024
*** line 96: $4026 != $4027
*** line 97: $4028 != $4029
*** line 98: $402b != $402c
*** line 99: $402d != $402e
*** line 100: $4030 != $4031
*** line 101: $4033 != $4034
*** line 102: $4036 != $4037
*** line 103: $4039 != $403a
*** line 104: $403c != $403d
*** line 105: $403f != $4040
*** line 106: $4042 != $4043
*** line 107: $4045 != $4046
*** line 109: $4048 != $4049
*** line 110: $404b != $404c
*** line 111: $404e != $404f
*** line 112: $4050 != $4051
*** line 113: $4053 != $4054
*** line 114: $4056 != $4057
*** line 115: $4058 != $4059
*** line 116: $405b != $405c
*** line 117: $405d != $405e
*** line 130: $405f != $4060
*** line 131: $4062 != $4063
*** line 132: $4065 != $4066
*** line 133: $4068 != $4069
*** line 134: $406b != $406c
*** line 135: $406e != $406f
*** line 136: $4071 != $4072
*** expl1: $4071 != $4072
*** line 138: $4075 != $4076
*** line 139: $4078 != $4079
*** line 140: $407a != $407b
*** line 141: $407c != $407d
*** line 142: $407e != $407f
*** line 143: $4081 != $4082
*** line 144: $4084 != $4085
*** line 145: $4085 != $4086
*** line 146: $4088 != $4089
*** line 147: $408b != $408c
*** line 148: $408e != $408f
*** line 149: $4091 != $4092
*** line 150: $4094 != $4095
*** line 151: $4096 != $4097
*** line 159: $4097 != $4098
*** line 160: $4098 != $4099
*** line 161: $409a != $409b
*** line 162: $409c != $409d
*** line 163: $409f != $40a0
*** line 164: $40a0 != $40a1
*** line 165: $40a2 != $40a3
*** line 166: $40a5 != $40a6
*** line 167: $40a7 != $40a8
*** line 168: $40aa != $40ab
*** line 169: $40ab != $40ac
*** line 170: $40ae != $40af
*** line 171: $40af != $40b0
*** line 172: $40b0 != $40b1
*** line 173: $40b1 != $40b2
*** line 174: $40b4 != $40b5
*** line 175: $40b7 != $40b8
*** line 176: $40b9 != $40ba
*** line 177: $40bc != $40bd
*** line 178: $40bd != $40be
*** line 179: $40c0 != $40c1
*** line 180: $40c1 != $40c2
*** line 181: $40c2 != $40c3
*** line 182: $40c3 != $40c4
*** line 183: $40c6 != $40c7
*** line 184: $40c9 != $40ca
*** line 185: $40cc != $40cd
*** line 186: $40ce != $40cf
*** line 187: $40d1 != $40d2
*** line 188: $40d3 != $40d4
*** line 189: $40d5 != $40d6
*** line 190: $40d8 != $40d9
*** line 191: $40da != $40db
*** line 192: $40dc != $40dd
*** line 193: $40df != $40e0
*** line 194: $40e1 != $40e2
*** line 195: $40e3 != $40e4
*** line 196: $40e5 != $40e6
*** line 197: $40e7 != $40e8
*** line 198: $40e9 != $40ea
*** nogo: $40e9 != $40ea
*** line 205: $40ea != $40eb
*** line 206: $40ed != $40ee
*** line 207: $40f0 != $40f1
*** line 208: $40f1 != $40f2
*** line 209: $40f2 != $40f3
*** line 210: $40f5 != $40f6
*** line 211: $40f6 != $40f7
*** line 212: $40f7 != $40f8
*** line 213: $40fa != $40fb
*** line 214: $40fd != $40fe
*** line 215: $4100 != $4101
*** line 220: $4101 != $4102
*** line 221: $4104 != $4105
*** line 222: $4105 != $4106
*** line 223: $4108 != $4109
*** line 224: $4109 != $410a
*** line 225: $410a != $410b
*** line 226: $410d != $410e
*** line 227: $4110 != $4111
*** line 228: $4113 != $4114
*** line 229: $4116 != $4117
*** line 230: $4119 != $411a
*** line 239: $411a != $411b
*** line 240: $411c != $411d
*** line 241: $411d != $411e
*** line 242: $411e != $411f
*** line 243: $411f != $4120
*** line 244: $4120 != $4121
*** line 245: $4121 != $4122
*** line 246: $4122 != $4123
*** line 247: $4125 != $4126
*** line 248: $4127 != $4128
*** line 249: $4129 != $412a
*** line 250: $412c != $412d
=== Pass 5
Listing of initial part of program:

Code: Select all

                      
                      * explode - Dragon M/L for Abs Beginner - p178
                      *
                      * program to produce an explosion effect.
                      * EORS spots onto the screen randomly
                      * into a growing boundary while generating
                      * noise using the DAC
                      
4000                          org $4000
                      
                      * Device addresses
                      
FF01                  pia1ca  equ     $FF01   ;PIA1 control reg
FF03                  pia1cb  equ     $FF03   ;PIA1 control reg
FF20                  dac     equ     $FF20   ;PIA2 data A =
FF22                  devpia  equ     $FF22   ;PIA2 data B =
FF23                  pia2cb  equ     $ff23   ;PIA2 control reg
FFC0                  devsam  equ     $FFC0   ;SAM-RAM
                      *       end
                      
                      * Screen variables in direct page
                      
0000                          org     0
0000                  start   rmb     2       ;start of graphics screen
0002                  length  rmb     2       ;YMAX*32
0004                  sam     rmb     1       ;value for display mode reg
0005                  pia     rmb     1       ;value for PIA
0006                  lowbit  rmb     1       ;mask for last 3 bits of xcoord
0007                  ymax    rmb     1       ;number of lines in screen
                      *       reorg

The book version:
explode code fragment from book
explode code fragment from book
explode.png (145.84 KiB) Viewed 6243 times
sixxie
Posts: 1346
Joined: Fri Jul 18, 2008 8:36 am
Location: Hertfordshire
Contact:

Re: Explode routine

Post by sixxie »

You can ignore that debugging - the perl script can give verbose about why it's triggered another pass.

I see the problem - neither the perl or C versions of asm6809 assume that DP is zero - until you use a SETDP directive, no assumptions will be made about whether to to use direct addressing (you can use < to force it).

This code defines a bunch of symbols from "org 0", then sets DP to 4 - without a SETDP, all the addresses will still be relative to 0.

So if you add a line at the top, "setdp 0", it works (bar one typo in the paste - "ldb #7s" needs the s stripping). I'd say the approach taken here is pretty confusing coding practice though!
Alastair
Posts: 669
Joined: Fri Jul 18, 2008 11:33 pm

Re: Explode routine

Post by Alastair »

sixxie wrote:The book examples do seem to include use of "RZORG" and "REORG" pseudo-ops, [...]
The "RZORG" on page 171 is actually a poorly printed "REORG", the same printing error occurs in my copy of the book as it does in the PDF (ditto the B of RMB a few lines above, perhaps the printing plate had a defect or some contaminate prevented the ink from adhering to those parts of the plate).

Edit...

The Macro-80C Assembler by Micro Works uses REORG and END, the manuals are available from the TRS-80 Colour Computer Archive. REORG resets the assembler's code generation pointer to the value it had before the last ORG statement, END signals the end of a source file. Was this assembler ever converted to the Dragon?
sixxie
Posts: 1346
Joined: Fri Jul 18, 2008 8:36 am
Location: Hertfordshire
Contact:

Re: Explode routine

Post by sixxie »

Interesting. asm6809 (not the perl version) allows a similar approach through the use of sections:

Code: Select all

                section "zero"
                org     $0000
tmp1            rmb     1

                section "main"
                org     $4000
func1           adda    tmp1
                rts

                section "zero"
tmp2            rmb     1               ; will follow tmp1 in memory

                section "main"
func2           suba    tmp2            ; will follow func1 in memory
                rts
The idea being to make it easier to define code & associated zero page data in included files. Sadly, yes at the moment the quotes around those section names are required.

Perhaps I'll add REORG too, for compatibility. Not that it actually appears to be used for that purpose in this book's example.
Post Reply