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 > CSDb Entries > Release id #249931 : Two Tricks That Will Make You a Ridiculously Productive C64 Demo Coder
2025-02-08 01:45
Mixer

Registered: Apr 2008
Posts: 457
Release id #249931 : Two Tricks That Will Make You a Ridiculously Productive C64 Demo Coder

I thank you for the great talk Trident. The talk invited some reflection.

It is interesting that you come up with what is essentially scheduling and threads/processes from the simple need of making code easier to manage. This observation connects to something that in my experience happens in software development all the time.

The code that we produce has two classes of observers. One is the processor for which the readability or structure does not matter much. There may be some better performing sequences of instructions, but apart from that it has no preference. Then there is the human, the programmer who translates the human intent to processor code via a sequence of substitutions.

Lets say that there are two kind of problems, complex and difficult. Computing is complex. The foundations are very simple, just bits and binary logic, but to do something useful requires a lot of these components and the complexity emerges. Doing a back flip or climbing up a tree are difficult. They are difficult because of physical limitations of humans interacting with the world.

The complexity and difficulty meet in the human brain. Our brain has physical limitations and can only manage a couple of items in a few second interval. This means that in order to work with complex things, we must split everything into small chunks of just a few parts at a time. Thus it is a natural need for us to substitute groups of concepts with aggregate concepts and so on. This way the structure and organization of code and coding concepts are for humans by humans. This need also explains the thousands of design patterns and programming languages and frameworks that we've built for managing just our own concepts.

Our productivity increases when we find a new concept that can be substituted over an older one. In groups our productivity increases as we share these concepts. In projects and organizations we often choose to use particular tools or technology that is common for all programmers and so on, instead of what the processor might find most efficient.

One implication of all this is that when we plan stuff for people to do, we should take the brain into account and plan work for humans, not for "the processor" or a "process". Basically this means just splitting stuff into chunks and accepting that people can only do what they can see that they can do next. They've been researching why software is shit for decades and figured out ways to manage people and common information (agile, scrum, kanban, lean...) and so on, but that's another rant...

Well, anyway...
 
... 22 posts hidden. Click here to view all posts....
 
2025-02-11 22:57
JackAsser

Registered: Jun 2002
Posts: 2038
Quote: Quoting chatGPZ

That NMI-for-Music is something i have to think about - not sure i like it, but it sounds like a good idea :)

Edit: how are you dealing with the case when you need the processing time in the border for something else? just write a different timer value for one frame (that seems glitchy). or us a slightly smaller timer value, and wait (in a transition or so) until the music call arrives at the wanted new position?


I usually issue that NMI at rasterline $ff (but any other position is possible), so it is still possible to open borders with ease. I have never been in trouble, i always placed the music call somewhere at that place, even when still using raster IRQs for that and let the rest of things happen on the other rasterlines on screen. Moving is possible, but a bit of work in any case. THCMs sample stuff uses NMIs, and sid playing is bogus in that case anyway. It made my life way easier, especially when linking parts together. There are macros to switch the music between irq/nmi mode, hotswap so to say.
There's still visual glitches to cope with more than enough, but fighting sound glitches is like twice the work.


Must say I like this approach. I might adopt it. It's quite seldom you have timing critical stuff in the lower border anyways. (I had during the BasicFader in Codeboys, but that's it basically and it's not even shown! :D). But the full border on the whole PAL-frame is open there.
2025-02-12 09:39
Oswald

Registered: Apr 2002
Posts: 5110
sometimes you use both kind of interrupts. Ninja's 4x4 routine uses timer irq's for doing the fli (bit faster no need to change d012 each time), and raster irq to enable disable these interrupts only for the screen area.
2025-02-12 10:30
chatGPZ

Registered: Dec 2001
Posts: 11445
you can do that without NMI though :)
2025-02-12 21:11
MagerValp

Registered: Dec 2001
Posts: 1081
In the Q&A was it JackAsser that brought up eight concurrent protothreads? The audio wasn't great so maybe I got that wrong, but it sounded like source for that was available somewhere?
2025-02-13 00:40
JackAsser

Registered: Jun 2002
Posts: 2038
Quote: In the Q&A was it JackAsser that brought up eight concurrent protothreads? The audio wasn't great so maybe I got that wrong, but it sounded like source for that was available somewhere?

Yes. I mentioned Copper Booze, source available. But it’s really not proto threads there, but full threading in a cooperative way. I.e. full task switch including split stack per task.
2025-02-13 16:42
MagerValp

Registered: Dec 2001
Posts: 1081
Excellent, thank you!
2025-02-14 14:00
trident

Registered: May 2002
Posts: 100
speaking of concurrency, another cool thing with protothreads is how easy it is to implement concurrent protothreads (multiple protothreads running at the same time). you just need to define another subroutine with a protothread inside it and call that too.

for example, something like this:

irq:
{
    irq_wait($f8)

    jsr blink_logo
    jsr blink_text

    irq_set(irq, 0)
    inc $d019
    rti
}

blink_logo:
{
    jmp (pt)
pt: .word again

again:
    pt_wait_ticks(pt, 2 * 50)
    lda #5
    sta logo_color

    pt_wait_ticks(pt, 2 * 50)
    lda #6
    sta logo_color

    jmp again
}


blink_text:
{
    jmp (pt)
pt: .word again

again:
    pt_wait_ticks(pt, 1 * 50)
    lda #7
    sta text_color

    pt_wait_ticks(pt, 1 * 50)
    lda #8
    sta text_color

    pt_wait_ticks(pt, 1 * 50)
    lda #9
    sta text_color

    jmp again
}


this will blink both the text_color and the logo_color, with different frequencies.
2025-02-14 19:08
MuZZa

Registered: Nov 2020
Posts: 17
in case there's anyone who uses 64tass...

; Implement of anonymous Irq Handlers and Protothreads
; by Trident Fjälldata 2025 (64tass example)

        ; BASIC START
	* = $0801
	.text 12,8,0,0,$9e,"2061",0,0,0
	
	; CODE START
	*= $080d
    
        sei
        lda #$7f
        sta $dc0d
        bit $dc0d

        lda #$01
        sta $d01a

        lda #$35
        sta $01

        #irq_set irq, 0
        cli

        jmp *
        
        ; Calling the Protothreads
irq
        lda #$0e
        sta $d020

        #irq_wait $40
        lda #$02                        
        sta $d020

        #irq_wait $80
        lda #$03                        
        sta $d020

        #irq_wait $b4
        lda #$04                        
        sta $d020

        #irq_wait $f8
        lda #$06                         
        sta $d020

        jsr sequence

        #irq_set irq, 0
        asl $d019
        rti

sequence
.block
        jmp (pt)

again
        #pt_wait_ticks pt, 2 * 50
        lda #$05
        sta $d021

        #pt_wait_ticks pt, 2 * 50
        lda #$06
        sta $d021

        #pt_wait_ticks pt, 2 * 50
        lda #$07
        sta $d021

        jmp again

pt      .word again
        .endblock

; Macros Definitions
irq_set .macro name, rasterline
        lda #<\name
        sta $fffe
        lda #>\name
        sta $ffff
        lda #\rasterline
        sta $d012
        lda $d011
        and #$7f
        ora #(\rasterline & $100) >> 1
        sta $d011
.endm

irq_wait .macro rasterline
        #irq_set next, \rasterline
        inc $d019
        rti
next
.endm

pt_wait_ticks .macro pt, ticks
        lda #0
        sta count + 1
        lda #<again
        sta \pt
        lda #>again
        sta \pt + 1
again
count
        lda #0
        cmp #\ticks
        beq done
        inc count + 1
        rts
done
.endm
2025-02-18 09:11
Digger

Registered: Mar 2005
Posts: 446
Great stuff. I saw Bexxx doing this instead:
jmp pt:*+3

Then there's no need to declare a memory for the jump address unless one needs to use ZP ofc.
2025-02-18 09:17
bexxx

Registered: Nov 2023
Posts: 7
This is one of the possible implementation options :)
My childish self just loves self modifying code and illegal opcodes because that sounds cool :).

I did implement enable triggering of PTs like this:

handleRedTrafficLightSprites: {
jmp pt: exit

triggerStart:
delay_repeatable(pt, 2 * 50)

// show green traffic light
... all your sequence code

exit:
lda #<exit
sta pt
lda #>exit
sta pt+1

rts
}

do a
jsr handleRedTrafficLightSprites
as usual to execute it (disabled/enabled) and trigger it with
jsr handleRedTrafficLightSprites.triggerStart

depending on your needs you might not want to execute the first iteration here and just setup the pt ptrs, add rts accordingly.

Cheers,
bexxx
Previous - 1 | 2 | 3 | 4 - Next
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
Twoflower/ΤRIΛD
thesuperfrog
Pararaum/T7D
MWR/Visdom
Stone/Prosonix/Offence
E$G/HF ⭐ 7
Radiant
Brittle/Dentifrice^(?)
JackAsser/Booze Design
blala/ammb
Exile/Anubis
Guests online: 120
Top Demos
1 Next Level  (9.7)
2 13:37  (9.7)
3 Codeboys & Endians  (9.7)
4 Coma Light 13  (9.6)
5 Mojo  (9.6)
6 Edge of Disgrace  (9.6)
7 Uncensored  (9.6)
8 Comaland 100%  (9.6)
9 What Is The Matrix 2  (9.5)
10 Wonderland XIV  (9.5)
Top onefile Demos
1 Nine  (9.8)
2 Layers  (9.6)
3 Cubic Dream  (9.6)
4 Party Elk 2  (9.6)
5 Copper Booze  (9.6)
6 Rainbow Connection  (9.5)
7 Dawnfall V1.1  (9.5)
8 Onscreen 5k  (9.5)
9 Ten  (9.5)
10 50 Coins  (9.5)
Top Groups
1 Oxyron  (9.3)
2 Booze Design  (9.3)
3 Performers  (9.3)
4 Censor Design  (9.2)
5 Triad  (9.2)
Top Organizers
1 Burglar  (9.9)
2 Sixx  (9.8)
3 MWS  (9.7)
4 Irata  (9.7)
5 hedning  (9.7)

Home - Disclaimer
Copyright © No Name 2001-2025
Page generated in: 0.048 sec.