How to calculate memory location of a coordinate?

Here you can ask questions or provide insights about how to use efficiently 6502 assembly code on the Oric.
User avatar
peacer
Flight Lieutenant
Posts: 451
Joined: Wed Jun 09, 2010 9:23 pm
Location: Turkey
Contact:

How to calculate memory location of a coordinate?

Post by peacer »

I want to use a simple routine to calculate which memory address is used for a character to display on the screen at coordinates of X and Y..

Firstly, is there a rom routine for that? For example, getting 2 memory locations as input and calculating the adress by adding display memory top adress + Y*40 + X for text mode. Maybe PLOT or PRINT@ commands might use such rom routine.

If there's no preprogrammed rom routine, can you give me a simple code to do that? Adding 40*Y to a memory adress means looping Y times of 16 bits ADC adding command and this could be time consuming..

I have a game project in my mind using Basic and machine code together and trying to speed up some works with Machine code. So instead of saying : A=48040+X+Y*8 , I want to say : POKE 0,X:POKE 1,Y:CALL #1000 and get the calculated address from DEEK(2) for example. Then I will call another routine to display the characters on calculated address.

So would this code will speed up things ? Or should I keep up with basic as it might be useless?
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: How to calculate memory location of a coordinate?

Post by Dbug »

The easiest and fastest is to use a precalculated table that contains 200 entries with the final address already calculated.

In most of my code you will find these tables, just one example: http://miniserve.defence-force.org/svn/ ... /display.s

Code: Select all

_HiresAddrLow			.dsb 256
_HiresAddrHigh			.dsb 256

	; Generate screen offset data
	lda #<$a000
	sta tmp0+0
	lda #>$a000
	sta tmp0+1

	ldx #0
loop
	; generate two bytes screen adress
	clc
	lda tmp0+0
	sta _HiresAddrLow,x
	adc #40
	sta tmp0+0
	lda tmp0+1
	sta _HiresAddrHigh,x
	adc #0
	sta tmp0+1

	inx
	cpx #200
	bne loop
My new code now tends to use 256 entries, with the last 56 ones pointing to an empty area with 40 unused bytes, that allows me to not even bother clipping: It will just draw garbage in some unimportant place :)

Advantage of this method: It is also easy to implement in BASIC.
User avatar
peacer
Flight Lieutenant
Posts: 451
Joined: Wed Jun 09, 2010 9:23 pm
Location: Turkey
Contact:

Re: How to calculate memory location of a coordinate?

Post by peacer »

:) Thanks for the reply... Its beyond my ability though..

Machine code: too much code for too simple work :)

Thanks anyway !
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: How to calculate memory location of a coordinate?

Post by Dbug »

Can't you just do that?

Code: Select all

10 DIM LINE%(200)
20 FOR Y=0 TO 199:LINE%(Y)=#BB80+Y*40:NEXT Y
After, all you have to do yo get the address is to get LINE%(Y)+X
User avatar
peacer
Flight Lieutenant
Posts: 451
Joined: Wed Jun 09, 2010 9:23 pm
Location: Turkey
Contact:

Re: How to calculate memory location of a coordinate?

Post by peacer »

Hmm... it makes sense. Thank you :)
Godzil
Squad Leader
Posts: 774
Joined: Sat May 21, 2011 7:21 pm
Location: Between UK and France
Contact:

Re: How to calculate memory location of a coordinate?

Post by Godzil »

Dbug wrote:Can't you just do that?

Code: Select all

10 DIM LINE%(200)
20 FOR Y=0 TO 199:LINE%(Y)=#BB80+Y*40:NEXT Y
After, all you have to do yo get the address is to get LINE%(Y)+X
And I think, even if the BASIC is not that quick, it will be quicker than having to poke to value, call an ASM function, then DEEK the return value
User avatar
Hialmar
Flight Lieutenant
Posts: 349
Joined: Tue Mar 04, 2014 11:25 am
Location: Toulouse, France
Contact:

Re: How to calculate memory location of a coordinate?

Post by Hialmar »

Not too sure about this.

Basic will need to convert the first operand to the Float kind used with basic and then make the addition as a float. All this is slow as hell.
Hialmar
CEO and Silicium member.
User avatar
peacer
Flight Lieutenant
Posts: 451
Joined: Wed Jun 09, 2010 9:23 pm
Location: Turkey
Contact:

Re: How to calculate memory location of a coordinate?

Post by peacer »

I wrote this code to calculate the adress

Code: Select all

$103B  A9 80      LDA #$80      .. 
$103D  85 00      STA $00       .. 
$103F  A9 BB      LDA #$BB      .. 
$1041  85 01      STA $01       .. 
$1043  A6 03      LDX $03       .. 
$1045  18          CLC           .  
$1046  A5 00      LDA $00       .. 
$1048  69 28      ADC #$28      i( 
$104A  85 00      STA $00       .. 
$104C  90 02      BCC $1050     .. 
$104E  E6 01      INC $01       .. 
$1050  CA         DEX           .  
$1051  D0 F2      BNE $1045     .. 
$1053  18         CLC           .  
$1054  A5 00      LDA $00       .. 
$1056  65 02      ADC $02       e. 
$1058  85 00      STA $00       .. 
$105A  90 02      BCC $105E     .. 
$105C  E6 01      INC $01       .. 
$105E  60         RTS
So in a way, this works

POKE 2,X:POKE 3,Y:CALL #1035

This puts calculated address to memory location 0 (TEXT mode)
User avatar
Dbug
Site Admin
Posts: 4437
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: How to calculate memory location of a coordinate?

Post by Dbug »

Hialmar wrote:Not too sure about this.

Basic will need to convert the first operand to the Float kind used with basic and then make the addition as a float. All this is slow as hell.
Are you sure it will, when using integer variables and arrays?
User avatar
Hialmar
Flight Lieutenant
Posts: 349
Joined: Tue Mar 04, 2014 11:25 am
Location: Toulouse, France
Contact:

Re: How to calculate memory location of a coordinate?

Post by Hialmar »

Geoff Philipps tells it (chapter 6 Maths):
All calculations are done in ‘floating point’, In BASIC, numbers can be stored in either a floating-point variable (e.g., B) or an integer variable (e.g., C%). A variable such as B can contain any number up to an accuracy of nine digits, with a decimal point that ‘floats’ up and down the number. An integer variable can only contain a number between – 32768 and +32767, without a decimal point. Although in theory this would seem to be faster to process, the ROM can only manipulate numbers in floating-point form, so converts any integers that are used.
I'm not quoting the remainder of the chapter but everyone using Basic should read it. Microsoft guys were completely crazy to do this like that. I understand it was simpler for them to switch from Z80 to 6502 and to 6800 code but it's so slow !

Oh and X and Y are not integer variables. But anyway it's better to use them as the integer equivalents actually need conversion to floating point before any calculations.
Hialmar
CEO and Silicium member.
Godzil
Squad Leader
Posts: 774
Joined: Sat May 21, 2011 7:21 pm
Location: Between UK and France
Contact:

Re: How to calculate memory location of a coordinate?

Post by Godzil »

That's why Apple Integer Basic (the one design by Woz) was so quick against the AppleSoft (microsoft) one?
User avatar
Hialmar
Flight Lieutenant
Posts: 349
Joined: Tue Mar 04, 2014 11:25 am
Location: Toulouse, France
Contact:

Re: How to calculate memory location of a coordinate?

Post by Hialmar »

Yep :)

I have the WozPak with a ton of assembler from Integer Basic and other old stuff and it's way more optimized ;)
Hialmar
CEO and Silicium member.
Post Reply