Help with *load

bbc micro/electron/atom/risc os coding queries and routines
Post Reply
AJW
Posts: 907
Joined: Sun Feb 15, 2004 2:01 pm
Contact:

Help with *load

Post by AJW » Tue Jul 21, 2020 1:16 pm

I'm *loading a background music player but it's not working.
on closer inspection two sample bytes are zero where they should be otherwise.

O%=&6c00:P%=&4285
Then *saved 6C00 6E7b (635bytes)

When I *LOAD it at 4285, 4285 should be 1 and 4456 (the "on" subroutine) should be 169 but they are both 0.

I can CALL&4456 after the program is assembled and the music starts but not after *loading the code.

Is there a step I'm missing?

cmorley
Posts: 1322
Joined: Sat Jul 30, 2016 8:11 pm
Location: Oxford
Contact:

Re: Help with *load

Post by cmorley » Tue Jul 21, 2020 1:27 pm

Are you doing 2 pass assembly? If so did you set O% & P% inside the FOR loop?

Code: Select all

FOR pass%=0TO3STEP3
O%=...:P%=...
[OPTpass%
...]
N.

AJW
Posts: 907
Joined: Sun Feb 15, 2004 2:01 pm
Contact:

Re: Help with *load

Post by AJW » Tue Jul 21, 2020 2:24 pm

Yes

julie_m
Posts: 237
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Help with *load

Post by julie_m » Tue Jul 21, 2020 2:41 pm

Press ctrl+N and *DUMP the machine code file. Can you see from that what might be going wrong?

Note you need OPT 4 on the first pass and OPT 6 or OPT 7 on the second pass.

AJW
Posts: 907
Joined: Sun Feb 15, 2004 2:01 pm
Contact:

Re: Help with *load

Post by AJW » Tue Jul 21, 2020 2:56 pm

Ok will try. Yes using 4 and 7.

AJW
Posts: 907
Joined: Sun Feb 15, 2004 2:01 pm
Contact:

Re: Help with *load

Post by AJW » Tue Jul 21, 2020 3:15 pm

Well &4456 -&4285 = &1D1 . ?&4456 is 169 when initially assembled but when dumped:
Untitled.png
Seems to be 08?

julie_m
Posts: 237
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Help with *load

Post by julie_m » Tue Jul 21, 2020 5:53 pm

Where's the beginning of the dump file? That's where the error is.

Remember you need the first (starting) address in your *SAVE to be based on the starting value of O% and the fourth (reload) address to be where it actually runs from. (I habitually use .begin as my first label, and also label the first RTS in my code as .rts to use for the third (execution) address in a *SAVE if there is no obvious single entry point.)

AJW
Posts: 907
Joined: Sun Feb 15, 2004 2:01 pm
Contact:

Re: Help with *load

Post by AJW » Tue Jul 21, 2020 6:14 pm

So *SAVE mus 6C00 6E7B 4456 4285

That doesn't work it seems.
Untitled2.png

AJW
Posts: 907
Joined: Sun Feb 15, 2004 2:01 pm
Contact:

Re: Help with *load

Post by AJW » Tue Jul 21, 2020 6:53 pm

Wait, I am using opt 0 and 3. Still doesn't play but at least the bytes are being stored.

cmorley
Posts: 1322
Joined: Sat Jul 30, 2016 8:11 pm
Location: Oxford
Contact:

Re: Help with *load

Post by cmorley » Tue Jul 21, 2020 7:52 pm

I find using start address + length an easier syntax...
*SAVE fn 6C00+27B 4285

I think if anyone is to offer more help for your problem you're going to have to post some more code.

julie_m
Posts: 237
Joined: Wed Jul 24, 2019 9:53 pm
Location: Derby, UK
Contact:

Re: Help with *load

Post by julie_m » Tue Jul 21, 2020 7:59 pm

&4456 - &4285 = &01D1. At 01D1 in your dump (&6DD1 in the original assembly), we see 08 01 03 02. 08 is PHP. 01 03 is ORA(&03),X. 02 isn't a valid instruction opcode.

I was expecting to see at least a few closing round brackets ) in the right-hand side of the dump; since the opcode for LDA#imm is &A9 and will display the same as &29, which is the ASCII code for a closing round bracket. I'd also expect to see some £ signs (&60 = RTS). Surely any valid code would end in an RTS, even if it didn't have any LDA# instructions in it? Are you sure that you are saving the same bit of memory where the code is actually being assembled? It's not even first-pass code (which would have all the correct opcodes, just wrong addresses) so it's not just O% and P% being defined outside the FOR loop.

The arguments to *SAVE need to be:

Code: Select all

<first location to save> {<first location [i]not[/i] saved> | +<length>} [<execution address> [<reload address>]]
If O% gets set to code% at the top of the FOR loop and the first label after your opening square bracket is .begin , the code is to begin executing at .play and there is a label .end immediately before the closing square bracket, then

Code: Select all

PRINT ~code%;" +";~end-begin;" ";~play;" ";~begin
should give you the addresses you need, in the right order.

Code: Select all

OSCLI "SAVE MUS " +STR$~code%+" +"+STR$~(end-begin)+" "+STR$~play+" "+STR$~begin
should even save it for you, if you are too lazy to COPY the addresses from the screen!

Otherwise I think we've reached the point now where you are going to have to let the dog see the rabbit, so to speak.

AJW
Posts: 907
Joined: Sun Feb 15, 2004 2:01 pm
Contact:

Re: Help with *load

Post by AJW » Tue Jul 21, 2020 9:25 pm

I don't get why it doesn't work, before I've done the same without *saving execution and reload addresses.
Note I 've cut out the tune to3 notes.

Code: Select all

   10 PROCinit
   20ENVELOPE 1,8,0,0,0, 0,0,0, 63,10,0,-6,63,126
   30REMCALLmusinit
   40 REPEAT
   50 CLS:PRINT''"Press a key to start music."'" ";:*FX21,0
   60 REPEAT:I%=(I%+1)MOD10:VDU8:PRINT;I%;:UNTILINKEY100<>-1:CALL on
   70 CLS:PRINT''"Press a key to stop music."'" ";:*FX21,0
   80 REPEAT:I%=(I%+1)MOD10:VDU8:PRINT;I%;:UNTILINKEY100<>-1:CALL off
   90 UNTIL 0
  100 END
  110 DEFPROCinit
  120 DIM code 635:REM sound 7
  130 osword=&FFF1
  140 osbyte=&FFF4
  150 REMvector=&206
  160 REMspeed=&70
  170 REMnumber=&73
  180 counter=&60:REM keep, was 74
  190 position=&61:REM keep, was 75
  200 REM?number=154:REM no. of data lines
   350PROCcode:REMg=GET
  360FOR note=0 TO 3:REM?number-1
  370READ TMP:REMchann?note
  380READ volume?note
  390READ pitch?note
  400READ length?note
  410NEXT
414E%=on:F%=off
415REM *SAVE CODE HERE TO GAMES DISC? NEED (N longer initmusic) on and off stored as integers
416OSCLI("SAVE MUS 6C00 6E7B")
417P.~E%,~F%:G=GET
  420DATA 1,1,129,5
  430DATA 1,1,125,5
 
1374DATA1,0,0,60

 1375ENDPROC
 1376DEF PROCcode
 1377 FOR pass%=4 TO7STEP3

 1378O%=&6C00
1379P%=&4285
 1380[OPT pass%
 1381\.chann \put this in place of the DIMs and do the reading in after
 1390]
 1400REMFORt=0TO 3:REM?number
 1410REM[OPT pass%
 1420REMEQUB0
 1430REM]
 1440REMNEXTt
 1450[OPT pass%
 1460.volume
 1470]
 1480FORt=0TO 3:REM?number
 1490[OPT pass%
 1500EQUB0
 1510]
 1520NEXTt
 1530[OPT pass%
 1540.pitch
 1550]
 1560FORt=0TO 3:REM?number
 1570[OPT pass%
 1580EQUB0
 1590]
 1600NEXTt
 1610[OPT pass%
 1620.length
 1630]
 1640FORt=0TO 3:REM?number
 1650[OPT pass%
 1660EQUB0
 1670]
 1680NEXTt
 1690[OPT pass%
 1700\.musinit
 1710\LDA#75\ data+1
 1720\STA speed \speed 75
 1730\LDA data+2\#3000 MOD 256
 1740\STA speed+1
 1750\LDA data+3\#3000 DIV 256
 1760\STA speed+2 \cycles 3000
 1770\RTS
 1780 .on \need to store this as integer and pass to main game loop somehow, as with .off
 1790 LDA #0
 1800 STA counter
 1810 STA position
 1820 LDX #7
 1830 .loop\store 0 in sound array ie reset all
 1840 STA sound,X
 1850 DEX
 1860 BPL loop
 1870 LDA #&5F \setting VIA up,95,bits 0,1,2,3,4,6 set; disable other interrupts
 1880 STA &FE6E \interrupt  enable register
 1890 LDA #&A0 \160 bits 5 and 7 set; clears interrupts and times out T2 timer
 1900 STA &FE6D \interrupt flag reg
 1910 STA &FE6E \IER; bits 5 and 7; enable interrupt using timer T2
 1920 LDA #&96\\150,setbits 1,2,4,7;PB latch enable,shift out under control of T2
 1930\one-shot output pulse to PB7 (peripheral B -user- port7,used by timers) from CB2 via shift reg (8bits); physically shift data to peripheral device/routine using interrupt
 1940 STA &FE6B \aux control reg
 1950 LDA #3000MOD256\speed+1
 1960 STA &FE68 \T2 low order counter
 1970 LDA #3000DIV256\speed+2
 1980 STA &FE69 \ high order counter;3000 CPU cycles equivalent written in
 1990 LDA #handler MOD 256 \store addr of music routine at vector&206
 2000 STA &206\vector
 2010 LDA #handler DIV 256
 2020 STA &207\vector+1
 2030 RTS
 2040 .off
 2050 LDA #&7F \disable all interrupt bits 0-6set
 2060 STA &FE6E
 2070 RTS
 2080 .handler
 2090 PHP
 2100 PHA
 2110 TXA
 2120 PHA
 2130 TYA
 2140 PHA
 2150 LDA counter
 2160 CLC
 2170 ADC #1
 2180 STA counter
 2190 CMP #75\speed+0
 2200 BNE return\if counter not reached spped,75,return
 2210 LDA #0
 2220 STA counter \if counter reaches speed then reset
 2230 JSR music \when counter reaches speed,75, call music routine
 2240 .return
 2250 LDA #3000MOD256\speed+1\reset timer2 counter with 3000cycles, as in one-shot mode
 2260 STA &FE68
 2270 LDA #3000DIV256\speed+2
 2280 STA &FE69
 2290 PLA
 2300 TAY
 2310 PLA
 2320 TAX
 2330 PLA
 2340 PLP
 2350 RTI \\return from interrupt mode
 2360 .music
 2370 LDX position
 2380 LDA #1\chann,X
 2390 STA sound+0
 2400 EOR #251
 2410 TAX \get sound channel to check buffer
 2420 LDA #&80\128
 2430 LDY #&FF \256
 2440 JSR osbyte
 2450 CPX #15 \check for 15 entries in buffer?
 2460 BNE continue
 2470 LDX position
 2480 LDA volume,X
 2490 STA sound+2
 2500 LDA pitch,X
 2510 STA sound+4
 2520 LDA length,X
 2530 STA sound+6
 2540 LDA #7
 2550 LDX #sound MOD 256
 2560 LDY #sound DIV 256
 2570 JSR osword \sound x and y param block cape 2bytes each lsb msb
 2580 INC position
 2590 LDA position
 2600 CMP #154\number
 2610 BNE continue
 2620 LDA #0
 2630 STA position
 2640 .continue
 2650 RTS
 2660.data
 2670EQUB 6
 2680EQUB75:EQUB&B8:EQUB&0B
 2690.sound EQUW0:EQUB0
 2760]
 2770NEXTpass%
 2780 ENDPROC

AJW
Posts: 907
Joined: Sun Feb 15, 2004 2:01 pm
Contact:

Re: Help with *load

Post by AJW » Tue Jul 21, 2020 9:37 pm

Got it - I wasn't reserving enough bytes at the end, needed EQUD,EQUD meaning I wasn't reserving enough in DIM code (639) nor saving the right range - the correct being 6C00-6E7F.

User avatar
BeebMaster
Posts: 3641
Joined: Sun Aug 02, 2009 5:59 pm
Location: Lost in the BeebVault!
Contact:

Re: Help with *load

Post by BeebMaster » Wed Jul 22, 2020 12:08 am

It's very easy to do, which is why having a label at the very end of the assembler, as already suggested, is good practice for knowing the end point of the assembled code - the assembler print-out only shows the start location of the last instruction, so it's easy to miscalculate the end point.

Also not reserving enough DIM space is very easy to do, so I'd always recommend reserving as much space as possible rather than trying to keep it to the exact code size. If the code is bigger than the amount of space reserved it can end up overwriting subsequent reserved space or variables.
Image

Post Reply

Return to “programming”