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!
Explode routine
Explode routine
- Attachments
-
- explode.cas
- (888 Bytes) Downloaded 379 times
- snarkhunter
- Posts: 241
- Joined: Fri Apr 03, 2009 7:16 pm
- Location: France
Re: Explode routine
Hello,devo wrote:... I could not understand the use of some ORG directives which seem specific to the assembler the author used.
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.
Re: Explode routine
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!
No idea what assembler that would be, though!
Re: Explode routine
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.
Assembler output when removing 'end' and 'reorg' directives:
Listing of initial part of program:
The book version:
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
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:
Re: Explode routine
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!
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!
Re: Explode routine
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).sixxie wrote:The book examples do seem to include use of "RZORG" and "REORG" pseudo-ops, [...]
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?
Re: Explode routine
Interesting. asm6809 (not the perl version) allows a similar approach through the use of sections:
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.
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
Perhaps I'll add REORG too, for compatibility. Not that it actually appears to be used for that purpose in this book's example.