6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 11:04 pm

All times are UTC




Post new topic Reply to topic  [ 171 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10 ... 12  Next
Author Message
PostPosted: Sat Dec 07, 2019 4:00 pm 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
New problem. Optimizing chain of single register assignment sometimes produces code that uses already deallocated reg:

Code:
call __wolin_pl_qus_wolin_SomeClass_suma[adr]
free SPF<pl.qus.wolin.SomeClass.suma.__returnValue>, #1
let &SP(0)<__wolin_reg16>[ubyte*] = SPF(2)<pl.qus.wolin.SomeClass.suma.__returnValue>[ubyte] <--- OOOOOPS!


I guess I have to find such cases and "manually" move
Code:
free
past such assignment.


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 08, 2019 12:58 pm 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
I'm pretty sure I've found no OO language for C64 during my searches, so am I getting "First 6502 OO Cup"?

This code sets border to result of calling a method on allocated object:

Code:
package pl.qus.wolin

var border: ubyte^53280

fun allocMem(size: uword, count: uword): uword {
    return 30000
}

class SummingClass {
    var x: ubyte = 3
    var y: ubyte = 7

    fun suma(): ubyte {
        return x+y
    }
}

fun main() {
   val testowa : SummingClass
   testowa = SummingClass()
   border = testowa.suma()
}


In optimized pseudo-asm:

Code:
setup HEADER
setup SPF = 251[ubyte], 40959[uword]
setup SP = 143[ubyte]
setup HEAP = 176[ubyte]
let __wolin_pl_qus_wolin_znak<pl.qus.wolin.znak>[ubyte] = #0[ubyte]
let __wolin_pl_qus_wolin_i<pl.qus.wolin.i>[uword] = #0[ubyte]
alloc SPF, #2
call __wolin_pl_qus_wolin_main[adr]
ret

function __wolin_pl_qus_wolin_allocMem
let SPF(4)<pl.qus.wolin.allocMem.__returnValue>[uword] = #30000[uword]
free SPF<pl.qus.wolin.allocMem.__fnargs>, #4
ret

function __wolin_pl_qus_wolin_SummingClass
alloc SPF, #6
let SPF(2)<pl.qus.wolin.allocMem.size>[uword] = #3[uword]
let SPF(0)<pl.qus.wolin.allocMem.count>[uword] = #1[uword]
call __wolin_pl_qus_wolin_allocMem[adr]
let SPF(2)<pl.qus.wolin.SummingClass.__returnValue>[any*] = SPF(0)<pl.qus.wolin.allocMem.__returnValue>[uword]
setup HEAP = SPF(0)<pl.qus.wolin.allocMem.__returnValue>[uword]
let HEAP(2)<pl.qus.wolin.SummingClass.x>[ubyte] = #3[ubyte]
let HEAP(1)<pl.qus.wolin.SummingClass.y>[ubyte] = #7[ubyte]
free SPF<pl.qus.wolin.allocMem.__returnValue>, #2
ret

function __wolin_pl_qus_wolin_SummingClass_suma
setup HEAP = this
alloc SP<__wolin_reg8>, #2
let SP(0)<__wolin_reg8>[ubyte*] = *HEAP(2)<pl.qus.wolin.SummingClass.x>[ubyte]
add &SP(0)<__wolin_reg8>[ubyte*] = &SP(0)<__wolin_reg8>[ubyte*], HEAP(1)<pl.qus.wolin.SummingClass.y>[ubyte]
let SPF(2)<pl.qus.wolin.SummingClass.suma.__returnValue>[ubyte] = &SP(0)<__wolin_reg8>[ubyte*]
free SP<__wolin_reg8>, #2
free SPF<pl.qus.wolin.SummingClass.suma.__fnargs>, #2
ret

function __wolin_pl_qus_wolin_main
alloc SP<__wolin_reg13>, #2
let SP(0)<__wolin_reg13>[any*] = SPF(0)<pl.qus.wolin.main..testowa>[any*]
alloc SP<__wolin_reg14>, #2
alloc SPF, #2
call __wolin_pl_qus_wolin_SummingClass[adr]
let SP(0)<__wolin_reg14>[any*] = SPF(0)<pl.qus.wolin.SummingClass.__returnValue>[any*]
let &SP(2)<__wolin_reg13>[any*] = &SP(0)<__wolin_reg14>[any*]
free SP<__wolin_reg14>, #2
free SP<__wolin_reg13>, #2
alloc SP<__wolin_reg16>, #2
let SP(0)<__wolin_reg16>[ubyte*] = 53280[ubyte*]
alloc SPF, #3
let SPF(0)[any*] = SPF(2)<pl.qus.wolin.main..testowa>[any*]
call __wolin_pl_qus_wolin_SummingClass_suma[adr]
let &SP(0)<__wolin_reg16>[ubyte*] = SPF(0)<pl.qus.wolin.SummingClass.suma.__returnValue>[ubyte]
free SP<__wolin_reg16>, #2
free SPF<pl.qus.wolin.main.__fnargs>, #1
free SPF<pl.qus.wolin.SummingClass.__returnValue>, #2
free SPF<pl.qus.wolin.SummingClass.suma.__returnValue>, #1
ret

label __wolin_indirect_jsr
goto 65535[adr]
label __wolin_pl_qus_wolin_znak
alloc 0[ubyte]
label __wolin_pl_qus_wolin_i
alloc 0[uword]


And finally in 6502 asm:

Code:
; setupHEADER


;**********************************************
;*
;* BASIC header
;*
;* compile with:
;* cl65.exe -o assembler.prg -t c64 -C c64-asm.cfg -g -Ln labels.txt assembler.s
;*
;**********************************************
            .org 2049
            .export LOADADDR = *
Bas10:      .word BasEnd
            .word 10
            .byte 158 ; sys
            .byte " 2064"
            .byte 0
BasEnd:     .word 0
            .word 0
            ;


; setupSPF=251[ubyte],40959[uword]


; prepare function stack
__wolin_spf := 251 ; function stack ptr
__wolin_spf_hi := 251+1 ; function stack ptr

__wolin_spf_top := 40959 ; function stack top
__wolin_spf_top_hi := 40959+1 ; function stack top
    lda #<__wolin_spf_top ; set function stack top
    sta __wolin_spf
    lda #>__wolin_spf_top
    sta __wolin_spf+1

; setupSP=143[ubyte]


; prepare program stack
__wolin_sp_top := 143 ; program stack top
__wolin_sp_top_hi := 143+1 ; program stack top
    ldx #__wolin_sp_top ; set program stack top

; setupHEAP=176[ubyte]


__wolin_this_ptr := 176
__wolin_this_ptr_hi := 176+1


; let__wolin_pl_qus_wolin_znak<pl.qus.wolin.znak>[ubyte]=#0[ubyte]


    lda #0
    sta __wolin_pl_qus_wolin_znak

; let__wolin_pl_qus_wolin_i<pl.qus.wolin.i>[uword]=#0[ubyte]


    lda #<0
    sta __wolin_pl_qus_wolin_i
    lda #0
    sta __wolin_pl_qus_wolin_i+1

; allocSPF,#2


    clc
    lda __wolin_spf
    sbc #2
    sta __wolin_spf
    bcs :+
    dec __wolin_spf+1
:

; call__wolin_pl_qus_wolin_main[adr]

    jsr __wolin_pl_qus_wolin_main

; ret

    rts

; function__wolin_pl_qus_wolin_allocMem

__wolin_pl_qus_wolin_allocMem:

; letSPF(4)<pl.qus.wolin.allocMem.__returnValue>[uword]=#30000[uword]


    ldy #4
    lda #<30000
    sta (__wolin_spf),y
    iny
    lda #>30000
    sta (__wolin_spf),y

; freeSPF<pl.qus.wolin.allocMem.__fnargs>,#4


    clc
    lda __wolin_spf
    adc #4
    sta __wolin_spf
    bcc :+
    inc __wolin_spf+1
:

; ret

    rts

; function__wolin_pl_qus_wolin_SummingClass

__wolin_pl_qus_wolin_SummingClass:

; allocSPF,#6


    clc
    lda __wolin_spf
    sbc #6
    sta __wolin_spf
    bcs :+
    dec __wolin_spf+1
:

; letSPF(2)<pl.qus.wolin.allocMem.size>[uword]=#3[uword]


    ldy #2
    lda #<3
    sta (__wolin_spf),y
    iny
    lda #>3
    sta (__wolin_spf),y

; letSPF(0)<pl.qus.wolin.allocMem.count>[uword]=#1[uword]


    ldy #0
    lda #<1
    sta (__wolin_spf),y
    iny
    lda #>1
    sta (__wolin_spf),y

; call__wolin_pl_qus_wolin_allocMem[adr]

    jsr __wolin_pl_qus_wolin_allocMem

; letSPF(2)<pl.qus.wolin.SummingClass.__returnValue>[any*]=SPF(0)<pl.qus.wolin.allocMem.__returnValue>[uword]


    ldy #0
    lda (__wolin_spf),y
    ldy #2
    sta (__wolin_spf),y
    ldy #0+1
    lda (__wolin_spf),y
    ldy #2+1
    sta (__wolin_spf),y


; setupHEAP=SPF(0)<pl.qus.wolin.allocMem.__returnValue>[uword]


    ldy #0 ; this pointer from SPF to this pointer on ZP
    lda (__wolin_spf),y
    sta __wolin_this_ptr
    iny
    lda (__wolin_spf),y
    sta __wolin_this_ptr+1

; letHEAP(2)<pl.qus.wolin.SummingClass.x>[ubyte]=#3[ubyte]


    lda #3
    ldy #2
    sta (__wolin_this_ptr),y

; letHEAP(1)<pl.qus.wolin.SummingClass.y>[ubyte]=#7[ubyte]


    lda #7
    ldy #1
    sta (__wolin_this_ptr),y

; freeSPF<pl.qus.wolin.allocMem.__returnValue>,#2


    clc
    lda __wolin_spf
    adc #2
    sta __wolin_spf
    bcc :+
    inc __wolin_spf+1
:

; ret

    rts

; function__wolin_pl_qus_wolin_SummingClass_suma

__wolin_pl_qus_wolin_SummingClass_suma:

; setupHEAP=this


    ldy #0 ; this pointer from SPF to this pointer on ZP
    lda (__wolin_spf),y
    sta __wolin_this_ptr
    iny
    lda (__wolin_spf),y
    sta __wolin_this_ptr+1

; allocSP<__wolin_reg8>,#2


    dex
    dex

; letSP(0)<__wolin_reg8>[ubyte*]=*HEAP(2)<pl.qus.wolin.SummingClass.x>[ubyte]


    clc
    lda __wolin_this_ptr
    adc #2
    sta 0,x
    lda __wolin_this_ptr+1
    adc #0
    sta 0+1,x

; add&SP(0)<__wolin_reg8>[ubyte*]=&SP(0)<__wolin_reg8>[ubyte*],HEAP(1)<pl.qus.wolin.SummingClass.y>[ubyte]


    clc
    lda (0,x)
    ldy #1
    adc (__wolin_this_ptr), y
    sta (0,x)


; letSPF(2)<pl.qus.wolin.SummingClass.suma.__returnValue>[ubyte]=&SP(0)<__wolin_reg8>[ubyte*]


    lda (0,x)
    ldy #2
    sta (__wolin_spf),y


; freeSP<__wolin_reg8>,#2


    inx
    inx

; freeSPF<pl.qus.wolin.SummingClass.suma.__fnargs>,#2


    clc
    lda __wolin_spf
    adc #2
    sta __wolin_spf
    bcc :+
    inc __wolin_spf+1
:

; ret

    rts

; function__wolin_pl_qus_wolin_main

__wolin_pl_qus_wolin_main:

; allocSP<__wolin_reg13>,#2


    dex
    dex

; letSP(0)<__wolin_reg13>[any*]=SPF(0)<pl.qus.wolin.main..testowa>[any*]


    ldy #0
    lda (__wolin_spf),y
    sta 0,x
    iny
    lda (__wolin_spf),y
    sta 0+1,x

; allocSP<__wolin_reg14>,#2


    dex
    dex

; allocSPF,#2


    clc
    lda __wolin_spf
    sbc #2
    sta __wolin_spf
    bcs :+
    dec __wolin_spf+1
:

; call__wolin_pl_qus_wolin_SummingClass[adr]

    jsr __wolin_pl_qus_wolin_SummingClass

; letSP(0)<__wolin_reg14>[any*]=SPF(0)<pl.qus.wolin.SummingClass.__returnValue>[any*]


    ldy #0
    lda (__wolin_spf),y
    sta 0,x
    iny
    lda (__wolin_spf),y
    sta 0+1,x

; let&SP(2)<__wolin_reg13>[any*]=&SP(0)<__wolin_reg14>[any*]


    ; take value that is located at address stored in 0
    lda (0,x)
    ; store it at address stored in 2
    sta (2,x)

    inc 0,x
    bne :+
    inc 0+1,x
:
    lda (0,x)
    sta (2,x)


; freeSP<__wolin_reg14>,#2


    inx
    inx

; freeSP<__wolin_reg13>,#2


    inx
    inx

; allocSP<__wolin_reg16>,#2


    dex
    dex

; letSP(0)<__wolin_reg16>[ubyte*]=53280[ubyte*]


    lda #<53280
    sta 0,x
    lda #>53280
    sta 0+1,x

; allocSPF,#3


    clc
    lda __wolin_spf
    sbc #3
    sta __wolin_spf
    bcs :+
    dec __wolin_spf+1
:

; letSPF(0)[any*]=SPF(2)<pl.qus.wolin.main..testowa>[any*]


    ldy #2
    lda (__wolin_spf),y
    ldy #0
    sta (__wolin_spf),y
    ldy #2
    iny
    lda (__wolin_spf),y
    ldy #0
    iny
    sta (__wolin_spf),y


; call__wolin_pl_qus_wolin_SummingClass_suma[adr]

    jsr __wolin_pl_qus_wolin_SummingClass_suma

; let&SP(0)<__wolin_reg16>[ubyte*]=SPF(0)<pl.qus.wolin.SummingClass.suma.__returnValue>[ubyte]


    ldy #0
    lda (__wolin_spf),y
    sta (0,x)


; freeSP<__wolin_reg16>,#2


    inx
    inx

; freeSPF<pl.qus.wolin.main.__fnargs>,#1


    clc
    lda __wolin_spf
    adc #1
    sta __wolin_spf
    bcc :+
    inc __wolin_spf+1
:

; freeSPF<pl.qus.wolin.SummingClass.__returnValue>,#2


    clc
    lda __wolin_spf
    adc #2
    sta __wolin_spf
    bcc :+
    inc __wolin_spf+1
:

; freeSPF<pl.qus.wolin.SummingClass.suma.__returnValue>,#1


    clc
    lda __wolin_spf
    adc #1
    sta __wolin_spf
    bcc :+
    inc __wolin_spf+1
:

; ret

    rts

; label__wolin_indirect_jsr

__wolin_indirect_jsr:

; goto65535[adr]

    jmp 65535


; alloc0[uword]

    .word 0


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 05, 2020 10:46 am 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
Update.

Since I always hated how I had to set things in BASIC via some POKE X, PEEK(Y) OR A AND B, I really wanted to have neat and simple bit operations via variables attached to bits at specific address, like:

Code:
var sprite0On: bool^0xd015@0


That would be very useful on C64, as it would make handling lot of I/O as simple as:

Code:
sprite0On = true


Unfortunately it would break literally everything I've done so far. So instead I've added bit setting ops.

Code:
var spritesOn: ubyte^0xd015

spritesOn := 0 // show sprite 1 (set bit 0 at d015)
spritesOn .= 128 // hide sprite 7 (clear bit 0 at d015)


Last edited by qus on Sun Jan 05, 2020 3:05 pm, edited 2 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 05, 2020 3:04 pm 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
And here's a question (anyone reading?) for feature described above. While setting bits is straightforward, how do I clear bits on 6502 if there's no NOT opcode? How would I implement in assembly clearing bit 7 and 0 like in code below:

Code:
someVariable .= 128+1


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 05, 2020 3:12 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10986
Location: England
To complement a value you'd generally use EOR #$FF - in the case of clearing bits, you first invert the mask and then use it to AND the variable to be masked. (Is this the question you're asking?)


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 05, 2020 9:30 pm 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
Yep. Exactly that. Thanks.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 06, 2020 10:03 am 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
Would that be right code for setting byte at address pointed by ZP:

Set val bits in &dst:
Code:
bit &SP(?dst)[ubyte*] = #?val[ubyte], #1[bool] -> """
    lda ({dst},x)
    ora #{val}
    sta ({dst},x)
"""


Clear val bits in &dst:
Code:
bit &SP(?dst)[ubyte*] = #?val[ubyte], #0[bool] -> """
    lda #{val}
    xor #$ff
    and ({dst},x)
    sta ({dst},x)
"""


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 06, 2020 12:51 pm 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
Don't need no ouija board to summon some ghosts now:

Code:
package pl.qus.wolin

var screen: ubyte[]^1024

var spritesOn: ubyte^0xd015
var sprite0X: ubyte^0xd000
var sprite0Y: ubyte^0xd001
var spritesFat: ubyte^0xd01d
var spritesTall: ubyte^0xd017
var sprite0Color: ubyte^0xd027

fun main() {
    spritesOn := 1
    spritesFat := 1
    spritesTall := 1
    sprite0X = 100
    sprite0Y = 100
    sprite0Color = 2
}


Compiles to:

Code:
; setupHEADER


;**********************************************
;*
;* BASIC header
;*
;* compile with:
;* cl65.exe -o assembler.prg -t c64 -C c64-asm.cfg -g -Ln labels.txt assembler.s
;*
;**********************************************
            .org 2049
            .export LOADADDR = *
Bas10:      .word BasEnd
            .word 10
            .byte 158 ; sys
            .byte " 2064"
            .byte 0
BasEnd:     .word 0
            .word 0
            ;


; setupSPF=251[ubyte],40959[uword]


; prepare function stack
__wolin_spf := 251 ; function stack ptr
__wolin_spf_hi := 251+1 ; function stack ptr

__wolin_spf_top := 40959 ; function stack top
__wolin_spf_top_hi := 40959+1 ; function stack top
    lda #<__wolin_spf_top ; set function stack top
    sta __wolin_spf
    lda #>__wolin_spf_top
    sta __wolin_spf+1

; setupSP=143[ubyte]


; prepare program stack
__wolin_sp_top := 143 ; program stack top
__wolin_sp_top_hi := 143+1 ; program stack top
    ldx #__wolin_sp_top ; set program stack top

; setupHEAP=176[ubyte]


__wolin_this_ptr := 176
__wolin_this_ptr_hi := 176+1


; allocSPF,#0

 

; call__wolin_pl_qus_wolin_main[adr]

    jsr __wolin_pl_qus_wolin_main

; ret

    rts

; function__wolin_pl_qus_wolin_main

__wolin_pl_qus_wolin_main:

; bit53269[ubyte]=#1[ubyte],#1[bool]


    lda 53269
    ora 1
    sta 53269


; bit53277[ubyte]=#1[ubyte],#1[bool]


    lda 53277
    ora 1
    sta 53277


; let53248[ubyte]=#100[ubyte]


    lda #100
    sta 53248

; let53249[ubyte]=#100[ubyte]


    lda #100
    sta 53249

; let53287[ubyte]=#2[ubyte]


    lda #2
    sta 53287

; ret

    rts

; label__wolin_indirect_jsr

__wolin_indirect_jsr:

; goto65535[adr]

    jmp 65535



Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 06, 2020 11:35 pm 
Offline

Joined: Mon Sep 17, 2018 2:39 am
Posts: 138
Hi!

qus wrote:
Would that be right code for setting byte at address pointed by ZP:

Set val bits in &dst:
Code:
bit &SP(?dst)[ubyte*] = #?val[ubyte], #1[bool] -> """
    lda ({dst},x)
    ora #{val}
    sta ({dst},x)
"""



That looks ok.

Quote:
Clear val bits in &dst:
Code:
bit &SP(?dst)[ubyte*] = #?val[ubyte], #0[bool] -> """
    lda #{val}
    xor #$ff
    and ({dst},x)
    sta ({dst},x)
"""


That does look OK, but it is simpler to do:
Code:
bit &SP(?dst)[ubyte*] = #?val[ubyte], #0[bool] -> """
    lda #$FF-{val}
    and ({dst},x)
    sta ({dst},x)
"""


Also, you can write the first version to be similar to the second:

Code:
bit &SP(?dst)[ubyte*] = #?val[ubyte], #1[bool] -> """
    lda #{val}
    ora ({dst},x)
    sta ({dst},x)
"""


But a warning: it is typical for simple hardware register to have different functions on READ and WRITE, you can't read back the value you just wrote - so the above won't work. For example, on the Atari 8-bit computers you can't read back ANTIC, GTIA or POKEY registers, you must always write the full register values.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 07, 2020 5:17 pm 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
Ha! I'm well aware of that. But is there any solution for such cases besides keeping a separate variable, making bit ops on it and then writing this variable to I/O reg?


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 07, 2020 9:11 pm 
Offline

Joined: Mon May 21, 2018 8:09 pm
Posts: 1462
In these cases, the "shadow register" technique is the standard. Often the ROM will reserve a location for it, if the hardware is standard for the machine.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 07, 2020 9:25 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1488
Location: Scotland
qus wrote:
Ha! I'm well aware of that. But is there any solution for such cases besides keeping a separate variable, making bit ops on it and then writing this variable to I/O reg?


The solution is left as an exercise to the user ;-)

ie. Don't make the language do more than it needs to. If you/me/anyone is writing code in this language and we're poking hardware, then we need to know if the hardware supports read/modify/write (some do, some don't) or not, and if not, then w need to keep a copy, managed by our own code.

My thoughts on this, anyway.

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 09, 2020 6:40 am 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
Update. Finally optimized pointer ops, so:

Code:
alloc SP<__wolin_reg5>, #2
let SP(0)<__wolin_reg5>[ubyte*] = 53269[ubyte]
bit 53269[ubyte] = #1[ubyte], #1[bool]
free SP<__wolin_reg5>, #2
alloc SP<__wolin_reg8>, #2
let SP(0)<__wolin_reg8>[ubyte*] = 53277[ubyte]
bit 53277[ubyte] = #1[ubyte], #1[bool]
free SP<__wolin_reg8>, #2
alloc SP<__wolin_reg11>, #2
let SP(0)<__wolin_reg11>[ubyte*] = 53271[ubyte]
bit 53271[ubyte] = #1[ubyte], #1[bool]
free SP<__wolin_reg11>, #2
alloc SP<__wolin_reg14>, #2
let SP(0)<__wolin_reg14>[ubyte*] = 53248[ubyte]
let 53248[ubyte], #100[ubyte]
free SP<__wolin_reg14>, #2
alloc SP<__wolin_reg17>, #2
let SP(0)<__wolin_reg17>[ubyte*] = 53249[ubyte]
let 53249[ubyte], #100[ubyte]
free SP<__wolin_reg17>, #2
alloc SP<__wolin_reg20>, #2
let SP(0)<__wolin_reg20>[ubyte*] = 53287[ubyte]
let 53287[ubyte], #2[ubyte]
free SP<__wolin_reg20>, #2


becomes:

Code:
bit 53269[ubyte]=#1[ubyte],#1[bool]
bit 53277[ubyte]=#1[ubyte],#1[bool]
bit 53271[ubyte]=#1[ubyte],#1[bool]
let 53248[ubyte]=#100[ubyte]
let 53249[ubyte]=#100[ubyte]
let 53287[ubyte]=#2[ubyte]


And the last todo opt is return values:

Code:
function __wolin_pl_qus_wolin_suma
alloc SP<__wolin_reg1>, #2
let SP(0)<__wolin_reg1>[ubyte*] = *SPF(1)<pl.qus.wolin.suma.a>[ubyte]
add &SP(0)<__wolin_reg1>[ubyte*] = &SP(0)<__wolin_reg1>[ubyte*], SPF(0)<pl.qus.wolin.suma.b>[ubyte]
let SPF(2)<pl.qus.wolin.suma.__returnValue>[ubyte] = &SP(0)<__wolin_reg1>[ubyte*]
free SP<__wolin_reg1>, #2
free SPF<pl.qus.wolin.suma.__fnargs>, #2
ret


to:

Code:
function __wolin_pl_qus_wolin_suma
let SPF(2)<pl.qus.wolin.suma.__returnValue>[ubyte] = *SPF(1)<pl.qus.wolin.suma.a>[ubyte]
add &SPF(2)<pl.qus.wolin.suma.__returnValue>[ubyte] = &SP(0)<__wolin_reg1>[ubyte*], SPF(0)<pl.qus.wolin.suma.b>[ubyte]
free SPF<pl.qus.wolin.suma.__fnargs>, #2
ret


Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 17, 2020 7:50 am 
Offline

Joined: Sat Apr 20, 2019 5:31 pm
Posts: 104
Update.

I forgot to mention that before but there was another reason for creating Wolin. An argument with some guy on C64 forum that you can open the border ONLY from assembler. He was unable to provide a reason for this ridiculous statement, though.

So I thought I will open C64 border form higl level language, and I guess a language with OO and lambdas is pretty high level, right? But still I need to set interrupt vector somehow. So now it is possible. Look at below Wolin code:

Code:
package pl.qus.wolin

var rasterVector: uword^0x0314 // this is C64 raster interrupt vector
var border: ubyte^53280

fun rasterProc() {
    // do something
   border = 5
}


fun main() {
   // do somethig more, set raster line, etc.

    rasterVector = rasterProc
}


Compiles to:

Code:
; setupHEADER


;**********************************************
;*
;* BASIC header
;*
;* compile with:
;* cl65.exe -o assembler.prg -t c64 -C c64-asm.cfg -g -Ln labels.txt assembler.s
;*
;**********************************************
            .org 2049
            .export LOADADDR = *
Bas10:      .word BasEnd
            .word 10
            .byte 158 ; sys
            .byte " 2064"
            .byte 0
BasEnd:     .word 0
            .word 0
            ;


; setupSPF=251[ubyte],40959[uword]


; prepare function stack
__wolin_spf := 251 ; function stack ptr
__wolin_spf_hi := 251+1 ; function stack ptr

__wolin_spf_top := 40959 ; function stack top
__wolin_spf_top_hi := 40959+1 ; function stack top
    lda #<__wolin_spf_top ; set function stack top
    sta __wolin_spf
    lda #>__wolin_spf_top
    sta __wolin_spf+1

; setupSP=143[ubyte]


; prepare program stack
__wolin_sp_top := 143 ; program stack top
__wolin_sp_top_hi := 143+1 ; program stack top
    ldx #__wolin_sp_top ; set program stack top

; setupHEAP=176[ubyte]


__wolin_this_ptr := 176
__wolin_this_ptr_hi := 176+1


; allocSPF,#0

 

; call__wolin_pl_qus_wolin_main[adr]

    jsr __wolin_pl_qus_wolin_main

; ret

    rts

; function__wolin_pl_qus_wolin_rasterProc

__wolin_pl_qus_wolin_rasterProc:

; let53280[ubyte]=#5[ubyte]


    lda #5
    sta 53280

; ret

    rts

; function__wolin_pl_qus_wolin_main

__wolin_pl_qus_wolin_main:

; let788[uword]=__wolin_pl_qus_wolin_rasterProc[uword]


    lda #<__wolin_pl_qus_wolin_rasterProc
    sta 788
    lda #>__wolin_pl_qus_wolin_rasterProc
    sta 788+1


; ret

    rts

; label__wolin_indirect_jsr

__wolin_indirect_jsr:

; goto65535[adr]

    jmp 65535



Top
 Profile  
Reply with quote  
PostPosted: Fri Jan 17, 2020 9:27 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1488
Location: Scotland
qus wrote:
Update.

I forgot to mention that before but there was another reason for creating Wolin. An argument with some guy on C64 forum that you can open the border ONLY from assembler. He was unable to provide a reason for this ridiculous statement, though.


Hehe... Well done! I love this sort of stuff!

But no different, really, from being able to point an interrupt (if that's what it takes, I know nothing about the C64 hardware) to a function in C - it's done daily in just about every CPU that supports C ... So if not C, then anything else that can do the right thing at function entry/exit...

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 171 posts ]  Go to page Previous  1 ... 4, 5, 6, 7, 8, 9, 10 ... 12  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 13 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: