Log inRegister an accountBrowse CSDbHelp & documentationFacts & StatisticsThe forumsAvailable RSS-feeds on CSDbSupport CSDb Commodore 64 Scene Database
You are not logged in - nap
CSDb User Forums


Forums > C64 Coding > Wanted: Source codes (for badass)
2020-10-17 08:22
Sasq

Registered: Apr 2004
Posts: 155
Wanted: Source codes (for badass)

In order to improve my assembler it would be great to try it on existing projects.

So if you have sources for demos/intros/games that you don't mind sharing it would be kind if you could send them my way, and I'll try to get them working in bass.

They need to be buildable the normal way (Kickass, Acme or whatever) so I can compare the output binaries...

(this also means that if your type of demos requires special tools there is a greater chance I will include such functionality in bass).

-- sasq64@gmail.com
2020-10-17 10:48
Walt

Registered: May 2004
Posts: 47
5 released projects shipped to you, written using Kick Assembler.

Beware of random() data generated when comparing btw :)

Have fun :)
2020-10-17 11:27
TheRyk

Registered: Mar 2009
Posts: 2060
A bunch of our releases include source codes and binaries here on CSDb, all in ACME syntax, check out
https://csdb.dk/release/download.php?id=190692 Trafolta (Trackmo)
https://csdb.dk/release/download.php?id=187582 Fallen Stars (Trackmo)
https://csdb.dk/release/download.php?id=180706 MYD Show (Trackmo)
And as Trackmos might be a little over the top for your purposes, here's also
https://csdb.dk/release/download.php?id=226237 Zoolook Stars ReMeistered (4K intro)

Cheers
Ryk

PS: Enjoy the spaghetti :)
2020-10-17 12:27
Peiselulli

Registered: Oct 2006
Posts: 81
Source code of "Krawall Deluxe" is open:
https://bitbucket.org/streetuff/krawall-deluxe-final/src/master/
2020-10-17 14:04
Conrad

Registered: Nov 2006
Posts: 833
My SID Dualux sourcecode here (KickAssembler):
https://csdb.dk/release/download.php?id=167312
"start.asm" is the one to call via commandline.

If you want to try a 64Tass example, I can also give you the sfx routine for Prince of Persia:
https://codebase64.org/doku.php?id=base:sound_fx_routine
2020-10-17 14:27
tlr

Registered: Sep 2003
Posts: 1714
I have released source codes for mainly native tools I did, some examples:
DTVMON V1.2
Format II
DMA loader II
2020-10-17 16:08
Six

Registered: Apr 2002
Posts: 287
https://github.com/sixofdloc/2018intro tmpx format, intro source

https://github.com/sixofdloc/cyofa tmpx format, adventure book engine

https://github.com/sixofdloc/netlib network library, dasm format
2020-10-17 23:27
Sasq

Registered: Apr 2004
Posts: 155
Thanks a lot everyone, I have stuff to do now :)
2020-10-18 11:49
Krill

Registered: Apr 2002
Posts: 2839
Some small'n'easy stuff:
Zoompinski [512 bytes]
Fontesquieu 256b
2020-10-18 16:00
Copyfault

Registered: Dec 2001
Posts: 466
Following the path of TheRyk, I'm absolutely fine if you want to use the source-codes of any release I did the code for (in case I had one included). Should at least be the case with The Other Lines, Sideborder Sprite Data Fetch TestProg (both ACME) and Scene Farts (Kickass).
2020-10-18 22:50
Isildur

Registered: Sep 2006
Posts: 274
Some sources from Golara/Samar/Desire + my graphics:
https://gitlab.com/pseregiet
2020-10-19 10:35
Alta

Registered: Dec 2010
Posts: 9
Quoting Sasq
They need to be buildable the normal way (Kickass, Acme or whatever) so I can compare the output binaries...

How far are you willing to go for allowing assembler syntax? Merlin and ORCAM are probably not worth it, but I could share more example sources for x65 if it would help add brace scoping (code inbetween { and } with referencing the start and end of the current scope with ! and % is what I use the most). I'm probably the only one using the assembler for demos so might not be worth it.
2020-10-20 06:17
Martin Piper

Registered: Nov 2007
Posts: 633
This this ACME source, it has particularly tricky forward references: https://github.com/martinpiper/ACME/blob/master/TestForForwardR..

The output should be: https://github.com/martinpiper/ACME/raw/master/TestForForwardRe..
2020-10-20 13:47
Sasq

Registered: Apr 2004
Posts: 155
The forward example works fine in bass, but requires 4 passes.
2020-10-20 13:54
Sasq

Registered: Apr 2004
Posts: 155
@Krill: Which assembler; what is exp() and log() defined as ?
2020-10-20 14:03
Sasq

Registered: Apr 2004
Posts: 155
@Krill: never mind, works now :)
2020-10-20 14:12
tlr

Registered: Sep 2003
Posts: 1714
Here are a few of the tests from my own (stalled) assembler project: asmtests-20201020.tar.gz

There are a two forward reference examples that are kind of nasty (patho1.asm/patho2.asm) and some examples of stacked relative origin and stacked segment constructs.
2020-10-20 14:28
Sasq

Registered: Apr 2004
Posts: 155
@tlr:

patho1.asm is easy.

patho2.asm will require an extra pass for each fill, so I have to increase max passes to get it to compile, becomes very slow but works :)

* PASS 1
* PASS 2
* PASS 3
* PASS 4
* PASS 5
* PASS 6
* PASS 7
* PASS 8
* PASS 9
* PASS 10
* PASS 11
* PASS 12
* PASS 13
* PASS 14
* PASS 15
* PASS 16
* PASS 17
* PASS 18
default 1000->10c8
1000-10c8 default
builds/release/bass asmtests-20201020/patho2.asm  0,38s user 0,00s system 99% cpu 0,375 total
2020-10-20 15:22
tlr

Registered: Sep 2003
Posts: 1714
Quote: @tlr:

patho1.asm is easy.

patho2.asm will require an extra pass for each fill, so I have to increase max passes to get it to compile, becomes very slow but works :)

* PASS 1
* PASS 2
* PASS 3
* PASS 4
* PASS 5
* PASS 6
* PASS 7
* PASS 8
* PASS 9
* PASS 10
* PASS 11
* PASS 12
* PASS 13
* PASS 14
* PASS 15
* PASS 16
* PASS 17
* PASS 18
default 1000->10c8
1000-10c8 default
builds/release/bass asmtests-20201020/patho2.asm  0,38s user 0,00s system 99% cpu 0,375 total


The performance of mine for reference:
tlr@sakura:examples$ time conasm -v patho2.asm
-- resolved in 18 iterations --

real	0m0.004s
user	0m0.004s
sys	0m0.000s
tlr@sakura:examples$
It only supports a limited set of pseudo assembly constructs though.
2020-10-20 19:07
Krill

Registered: Apr 2002
Posts: 2839
Quoting Sasq
@Krill: never mind, works now :)
How about Artefacts and of course Krill's Loader, Repository Version 184 then? =)
2020-10-20 19:31
Sasq

Registered: Apr 2004
Posts: 155
ca65 stuff is just so different I don't think I'll bother with that (yet).
2020-10-21 12:47
Martin Piper

Registered: Nov 2007
Posts: 633
Quote: The forward example works fine in bass, but requires 4 passes.

Cool, it did a good job.

Try this, it uses quite complex macros with pass by reference labels: https://github.com/martinpiper/C64Public/blob/master/SpriteMult..

It should generate: https://github.com/martinpiper/C64Public/raw/master/SpriteMulti..
2020-10-21 23:20
Sasq

Registered: Apr 2004
Posts: 155
What does expressions on left hand side of assignments do;

SomeSybol+1 = something

?
2020-10-21 23:24
Frantic

Registered: Mar 2003
Posts: 1627
Not sure, but.. forcing 8bit (zeropage)? +2 = 16bit
2020-10-22 05:24
Martin Piper

Registered: Nov 2007
Posts: 633
Quote: What does expressions on left hand side of assignments do;

SomeSybol+1 = something

?


Forces zero page, before the exact value is known.
2020-10-23 09:58
Sasq

Registered: Apr 2004
Posts: 155
I started converting this but there are so many Acme specific constructs I gave up after a while...
2020-10-23 12:51
Golara
Account closed

Registered: Jan 2018
Posts: 212
https://gitlab.com/pseregiet/samar-ghost-in-the-sydney-c64
https://gitlab.com/pseregiet/desire-fastline-c64-intro
https://gitlab.com/pseregiet/samar-watcher-of-time-and-space-c64
https://gitlab.com/pseregiet/desire-4k-for-moonshine
https://gitlab.com/pseregiet/one-year-a-scener
2020-10-23 13:30
TheRyk

Registered: Mar 2009
Posts: 2060
contact ACME creator Mac Bacon normally he's eager to help
2020-10-26 23:26
Walt

Registered: May 2004
Posts: 47
REUTools 1.0 also contains source code...
2020-11-01 06:23
Krill

Registered: Apr 2002
Posts: 2839
One thing i just came across again:

It would be nice to have the assembler emit an actual 16-bit operand with things like "lda $0000" and "sta $0000,x" as opposed to "lda $00" etc.

They seem to consistently insist on knowing better and "optimise" the code for zeropage access.

To counter this, all kinds of syntax (one fuglier than the next) to force specific address sizes were invented. Ugh. =)
2020-11-01 09:15
tlr

Registered: Sep 2003
Posts: 1714
Quoting Krill
One thing i just came across again:

It would be nice to have the assembler emit an actual 16-bit operand with things like "lda $0000" and "sta $0000,x" as opposed to "lda $00" etc.

They seem to consistently insist on knowing better and "optimise" the code for zeropage access.

To counter this, all kinds of syntax (one fuglier than the next) to force specific address sizes were invented. Ugh. =)

Tricky case. Do you have a suggestion for a good rule for this except in the trivial case with a constant?
I suppose a bit string concept like in 64tass might be sufficient. Not sure if 64tass uses it in that way though.
2020-11-01 11:32
Krill

Registered: Apr 2002
Posts: 2839
Quoting tlr
Tricky case. Do you have a suggestion for a good rule for this except in the trivial case with a constant?
I'm mostly interested in the trivial case where there are 16-bit values with a zero high-byte as literal operands (to be used with self-modifying and unrolled code).

When going via indirections (labels, symbols, expressions), explicitly marking 16-bit access the traditional way is okay.
2020-11-01 12:42
tlr

Registered: Sep 2003
Posts: 1714
Quote: Quoting tlr
Tricky case. Do you have a suggestion for a good rule for this except in the trivial case with a constant?
I'm mostly interested in the trivial case where there are 16-bit values with a zero high-byte as literal operands (to be used with self-modifying and unrolled code).

When going via indirections (labels, symbols, expressions), explicitly marking 16-bit access the traditional way is okay.


Recording the number of bits a constant was defined with, but maybe not propagating it through expressions would solve your use case. Might be annoying that it behaves differently if used in expression though.

I'd look a 64tass and see if and how that solves it first though.
2020-11-01 12:43
soci

Registered: Sep 2003
Posts: 473
Technically possible even with labels and expressions but it'd be too fragile to rely on it. Also some people tend to write out excess zeros to line up columns nicely(?).

The suggested "trivial" case for "mnemonic $00xx" would be not okay as it results in an inconsistent special case.

Personally what I tend to do is:

lda $abcd,x ; random address as it'll be overwritten anyway

lda @w 0,x ; traditionally

Further alternatives:

lda 0,b,x ; ask for address in data bank (not restricted to 65816)

selfmod = 0,b
lda selfmod,x ; same but self descriptive

.dpage ? ; direct page independent code
lda 0,x ; therefore this won't result in B5 00
2020-11-01 13:24
Krill

Registered: Apr 2002
Posts: 2839
Yes, i don't like any of those workarounds. :)

What about annotating the opcode, such as "lda.w $0000"?
And if that's ambiguous because it could imply reading a 16-bit value, not reading from a 16-bit address, something like "lda.m $0000"?
2020-11-01 14:28
tlr

Registered: Sep 2003
Posts: 1714
Quote: Yes, i don't like any of those workarounds. :)

What about annotating the opcode, such as "lda.w $0000"?
And if that's ambiguous because it could imply reading a 16-bit value, not reading from a 16-bit address, something like "lda.m $0000"?


This is how it works in dasm, at least my fork. This is also how chose to handle it in my own assembler. .a/.w for forcing 16-bit and .z/.b for forcing 8-bit.

I thought you didn't like it being explicitly annotated? Maybe I assumed wrong?
2020-11-01 14:31
Krill

Registered: Apr 2002
Posts: 2839
Quoting tlr
I thought you didn't like it being explicitly annotated? Maybe I assumed wrong?
I'd prefer no annotations, but with annotations, i'd prefer them on the opcodes, not the operands.
2020-11-01 14:45
tlr

Registered: Sep 2003
Posts: 1714
Quote: Quoting tlr
I thought you didn't like it being explicitly annotated? Maybe I assumed wrong?
I'd prefer no annotations, but with annotations, i'd prefer them on the opcodes, not the operands.


I too obviously prefer them on the opcodes. Paradoxically, allowing them implicitly would actually need to attach that property to the operand though. Allowing both implicit and explicit will need resolution code to handle some corner cases when the operand property conflicts with explicit opcode size.

It wouldn't be entierly weird to allow size extensions to the actual operand btw, e.g $00.w or (5 + 2).b. IIRC 68k asms have such constructs. Again, 64tass has _loads_ of such features, but syntax can always be argued about. :)
2020-11-04 11:35
Sasq

Registered: Apr 2004
Posts: 155
I have now refactored the assembler into using an AST for parsing, so parsing does not have to happen for every pass, and not for every rept, define or other block.
For instance, a !rept 30000 { opcode } is now around 15x faster.

It also means the parser can become a lot more advanced.
2020-11-04 12:04
Golara
Account closed

Registered: Jan 2018
Posts: 212
Quote: I too obviously prefer them on the opcodes. Paradoxically, allowing them implicitly would actually need to attach that property to the operand though. Allowing both implicit and explicit will need resolution code to handle some corner cases when the operand property conflicts with explicit opcode size.

It wouldn't be entierly weird to allow size extensions to the actual operand btw, e.g $00.w or (5 + 2).b. IIRC 68k asms have such constructs. Again, 64tass has _loads_ of such features, but syntax can always be argued about. :)


well 68k, x86 and any other arch needs this kind of syntax since they can load 8, 16, 32+ bit words. On 6502 you only need a distinction because of the zero page. I'd rather have the one byte address be always ZP and 2 byte address always be a full address, i.e

lda $00 = zp load
lda $000 = normal load
2020-11-04 12:14
Sasq

Registered: Apr 2004
Posts: 155
As was mentioned earlier, this requires the size of a Number to be part of the numeric token, and propagate through expressions -- meaning you need C-like promotion of different integer types.

Could for sure be done, but not something I would do now.
If I create a "promotable" type system for other reasons (to make it easier to do things like combine arrays, numbers and lambdas in expressions) then I may add support for it.
2020-11-04 13:16
tlr

Registered: Sep 2003
Posts: 1714
Quote: well 68k, x86 and any other arch needs this kind of syntax since they can load 8, 16, 32+ bit words. On 6502 you only need a distinction because of the zero page. I'd rather have the one byte address be always ZP and 2 byte address always be a full address, i.e

lda $00 = zp load
lda $000 = normal load


Yes, but what about things like:
      lda lab,x
lab   equ $f0 + 15
Do you want lda <abs>,x or lda <zp>,x?
2020-11-04 13:19
tlr

Registered: Sep 2003
Posts: 1714
Quote: I have now refactored the assembler into using an AST for parsing, so parsing does not have to happen for every pass, and not for every rept, define or other block.
For instance, a !rept 30000 { opcode } is now around 15x faster.

It also means the parser can become a lot more advanced.


Yay! An AST really pays off.

All this discussion actually got inspired to update mine a bit too. My aim might be a bit different though, although I noticed I'd put lua scripting in the TODO too. :)
2020-11-04 13:46
Krill

Registered: Apr 2002
Posts: 2839
Quoting tlr
Yes, but what about things like:
      lda lab,x
lab   equ $f0 + 15
Do you want lda <abs>,x or lda <zp>,x?
Sum is $ff, so this is not really ambiguous yet, i guess.

I'd implement the type promotion from ZP to mem16 access to happen when the result is at least $0100.

If this would be
lab = $00f0 + 15
instead, it would mean mem16 access, as the biggest type is mem16 in that expression.

But there should be some way to explicity force ZP access on a symbol (when all operands in an expression have type ZP but result in a value >255).
Could be as simple as "symbol = <( ... bla... expression )", though. :)
2020-11-04 17:07
tlr

Registered: Sep 2003
Posts: 1714
Quoting Krill
Quoting tlr
Yes, but what about things like:
      lda lab,x
lab   equ $f0 + 15
Do you want lda <abs>,x or lda <zp>,x?
Sum is $ff, so this is not really ambiguous yet, i guess.

I'd implement the type promotion from ZP to mem16 access to happen when the result is at least $0100.

If this would be
lab = $00f0 + 15
instead, it would mean mem16 access, as the biggest type is mem16 in that expression.
It was probably a bad example. $100 - 15 would be a better example. If the result is interpreted as zp, then the behaviour would be different.
Your idea with mem16 would solve that case if I understand it correctly.
2020-11-04 17:23
chatGPZ

Registered: Dec 2001
Posts: 11107
I'd prefer those ambigious cases to just show an error, so i am forced to write into the code explicitly what i mean/want. All those "smart" automatisms *will* fail to do what you intended in one case or another - and result in a night of WTF
2020-11-04 18:36
Krill

Registered: Apr 2002
Posts: 2839
Quoting tlr
$100 - 15 would be a better example. If the result is interpreted as zp, then the behaviour would be different.
Your idea with mem16 would solve that case if I understand it correctly.
I think most sensible would be to remain with the mem16 type in such a case. Then there is no implicit type demotion from mem16 to ZP, which i think would do more harm than good anyways. There was a 16-bit address on the way somewhere, probably for a good reason. :)

But then yeah, maybe what Groepaz said. Might be a good idea to have an option (default setting to be discussed) to force the programmer to mark the result type explicitly if the individual types within an expression are mixed. Then there is no implicit type conversion in any direction. This might be a bit annoying, as i'd prefer "$0100 + 15" over "$0100 + $000f" for getting 16-bit memory access without any warnings or errors.
2020-11-04 21:24
JackAsser

Registered: Jun 2002
Posts: 1989
Quote: I'd prefer those ambigious cases to just show an error, so i am forced to write into the code explicitly what i mean/want. All those "smart" automatisms *will* fail to do what you intended in one case or another - and result in a night of WTF

Agreed
2020-11-05 12:59
Golara
Account closed

Registered: Jan 2018
Posts: 212
I would skip the whole math and just use what's in the code, that is.

lda $f0 + $0A = lda $00 (still zp)
lda $00f0 + $0a = lda $0100

But since Sasq says it's more complicated to parse or whatever... well, too bad. I'm just saying what I'd be happy with
2020-11-05 13:14
Krill

Registered: Apr 2002
Posts: 2839
Quoting Golara
I would skip the whole math and just use what's in the code, that is.

lda $f0 + $0A = lda $00 (still zp)
lda $00f0 + $0a = lda $0100

But since Sasq says it's more complicated to parse or whatever... well, too bad. I'm just saying what I'd be happy with
This seems to be the "largest type in expression determines access size" and "no type demotion" idea i detailed above.
2020-11-05 13:48
Golara
Account closed

Registered: Jan 2018
Posts: 212
Quote: Quoting Golara
I would skip the whole math and just use what's in the code, that is.

lda $f0 + $0A = lda $00 (still zp)
lda $00f0 + $0a = lda $0100

But since Sasq says it's more complicated to parse or whatever... well, too bad. I'm just saying what I'd be happy with
This seems to be the "largest type in expression determines access size" and "no type demotion" idea i detailed above.


Point is, I don't think the automatic optimization to ZP is necessary, ZP is pretty small and always used knowingly. Adding a postfix like lda.w sta.b would be ugly, since only few opcodes would use that and it would destroy the perfect 3 characters for opcode rule which I really like.

For numbers that are generated in a loop, like :
.for (var i = 0; i < 100; i++) {
    lda i
    sta i+10
} 

I'd just add a static zero of a 1 or 2 bytes size
.for (var i = 0; i < 100; i++) {
    lda $00 + i
    sta $0000 + i + 10
}
2020-11-05 14:00
Sasq

Registered: Apr 2004
Posts: 155
There is not really an "automatic optimization". It's just that when it is time to assemble the opcode, we don't know which opcode to pick, and it makes most sense to pick the zp opcode if the argument is below $100.

I think the ideal would be something like;

* We support 3 numeric types, 8-bit, 16-bit and automatic.
* A literal matching $xxxx becomes 16-bit, $xx -> 8-bit, all others automatic.
* The type is kept during expression evaluation. If an operation causes an 8-bit value to overflow, then that is an _error_.
* An automatic type is converted to 8 or 16-bit depending on size when it is time to assemble the opcode.
2020-11-05 14:14
Sasq

Registered: Apr 2004
Posts: 155
There are special cases though. Let's say you have some weird routine that matches zero page addresses to the lower byte of some 16-bit address. Which opcode would you expect here ?

data = $c000
sta data & $ff
2020-11-05 14:55
tlr

Registered: Sep 2003
Posts: 1714
Quote: There are special cases though. Let's say you have some weird routine that matches zero page addresses to the lower byte of some 16-bit address. Which opcode would you expect here ?

data = $c000
sta data & $ff


I think it would be reasonable if an '&' masked the size of the other operand, resulting in size 8 in this case.
2020-11-05 15:20
Sasq

Registered: Apr 2004
Posts: 155
So what is the rule ? How do we know what the code actually means ?

We can't demote to 8-bit just because the value becomes < 256, that defeats the whole point. So it must be "if it looks like he REALLY means it", ie explicitly anding with constant $ff.

But what about
sta data & mask
sta data & (size-1)
sta data & (... complex expression)


madness lies here. For cases like this the programmer needs to rely on something like

sta.b data & $ff
2020-11-05 15:29
tlr

Registered: Sep 2003
Posts: 1714
Quoting Sasq
So what is the rule ? How do we know what the code actually means ?

You could demote to 8-bit because one of the operands of '&' is 8-bit. Same for '%' as they are essentially wrapping operations. Not sure if there will be other bad consequences because of this though.
2020-11-05 15:32
chatGPZ

Registered: Dec 2001
Posts: 11107
Quote:
How do we know what the code actually means ?

you write it, explicitly :)
2020-11-05 16:27
Sasq

Registered: Apr 2004
Posts: 155
This would mean that

table:
    !fill 256
end:

size = table-end

sta data & (size-1)
sta data & $ff


would generate different opcodes, because size is not 8-bit

All this would require a complicated type and promotion system, and you could only get it to do _almost_ what you want.

I think

sta     ; addressing mode depends on operand
sta.b   ; zp
sta.w   ; 16-bit


is probably the simplest/best way to do it.
2020-11-05 16:35
Raistlin

Registered: Mar 2007
Posts: 552
Or just use sta.zp and sta.abs in the same way as KickAss?
2020-11-05 16:43
Sasq

Registered: Apr 2004
Posts: 155
Sure, what you call the suffix is no too important :)

Probably .8 .b .zp .z should all be synonyms
And .w .16 .abs
2020-11-05 16:47
chatGPZ

Registered: Dec 2001
Posts: 11107
.whatimean
2020-11-05 17:00
JackAsser

Registered: Jun 2002
Posts: 1989
Quote: Sure, what you call the suffix is no too important :)

Probably .8 .b .zp .z should all be synonyms
And .w .16 .abs


Hear hear
2020-11-07 16:29
Peiselulli

Registered: Oct 2006
Posts: 81
ACME :
You can force ACME to use a specific addressing mode by adding "+1",
"+2" or "+3" to the assembler mnemonic. Each one of these postfixes
sets the relevant "Force Bit" in ACME's result. If Force Bit 3 is set,
ACME will use 24-bit addressing. Force Bit 2 means 16-bit addressing
and Force Bit 1 means 8-bit addressing. Higher Force Bits have higher
priorities.

Here's an (overly complicated) example:

	symbol1   = $fb
	symbol2   = $fd
	symbol3+3 = $ff	; set Force Bit 3 and store in symbol's flags

		ldx   $fa
		ldy+2 $fc	; set Force Bit 2 (16-bit addressing)
		lda+3 $fe	; set Force Bit 3 (24-bit addressing)
		stx   symbol1
		sty+2 symbol2	; set Force Bit 2 (16-bit addressing)
		sta   symbol3	; no need to set Force Bit 3 as it is
				; already set in "symbol3".

will be assembled to

  a6 fa		; ldx $fa
  ac fc 00	; ldy $00fc
  af fe 00 00	; lda $0000fe
  86 fb		; stx $fb
  8c fd 00	; sty $00fd
8f ff 00 00 ; sta $0000ff


from:
https://github.com/meonwax/acme/blob/master/docs/AddrModes.txt
2020-11-07 17:32
Krill

Registered: Apr 2002
Posts: 2839
ACME never ceases to amaze me over and over again with its creative syntax. =)
2020-11-14 09:09
tlr

Registered: Sep 2003
Posts: 1714
I'm pondering a bit about syntax for referencing symbols in different scopes... towards inner scopes I guess 'outer.inner.symbol'... is a reasonable syntax, but what about the parent scope, or an absolute reference, i.e from the global scope?

Python3 uses .global and .nonlocal key words to specify the bindings of variables in the current scope, but I'd personally prefer something directly in the symbol reference.
Parent scope could be @p.symbol and global @g.symbol perhaps? Not entierly happy with that though.

Any personal favorites here?

(Maybe this should be in a new thread as it's a generic assembly syntax question, but it's useful for the discussion here as well.)
2020-11-14 09:31
Krill

Registered: Apr 2002
Posts: 2839
Quoting tlr
what about the parent scope, or an absolute reference, i.e from the global scope?
Just a quick shot without thinking much about it, but what about a ".." prefix to go up/out one scope, similar to traversing folder structures? Would be something like "..outer.inner" to reach a same-level scope's inner symbol. Could be enhanced for "..." to go up two scopes, etc.

A fully qualified path starting from the global scope could be prefixed with ":", e.g., ":scope.child.grandchild".

@p.* and @g.* sure are not pretty. :)
2020-11-14 09:42
tlr

Registered: Sep 2003
Posts: 1714
Quote: Quoting tlr
what about the parent scope, or an absolute reference, i.e from the global scope?
Just a quick shot without thinking much about it, but what about a ".." prefix to go up/out one scope, similar to traversing folder structures? Would be something like "..outer.inner" to reach a same-level scope's inner symbol. Could be enhanced for "..." to go up two scopes, etc.

A fully qualified path starting from the global scope could be prefixed with ":", e.g., ":scope.child.grandchild".

@p.* and @g.* sure are not pretty. :)


I've thought about '..' as well. Somewhat analogous to file system paths but I'm not fully happy with that either. In 64tass '..' is the string concatenation operator, and that's quite nice.
':' would be similar to Amiga OS path specifiers I guess. An alternative would be a '/' analogous to a *nix path. I prefer ':' though.

I couldn't find a good comparison on how this works in different languages.
2020-11-14 09:58
Krill

Registered: Apr 2002
Posts: 2839
Quoting tlr
I couldn't find a good comparison on how this works in different languages.
":" is more "languagy" compared to "/". :) See https://en.wikipedia.org/wiki/Scope_resolution_operator and maybe also https://erlang.org/doc/reference_manual/expressions.html#functi.. or https://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-qualnames.

".." for string concatenation... hmm, does "+" not work due to ambiguities or so? :)
2020-11-14 10:43
tlr

Registered: Sep 2003
Posts: 1714
Quote: Quoting tlr
I couldn't find a good comparison on how this works in different languages.
":" is more "languagy" compared to "/". :) See https://en.wikipedia.org/wiki/Scope_resolution_operator and maybe also https://erlang.org/doc/reference_manual/expressions.html#functi.. or https://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-qualnames.

".." for string concatenation... hmm, does "+" not work due to ambiguities or so? :)


Thanks for the links!
Do you mean languagy (<- is that even a word :) as in computer languagy? I've never seen '..' used for this purpose. Feels a bit messy syntax-wise to me as the scope separator uses the same descriptor as the reference to the parent scope, especially if referencing to parents higher up, e.g '....scope1.scope2.label', etc...
I guess that could be relieved with something like '(..).scope1' or similar. Maybe (/).scope1 would work for global?

I believe '+' does not work for that purpose in 64tass because constants may be (always?) 'bit strings'. This means concatenation is a valid operation and is different from addition.
Soci might be able to elaborate on this.
2020-11-15 10:49
soci

Registered: Sep 2003
Posts: 473
"+" is for numerical sum only because calculations may be performed with strings. For example 1 - 'a' + 'z' is 26 (if letters are encoded in a sequence). Therefore concatenation must have a different operator.

As for means of access to a specific parent scope (without using it's name) I see little value in that. It's a good idea to name labels meant for cross-scope access unique while stacking up scopes. That way there's no confusion over which label or scope in which parent scope is referenced in a child.

If there's an "lp2" two levels up which needs access but there's another "lp2" in the current or the immediate parent and writing "something.lp2" isn't an option either (as "something" was reused too) then adding an unnamed parent access on top of that won't really improve the situation in my opinion.
2020-11-15 18:43
tlr

Registered: Sep 2003
Posts: 1714
Quoting soci
As for means of access to a specific parent scope (without using it's name) I see little value in that. It's a good idea to name labels meant for cross-scope access unique while stacking up scopes. That way there's no confusion over which label or scope in which parent scope is referenced in a child.

I'm thinking this might be useful for exporting a label beyond something akin to your .block or .proc scope, e.g having an entry point different than the first byte in the block.

But having said that, how to you access a named parent scope in 64tass?
2020-11-15 20:05
Krill

Registered: Apr 2002
Posts: 2839
Quoting soci
"+" is for numerical sum only because calculations may be performed with strings. For example 1 - 'a' + 'z' is 26 (if letters are encoded in a sequence). Therefore concatenation must have a different operator.
I thought single quotes would denote chars (which allow arithmetics) and double quotes strings. This would neatly allow + for string concatenation, as it does in C++ and other languages.
2020-11-15 20:58
tlr

Registered: Sep 2003
Posts: 1714
Quoting Krill
I thought single quotes would denote chars (which allow arithmetics) and double quotes strings. This would neatly allow + for string concatenation, as it does in C++ and other languages.

Me too, although "c" is quite common in this context as well. It starts to get a bit tricky once you add multiple data types.

Btw, another use for parent is to break out of relocated origin addresses. For instance finding out the "parent" pc of a relocated part of the code. This may be done in more than one level.
Maybe not be entierly related though as .logical/.here or .rorg/.rend and friends needn't be scopes per se. It could be entierly orthogonal but I'm not sure what to call it except "parent".
2020-11-15 22:20
soci

Registered: Sep 2003
Posts: 473
Label of a block is always at its start. However it does not have to be used as an entry point. Usually for such special functions I write something like below:
					    *=$1000

.1000	20 06 10	jsr $1006	    jsr stuff

=$1006					stuff = (+).entry
.1003					+   .proc
.1003	9d 00 04	sta $0400,x	lp  sta $400,x
.1006					entry
.1006	e8		inx		    inx
.1007	d0 fa		bne $1003	    bne lp
.1009	60		rts		    rts
					   .pend

An anonymous symbol was used as it's only used in the expression above to get the entry point.

Named parent scope access is exactly what it sounds:
b1   .block
label1
b2a    .block
label2
       .bend
b2b    .block
c1       .block
         jsr b1.label1
         jmp b1.b2a.label2
         jmp b2a.label2
         .bend
       .bend
     .bend

After all labels of parent scopes are visible for children.

It's not like I had much choice as the C64 TASM uses double quotes for both literals and strings. Therefore there's no special casing for character literals. Single quotes can be used for easy enclosing of text containing double quotes.
.1000	a9 93		lda #$93	lda #"{clr}"
.1002	20 d2 ff	jsr $ffd2	jsr $ffd2

					.al
.1005	a9 49 44	lda #$4449	lda #"id"
.1008	8d 00 04	sta $0400	sta $400

Yes it may take a while to remember the concatenation operator but it's not impossible to get used to it.

As for "parent" PC I usually just put a label in front:
						      *=$1000

.1000						label .logical $800
>1000	0800	00 10				      .word label
						      .here

Such a label is more useful for the installer code than the relocated one. As a .logical/.here block is just a relocation and so there's no label scoping.

But I see the point. If an assembler insists to scope every block then tough luck.
2020-11-16 12:15
tlr

Registered: Sep 2003
Posts: 1714
Quoting soci
Label of a block is always at its start. However it does not have to be used as an entry point. Usually for such special functions I write something like below:
					    *=$1000

.1000	20 06 10	jsr $1006	    jsr stuff

=$1006					stuff = (+).entry
.1003					+   .proc
.1003	9d 00 04	sta $0400,x	lp  sta $400,x
.1006					entry
.1006	e8		inx		    inx
.1007	d0 fa		bne $1003	    bne lp
.1009	60		rts		    rts
					   .pend

An anonymous symbol was used as it's only used in the expression above to get the entry point.

That's quite good. I wasn't sure if the constant assignment itself would trigger generation of the .proc contents.

Quoting soci
Named parent scope access is exactly what it sounds:
b1   .block
label1
b2a    .block
label2
       .bend
b2b    .block
c1       .block
         jsr b1.label1
         jmp b1.b2a.label2
         jmp b2a.label2
         .bend
       .bend
     .bend

After all labels of parent scopes are visible for children.

So scope lookup works the same as symbol lookup in 64tass? I.e search all scopes towards the global scope until it matches?
This isn't an entierly obvious behaviour to me, but perhaps it makes sense.

Being able to put stuff in the global scope is useful for implementing stateful behaviour of macros perhaps. The "start" macro could push stuff to a global stack and the "end" macro could pop it back, effectively implementing scope like behaviour.
Using your search method there is automatically a way to address the global scope, assuming it has a unique name and was already defined. But would it be reasonable to be able to _define_ stuff outside the local scope?

Quoting soci
As for "parent" PC I usually just put a label in front:
						      *=$1000

.1000						label .logical $800
>1000	0800	00 10				      .word label
						      .here

Such a label is more useful for the installer code than the relocated one. As a .logical/.here block is just a relocation and so there's no label scoping.

As an example in the freezer of superfluid I generate a depacking stub by copying it into place and then updating a couple of key variables at that location. The stub itself contains parts that are relocated so I have stacked relocations going on. Currently this is assembled in stages and there are separate calculations to find out the address of the various modification points.

Quoting soci
But I see the point. If an assembler insists to scope every block then tough luck.

I personally avoid an explicit scope for relocated origin too. Again in superfluid I even enter and exit the relocated scope within macros ENTER_ULTIMAX and EXIT_ULTIMAX which moves execution from $8000 space to $e000 space and vice versa. This would be impossible if this relocation was a scope.

I guess the struggle is to define (in a comprehendable way) at what stage different things get translated.
2020-11-22 17:55
Krill

Registered: Apr 2002
Posts: 2839
Fresh 64tass syntax code to test against: Transwarp V0.64 =)
RefreshSubscribe to this thread:

You need to be logged in to post in the forum.

Search the forum:
Search   for   in  
All times are CET.
Search CSDb
Advanced
Users Online
zscs
Alakran_64
Andy/AEG
megasoftargentina
Guests online: 94
Top Demos
1 Next Level  (9.8)
2 Mojo  (9.7)
3 Coma Light 13  (9.7)
4 Edge of Disgrace  (9.6)
5 Comaland 100%  (9.6)
6 No Bounds  (9.6)
7 Uncensored  (9.6)
8 The Ghost  (9.6)
9 Wonderland XIV  (9.6)
10 Bromance  (9.6)
Top onefile Demos
1 It's More Fun to Com..  (9.8)
2 Party Elk 2  (9.7)
3 Cubic Dream  (9.6)
4 Copper Booze  (9.5)
5 Rainbow Connection  (9.5)
6 TRSAC, Gabber & Pebe..  (9.5)
7 Onscreen 5k  (9.5)
8 Wafer Demo  (9.5)
9 Dawnfall V1.1  (9.5)
10 Quadrants  (9.5)
Top Groups
1 Oxyron  (9.3)
2 Nostalgia  (9.3)
3 Booze Design  (9.3)
4 Censor Design  (9.3)
5 Crest  (9.3)
Top Webmasters
1 Slaygon  (9.7)
2 Perff  (9.6)
3 Morpheus  (9.5)
4 Sabbi  (9.5)
5 CreaMD  (9.1)

Home - Disclaimer
Copyright © No Name 2001-2024
Page generated in: 0.131 sec.