Page 1 of 1

Macro to check for crossing page boundary (using VASM)

Posted: Wed Jun 10, 2020 11:08 am
by rascalsailor
Hi all this is my first post. I am new to the 6502 (previously worked with the Z80 and a few other processors)
I am busy making a 6502 Single board computer which will use Sram for program memory loaded from serial link. (i.e. Eprom emulator)
I have read warnings about the page boundary bug when using jump instructions (I'm probably going to use an older 6502 device)
I am using Vasm assembler to generate the binary file to be uploaded. (Although am open to other suggestions)
Now I found a macro example for checking crossing page boundaries, but am not sure how to associate it with my code.
The macro is:

Code: Select all

wbeq    macro   dst
        beq     dst
        if (($ ^ dst) & $ff00) != 0
        warn    "Branch crossed page"
        endif
        endm
An example of my code is:

Code: Select all

CONFIG8255: EQU $2003
PORTA : EQU $2000
PORTB : EQU $2001
PORTC : EQU $2002

	ORG $FF00
reset:	

	LDA #$80
	STA CONFIG8255 
	
loop1:	
	LDA #$77
	STA PORTA	
	STA PORTB
	STA PORTC	
	JSR delay; delay here
	
	LDA #$EC
	STA PORTA	
	STA PORTB
	STA PORTC	
	JSR delay; delay here
	JMP loop1
     	
delay:
back:		LDX $FF
loopx:      LDY  $FF
loopy:	    DEY
			BNE loopy
			DEX
			BNE loopx
			RTS
firstly, I tried placing the macro at the start of my code and then trying to use it with :
wbeq <address> e.g. wbeq loop1
It gives an error - unknown opcode <warn>
So among other things - Does Vasm assembler use another directive to print a console message? (I tried looking in the documentation)
And is my implementation of how to use this macro correct?
I also saw some info at:https://atariage.com/forums/topic/14764 ... ct-access/
What do you all out there do to avoid this issue - if using the older devices?
thanks all
regards
Russell

Re: Macro to check for crossing page boundary (using VASM)

Posted: Wed Jun 10, 2020 11:28 am
by John West
rascalsailor wrote:
Does Vasm assembler use another directive to print a console message?
I can't see anything in the documentation. There's .fail for issuing a warning, but that doesn't seem to provide any way of saying what the warning is. You could make it an error and use .err: that does let you give a message.

I can't comment on the implementation of the macro, as I don't use that assembler myself. But you seem to have got the wrong idea about the JMP bug. Your macro will give false positives when there is no problem, and won't detect the actual problem.

JMP comes in two versions. The one that's almost always used is JMP abs. That takes the next two bytes after the opcode as an address and jumps to them. So after executing JMP $1234, the next instruction will be at address $1234. There is no bug in this version.

The other is JMP (abs). This takes the next two bytes after the opcode as an address, reads another address from the location they point to, then jumps to that. If we execute JMP ($1234) and locations $1234 and $1235 contain $78 and $56 respectively, the next instruction will be at $5678.

This is the version with the bug. If the instruction was instead JMP ($12ff), we would expect it to read from $12ff and $1300, but instead it reads from $12ff and $1200. You'll want your macro to examine the operand of the JMP, and if the low byte is $ff, issue a warning (or error).

This bug only exists in NMOS 6502s. It's fixed in the 65C02.

There is one situation in which you might want to know whether a branch crosses a page. The branch instructions (BEQ and so on, not JMP) take an extra cycle if they cross a page boundary. This doesn't affect program correctness, but it's something to be aware of if you need to get the highest possible performance. Most of the time it's not worth worrying about.

Re: Macro to check for crossing page boundary (using VASM)

Posted: Wed Jun 10, 2020 1:52 pm
by rascalsailor
Hi John, thanks for the reply. Yes, I imagine that I got the wrong idea with the macro.
As you say though, JMP abs is a bug-free solution, so I'll stick to that.
thanks
Russell

Re: Macro to check for crossing page boundary (using VASM)

Posted: Wed Jun 10, 2020 1:53 pm
by vbc
rascalsailor wrote:
So among other things - Does Vasm assembler use another directive to print a console message? (I tried looking in the documentation)
Depending on the syntax module:

std: .err <message>
oldstyle: fail <message>
mot: fail <message>

Of course just leaving "warn" does almost the same:
Quote:
volker@y50:/tmp$ cat w1.s
fail "my error message"
volker@y50:/tmp$ vasm6502_oldstyle -quiet w1.s

error 20 in line 1 of "w1.s": fail: "my error message"
> fail "my error message"
volker@y50:/tmp$ cat w2.s
warn "my error message"
volker@y50:/tmp$ vasm6502_oldstyle -quiet w2.s

error 2 in line 1 of "w2.s": unknown mnemonic <warn>
> warn "my error message"
As was already mentioned, the macro does not seem to concern the 6502 bug. It would also probably not work with vasm as it seems to want to use the program counter in an if-expression. vasm is a multi-pass assembler and does not allow expressions that may change during optimization passes within if.

The bug should be easily avoidable in your code (e.g. use zero page pointers for indirect jumps).

Re: Macro to check for crossing page boundary (using VASM)

Posted: Wed Jun 10, 2020 2:25 pm
by BillG
John West wrote:
There is one situation in which you might want to know whether a branch crosses a page. The branch instructions (BEQ and so on, not JMP) take an extra cycle if they cross a page boundary. This doesn't affect program correctness, but it's something to be aware of if you need to get the highest possible performance. Most of the time it's not worth worrying about.
The macro he posted is indeed about a branch crossing a page boundary.

Code: Select all

wbeq    macro   dst
        beq     dst
        if (($ ^ dst) & $ff00) != 0
        warn    "Branch crossed page"
        endif
        endm
is a replacement for the BEQ instruction which checks for page crossing.

Re: Macro to check for crossing page boundary (using VASM)

Posted: Wed Jun 10, 2020 3:41 pm
by BigEd
Welcome!

You'd care about a branch crossing a page boundary if you were cycle-counting code and the extra cycle was important. That's relatively unusual, but if it matters then it's important. Having the macro cause the assembly to abort with 'unknown opcode' sounds reasonable to me: it's an assertion fail.

(What I thought we might be looking at is something else, which is more often useful: detecting in a friendly way that a branch can be used because the target is close, whereas a JMP must be used for a long distance.)

Re: Macro to check for crossing page boundary (using VASM)

Posted: Sun Jun 14, 2020 8:00 am
by Klaus2m5
The warn directive is not known and causes the unknown opcode error. The only directive to send a message that I found is
Quote:
fail <message>
- Show an error message including the <message> string.
- Do not generate an ouput file.
There seems to be no directive to issue just a warning.

There is also another problem with your macro as it cannot be used for forward branches. The address of a forward reference is not known in pass 1.