c64 assembly

Started by Amanda Dearheart, June 16, 2023, 02:53:41

Previous topic - Next topic

Amanda Dearheart

Is this the place to ask questions about C64 assembly instructions?
Prepare to be assimilated !  Resistance is futile!

dawlane

Depends on what you want to know. Possibly the best place is to try lemmon64, or one of the other dedicated Commodore 64 sites.
 
The best place to find information for assembly programming on a particular machine, is to find the machines hardware reference guides or programming books.
Some books:
Commodore 64 Programmers Reference Guide by Commodore Inc.
Programming the 6502 by Rodnay Zaks.
Programming the Commodore 64: The Definitive Guide by Raeto Collin West.
C64 Machine Language for the Absolute Beginner by Melbourne House.

You can find these round the internet in pdf format, or go looking around ebay.

Baggey

Quote from: Amanda Dearheart on June 16, 2023, 02:53:41Is this the place to ask questions about C64 assembly instructions?
As Dawlane say's it depends on what you want to know?

Ask a question and well see.

Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 32GB ram  2x1TB SSD and NVIDIA Quadro K1200 on Acer 24" . DID Technology stop! Or have we been assimulated!

Windows10, Parrot OS, Raspberry Pi Black Edition! , ZX Spectrum 48k, C64, Enterprise 128K, The SID chip. Im Misunderstood!

Amanda Dearheart

Thanks Dawlane, Baggey.


Sr. Member???

Does that mean you guys are administrators of the site?

OK. Here's the question.

[pre]
[size=2][font=Courier New, monospace]; ===========  MAIN  =================
MAIN
        RESET$ BORDER, SCREEN, BLACK
        INTR_SET$ >BORDER_SPARKLE$, <BORDER_SPARKLE$
        JSR SFX
        CLEAR$
SFX
        BORDER_SPARKLE$
        jmp SFX[/font][/size][/pre]





I'm using the CBM Prg Suite emulator on a Windows 8.1 machine.

In the line    INTR_SET$ >BORDER_SPARKLE$, <BORDER_SPARKLE$; I'm trying to get the Hi and Lo bytes of the BORDER_SPARKE$ SFX and load them into my interrupt addresses.  Both macros (INTR_SET$, BORDER_SPARKLE$) are def'd in a separate file but included in the project by CBM Suite standards.  Yet I get an error message INVALID OPERAND, LABEL, or VARIABLE when I try to assemble  
Prepare to be assimilated !  Resistance is futile!

dawlane

#4
Quote from: Amanda Dearheart on June 16, 2023, 20:11:01Sr. Member???

Does that mean you guys are administrators of the site?
No. It means that we are Senior Members and is a rating that is given depending on how many post we have done.
Administrators and Moderators have those titles and are coloured differently to the plebs.

Quote from: Amanda Dearheart on June 16, 2023, 20:11:01CBM Prg Suite emulator
Do you mean CBM Prg Studio?
What you have posted is practically meaningless to everyone without the macros.

Xerra

That assembly code isn't going to help. It's just a list of functions by the looks of it. No actual code there. 

If you're using CBM Prg editor then I don't know why you would want to be using the high/low bit anyway, unless I'm not getting what you're saying.

M2 Pro Mac mini - 16GB 512 SSD
ACER Nitro 5 15.6" Gaming Laptop - Intel® Core™ i7, RTX 3050, 1 TB SSD
Vic 20 - 3.5k 1mhz 6502

Latest game - https://xerra.itch.io/Gridrunner
Blog: http://xerra.co.uk
Itch.IO: https://xerra.itch.io/

Baggey

I have no idea how to use Cbm Studio.

Your last line. Shouldn't it just be

jmp SFX

Note, if you jmp to SFX your stuck there forever. Unless your SFX returns you some how.

Inside your SFX routine you need to alternate the border to 'Sparkle'

The Border color is stored in Address 53280, Register 32 of the Vic Chip. The Border looks as if it's going to be black all the time? so if your going to 'Sparkle it' ie change color's or make it flash you need to load the Border register with something else.

The MSB should be 208 and LSB should be 32 ie (208*256+32)=53280. Your color goes in here.

Im assuming SFX is your (Function/Macro/Routine) for changing the border color.

Im not quite sure what your really trying to do?

If this was of no help or i mist your point. Then ignore it. :-X

Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 32GB ram  2x1TB SSD and NVIDIA Quadro K1200 on Acer 24" . DID Technology stop! Or have we been assimulated!

Windows10, Parrot OS, Raspberry Pi Black Edition! , ZX Spectrum 48k, C64, Enterprise 128K, The SID chip. Im Misunderstood!

TomToad

I'm not sure what CBM PRG Suite is. A Google search brings up CBM .prg Studio.  Did you just simply misname the program?

This is not the proper syntax for CBM .prg studio's native assembler.  Things like RESET$ and INTR_SET$ are not valid commands.  It doesn't even match the syntax for macros, so couldn't be defined elsewhere. I'm not familiar with Kick Assembler, but looking over the docs, I cannot find anything similar there.  Those are the only two assemblers supported by CBM .prg Studio.   Is it possible that you are trying to use the syntax for a different assembler in CBM .prg Studio? 

Assembly language is just the three letter mnemonics and their operands (i.e. LDA #65, STA 1024, etc...)  Everything else, such as labels, variables, macros, etc... are assembler specific and are not always compatible with each other.

------------------------------------------------
8 rabbits equals 1 rabbyte.

dawlane

Quote from: TomToad on June 18, 2023, 11:15:11Things like RESET$ and INTR_SET$ are not valid commands.  It doesn't even match the syntax for macros, so couldn't be defined elsewhere.
According to CBM Pr Studio's manual. Anything with as dollar sign is a global macro.
And as far as I'm aware. CBM Pr Studio uses it's own 6502 assembler, with the option to add Kick Assembler as an alternative.

TomToad

Quote from: dawlane on June 18, 2023, 14:16:00And as far as I'm aware. CBM Pr Studio uses it's own 6502 assembler, with the option to add Kick Assembler as an alternative.
I stand corrected.  I guess I should've looked at the part of the manual on global labels. :)
------------------------------------------------
8 rabbits equals 1 rabbyte.

Amanda Dearheart

Thanks all for your help.  I have managed to solve the problem.  Your suggestion Mr. Baggey was the most helpful of all.  When you suggested that I I need to 'alternate the border to Sparkle, I tried to in my routine to change BORDER_SPARKLE to SFX to read

INTR_SET$  >SFX, <SFX instead of  INTR_SET$ >BORDER_SPARKLE$, <BORDER_SPARKLE$, and the routine assembled without problems. Now I just need to get the routine to work.

BTW,  you're correct about the last line.  It should just be jmp SFX.  All that other HTML stuff was pasted there by syntaxbomb's code editor.  I neglected to proofread the draft before I posted it.  Anyway, I changed that to rts.

dawlane,

Yes, you're correct,  it is CBM Prg Studio that I'm using.

Here are the macro defs
; ==============  MACROS  ===========
defm    RESET$
        LDA #/3
        STA /1
        STA /2
        endm

defm    CLEAR$
        LDA #$0093                       ;  ASCII 147 CLEAR THE SCREEN
        JSR CHROUT
        RTS
        endm
                       
defm    BORDER_SPARKLE$
        INC PEN_COLOR
        LDA PEN_COLOR
        CMP $0F
        BNE _exit
        LDA $00
        STA PEN_COLOR
_exit
        RTS
        endm

defm    INTR_SET$
        SEI                             ;  $0314 and $0315 store the mem address of the routine to point to
        LDA #/1                         ;  store the high byte first
        STA $0314
        LDA #/2                         ;  then store the lo byte
        STA $0315
        CLI
        RTS
        endm
; -------------


xerra

Commodore interrupt handler request that the high and low bytes of the ml routine be stored in 314 and 315.  I forget which book I was reading for that info.  If you know otherwise, let me know.
Prepare to be assimilated !  Resistance is futile!

Amanda Dearheart

Mr. Toad,

All the macros I used in my code are ones that I have def'd in a separate file.  I have posted that file in the post above.
Prepare to be assimilated !  Resistance is futile!

Baggey

Hi Amanda, Again im not familiar with CBM studio.

But i think you've stored your addresses back to front ie Old 8 Bit is Little endian! ie LSB first and MSB last. your Address will be (2*256)+1=513 so your Routine should be placed at address 513.

However to follow Little Endian you would have Address $0314=2 and Address $0315=1 which would give Address 257 just after Zero Page!

All instructions will store and load data in the Little Endian C6502/C6510 FORMAT Exactly the same CPU apart from Address $00 and Address $01 hold Paging info for the PLA chip on the C64!

So when you store your own addresses in Mem they should always be LSB first then MSB last, ie (MSB*256)+LSB=Address. Correct me if im wrong but i think modern PC's Store as Big Endian!?

Also,
Your line of CLI i think is incorrect.
I think as you've enabled interrupts with SEI, then set the address in memory. You then CLI, Clear the interrupt flag so the interrupt cant happen anyway ::).

 When the interrupt handler triggers and jumps to your subroutine because the INTERRUPT flag=1. Inside that routine is where you CLI before you return or if you want it to keep triggering leave it set. This may cause a problem if you start adding in other routines as they will/could change the status of the INTERRUPT flag as well.


Interrupts are something im trying to get my C64 Emulator to work on! Normal interrupts are every 24000 Cycles but setting up with the VIA Chips. ie the emulation of this is another story. indeed as you get in to Vector addressing which im still not totally ofay with either. You can trigger your own subroutines.
 
defm    INTR_SET$
        SEI                             ;  $0314 and $0315 store the mem address of the routine to point to
        LDA #/1                         ;  store the high byte first
        STA $0314
        LDA #/2                         ;  then store the lo byte
        STA $0315
        CLI
        RTS
        endm


Again if ive misunderstood ignore what ive said im only trying to help! ;D

Can i ask why your learning C6502 ::)

Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 32GB ram  2x1TB SSD and NVIDIA Quadro K1200 on Acer 24" . DID Technology stop! Or have we been assimulated!

Windows10, Parrot OS, Raspberry Pi Black Edition! , ZX Spectrum 48k, C64, Enterprise 128K, The SID chip. Im Misunderstood!

Xerra

Quote from: Amanda Dearheart on June 19, 2023, 04:21:56xerra

Commodore interrupt handler request that the high and low bytes of the ml routine be stored in 314 and 315.  I forget which book I was reading for that info.  If you know otherwise, let me know.

Ok, I see what you mean now. When using interrupts I loaded 788 and 789 (decimal) bytes with the location of the code I wanted to run as an interrupt and, I think, I used CLI to clear the interrupt flag, once that code had been run. I can't remember off-hand if I had to rts back to the program counter to continue operation, though. Also it's a bit odd on 8 bit machines with the low and high bytes. 

As I used to hate working with hex I just used to use direct decimal locations (which is obviously hell when you need to relocate code in memory) as I only ever really did short machine code routines for some stuff back then, so it was pretty simple. 

So, I'd often put my code in the tape buffer - bytes 832 to 1011 'ish, which is commonly used for short assembler routines as you weren't loading from a tape when you were playing a game. This meant I didn't have to mess with lowering the basic end location, or starting it at a higher place so I could mix it all up as that stuff freaked me out even more.

My calculation would be:
832/256 = 3.25
3 * 256 = 768
832 - 768 = 64

That gives me a high byte of 3 and a low byte of 64. From memory you had to use the low byte of the address in the first location [788] and the high byte in [789].

So, in assembler I'd have something like:

LDA # 64
STA 788
LDA # 3
STA 789
SEI
[normal loop]

Pretty sure that using CLI after the code you want to run in the interrupt just reverted back to wherever normal interrupts go, so keyboard and stuff could still work. Can't remember if you could just set it once or had to use SEI constantly. Been at least 38 years since I last tried to code an interrupt on the old C64.

 
M2 Pro Mac mini - 16GB 512 SSD
ACER Nitro 5 15.6" Gaming Laptop - Intel® Core™ i7, RTX 3050, 1 TB SSD
Vic 20 - 3.5k 1mhz 6502

Latest game - https://xerra.itch.io/Gridrunner
Blog: http://xerra.co.uk
Itch.IO: https://xerra.itch.io/

Amanda Dearheart

Baggey,

3 reasons,

1.  The commodore 64 was the 2nd computer I ever purchased during the '80s. (The first was a Sinclair ZX81). I had wanted to learn assembly then but didn't have the time, money, or space.  Now that I'm retired and not married, I do.  I already purchased the C64 Maxi, and plan on buying the ZX Spectrum Next.  I also hear that there is a company planning on producing an Atari 800 xl that I'll buy.  A also purchased an Raspberry Pi 400, and an Radio Shack MC10. There are several other on my list that I want to purchase.

2.  Like other people on YouTube, I also feel nostalgic for the retro computing craze. My major project for the C64 is Delta11 a mixture of gaming types similar in style like GORF.  My 2nd minor project is the VIC-20 challenge. Since that only has 5k of ram, the purpose of this exercise is to see what type of game can be produced with that amount of memory.  Also within that line of machines will be the ZX81, MC10 and Commodore 16.

3.  Hobby reasons for now.  I plan to make money on them when I release the finished games.
Prepare to be assimilated !  Resistance is futile!