JSR&FFEE

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

JSR&FFEE

Post by AJW » Fri May 15, 2020 2:03 pm

I'm trying to output to screen the value being held in the accumulator to see what's going on, but all I get is a VDU7 type sound. What am I missing?

User avatar
BigEd
Posts: 3098
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: JSR&FFEE

Post by BigEd » Fri May 15, 2020 2:07 pm

Maybe you're missing a conversion to printable characters? If the accumulator contains &07, that will come out as a beep. You'd probably want to output two characters, &30 for the zero and &37 for the seven. (Or possibly you'd want to output in decimal rather than hex.)

User avatar
jms2
Posts: 2562
Joined: Mon Jan 08, 2007 6:38 am
Location: Derby, UK
Contact:

Re: JSR&FFEE

Post by jms2 » Fri May 15, 2020 2:08 pm

Just doing JSR &FFEE will print the character corresponding to the ASCII value in the accumulator. It sounds like your accumulator must currently contain a 7!

BeebWiki offers the following code:

Code: Select all

 \ On entry, A=value to print
   \ On exit,  A corrupted
   
   .PrHex
   PHA                        :\ Save A
   LSR A:LSR A:LSR A:LSR A    :\ Move top nybble to bottom nybble
   JSR PrNybble               :\ Print this nybble
   PLA                        :\ Get A back and print bottom nybble
   .PrNybble
   AND #15                    :\ Keep bottom four bits
   CMP #10:BCC PrDigit        :\ If 0-9, jump to print
   ADC #6                     :\ Convert ':' to 'A'
   .PrDigit
   ADC #ASC"0":JMP OSWRCH     :\ Convert to character and print

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

Re: JSR&FFEE

Post by AJW » Fri May 15, 2020 2:21 pm

This reports MISTAKE:
CMP #10:BCC PrDigit :\ If 0-9, jump to print

User avatar
jms2
Posts: 2562
Joined: Mon Jan 08, 2007 6:38 am
Location: Derby, UK
Contact:

Re: JSR&FFEE

Post by jms2 » Fri May 15, 2020 4:36 pm

That line is definitely OK. I wonder, are you doing two-pass assembly, ie:

FOR pass%=0 TO 3 STEP 3
P%=code%
[OPT pass%
...code....
]
NEXT

Not doing that would lead to the issue that you are seeing. However I am puzzled that JSR PrNybble doesn't fail in the same way.

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

Re: JSR&FFEE

Post by AJW » Fri May 15, 2020 5:18 pm

It was some line numbering issue of mine.

However the assembler did complain about ':' in the comments.

User avatar
jms2
Posts: 2562
Joined: Mon Jan 08, 2007 6:38 am
Location: Derby, UK
Contact:

Re: JSR&FFEE

Post by jms2 » Fri May 15, 2020 5:21 pm

Yes, I have not seen the colons used like that before.

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

Re: JSR&FFEE

Post by BeebMaster » Fri May 15, 2020 5:35 pm

If want to know the contents of the accumulator after calling a machine code routine, you can use USR instead of CALL to execute the code. In the example code given, instead of CALL PrHex use PRINT ~USRPrHex which will call the code and then print in hex a 4 byte number representing the status register, Y register, X register and A register.

Code: Select all

10DIM code 32
20P%=code
30[
40.loadregs
50LDA#65
60LDX#100
70LDY#200
80RTS
90]
If you do CALLloadregs there's no "response" to say whether the registers have been loaded correctly, but PRINT~USRloadregs would print

Code: Select all

B0C86441
B0 = status register
C8 = Y register = 200 decimal
64 = X register = 100 decimal
41 = A register = 65 decimal

If you add

Code: Select all

75JSR&FFEE
then CALLloadregs will print A on screen as 65 is in the A register, and PRINT~USRloadregs prints the A and the 4 byte register printout.

If you'd like to know what's in the A register at a given point in the program, for debug purposes (but not print it at that exact moment), you could DIM some space and store the A register in the data block reserved by adding STA space or STA space+1 etc. then after the code executes or fails PRINT?space or PRINTspace?1 would reveal the value of the A register stored at that point.

N.B. in the above ~ is a tilde mark, not a minus sign!
Image

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

Re: JSR&FFEE

Post by AJW » Fri May 15, 2020 5:43 pm

I'm trying to decrement a counter to see when a loop should finish:

310LDA counter
320BNE lsbdec
330DEC counter+1
340.lsbdec
350DEC counter
360BNE loop

counter is stored at &76. Unfortunately, the loop doesn't finish and I can't escape it.

TopBanana
Posts: 1071
Joined: Wed Jun 09, 2010 3:16 pm
Contact:

Re: JSR&FFEE

Post by TopBanana » Fri May 15, 2020 5:59 pm

Can’t you use Exmon and just step through the code ?
Last edited by TopBanana on Fri May 15, 2020 6:00 pm, edited 1 time in total.

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

Re: JSR&FFEE

Post by BeebMaster » Fri May 15, 2020 6:00 pm

It's hard to tell from that snippet but probably the two counter loops are looping back into each other so it never finishes. To count down using a 2-byte number you need to make sure the low byte counter is operating independently, decrementing from 255 to 0, and only when it reaches zero, decrement the high byte, then test the high byte for zero and if greater than zero, re-start the low byte decrement loop from 255.

There's no escape from machine code - but you can still see what's happened after pressing BREAK if you know the memory location of "counter". Although the variable will be cleared, the value will still be stored in memory.
Image

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

Re: JSR&FFEE

Post by AJW » Fri May 15, 2020 6:13 pm

That sounds right. Strange, I had a look after break and it only decremented once!

gfoot
Posts: 11
Joined: Tue Apr 14, 2020 9:05 pm
Contact:

Re: JSR&FFEE

Post by gfoot » Fri May 15, 2020 7:44 pm

As written, your loop would count down until the low byte reaches one, then on the next cycle line 320 will still branch to line 340 (as 1 is not zero), then line 350 decrements it as usual, to zero now, and 360 will not loop this time. This is all regardless of the value of counter+1, because your loop never actually tests that.

What you probably need is for line 360 to be a JMP, and insert a similar LDA check on counter+1 just before line 330 to detect if counter+1 was already zero - and if it was, exit the loop.

Increment loops are a bit easier to write and understand if you're new to this. :)

User avatar
jgharston
Posts: 4008
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: JSR&FFEE

Post by jgharston » Fri May 15, 2020 9:12 pm

AJW wrote:
Fri May 15, 2020 5:43 pm
I'm trying to decrement a counter to see when a loop should finish:

310LDA counter
320BNE lsbdec
330DEC counter+1
340.lsbdec
350DEC counter
360BNE loop

counter is stored at &76. Unfortunately, the loop doesn't finish and I can't escape it.
Are you trying to do a 16-dit decrement? In which case, you've missed off a line:

Code: Select all

    LDA num+0:BNE skip    :\ Skip if low byte not about to wrap from &00 to &FF
    DEC num+1             :\ Decrement high byte
    .skip
    DEC num+0             :\ Decrement low byte
    \ The following code tests for zero
    BNE loop
    LDA num+1:BNE loop

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.32
(C) Copyright J.G.Harston 1989,2005-2020
>_

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

Re: JSR&FFEE

Post by AJW » Fri May 15, 2020 11:19 pm

That should work but it only decrements counter by one 384-->383 and the loop never ends or freezes somehow. The branch is in range as well I think.

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

Re: JSR&FFEE

Post by AJW » Sat May 16, 2020 2:15 pm

gfoot wrote:
Fri May 15, 2020 7:44 pm
As written, your loop would count down until the low byte reaches one, then on the next cycle line 320 will still branch to line 340 (as 1 is not zero), then line 350 decrements it as usual, to zero now, and 360 will not loop this time. This is all regardless of the value of counter+1, because your loop never actually tests that.

What you probably need is for line 360 to be a JMP, and insert a similar LDA check on counter+1 just before line 330 to detect if counter+1 was already zero - and if it was, exit the loop.

Increment loops are a bit easier to write and understand if you're new to this. :)
Yes i am new to 6502 assembly although I did a text compression routine abkut 15yrs ago.

User avatar
jgharston
Posts: 4008
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: JSR&FFEE

Post by jgharston » Sat May 16, 2020 6:31 pm

AJW wrote:
Fri May 15, 2020 11:19 pm
That should work but it only decrements counter by one 384-->383 and the loop never ends or freezes somehow. The branch is in range as well I think.
Works for me. I've wrapped it in some demo code:

Code: Select all

Escape at line 40
>L.
   10OSWRCH=&FFEE
   20DIM mcode% 100
   30num=&70
   40FOR opt%=0 TO 1
   50P%=mcode%
   60[OPT opt%*3
   70.loop
   80\ Do something in the loop:
   90LDA num+1:JSR PrHex
  100LDA num+0:JSR PrHex
  110LDA #ASC" ":JSR OSWRCH
  120:
  130\ 16-bit decrement:
  140LDA num+0:BNE skip  :\ Skip if low byte not about to wrap from &00 to &FF
  150DEC num+1            :\ Decrement high byte
  160.skip
  170DEC num+0            :\ Decrement low byte
  180:
  190\ Test and loop if not zero
  200BNE loop
  210LDA num+1:BNE loop
  220RTS
  230:
  240\ Standard PrHex routine
  250.PrHex
  260PHA:LSR A:LSR A:LSR A:LSR A
  270JSR PrNyb:PLA:.PrNyb
  280AND #15:CMP #10:BCC P%+4:ADC #6
  290ADC #ASC"0":JMP OSWRCH
  300]NEXT
>
And...
16bitDec.gif

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.32
(C) Copyright J.G.Harston 1989,2005-2020
>_

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

Re: JSR&FFEE

Post by AJW » Sat May 16, 2020 7:11 pm

May i ask how prnyb returns to the main loop and why you used BCC?

User avatar
jgharston
Posts: 4008
Joined: Thu Sep 24, 2009 12:22 pm
Location: Whitby/Sheffield
Contact:

Re: JSR&FFEE

Post by jgharston » Sat May 16, 2020 10:39 pm

AJW wrote:
Sat May 16, 2020 7:11 pm
May i ask how prnyb returns to the main loop and why you used BCC?
The RTS at the end of the OSWRCH handler.
Because 0 to 9 don't need adjusting to become the digits '0' to '9', but 10 to 15 need adjusting to become 'A' to 'F' as there's 6+1 additional characters between '9' and 'A'.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.32
(C) Copyright J.G.Harston 1989,2005-2020
>_

Post Reply

Return to “programming”