1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-11-29 18:49:22 +00:00
SixtyPical/doc/Emitting.markdown

8.1 KiB

Emitting Ophis from SixtyPical Programs

-> Tests for functionality "Emit ASM for SixtyPical program"

-> Functionality "Emit ASM for SixtyPical program" is implemented by
-> shell command "bin/sixtypical emit %(test-file)"

Emitting an if.

| assign byte screen $0400
| routine main {
|    lda screen
|    cmp screen
|    if beq {
|        tax
|    } else {
|        tay
|    }
|    sta screen
| }
= main:
=   lda screen
=   cmp screen
=   BEQ _label_1
=   tay
=   jmp _past_1
= _label_1:
=   tax
= _past_1:
=   sta screen
=   rts
= 
= .data
= .alias screen 1024

Emitting a repeat.

| assign byte screen 1024
| reserve byte four : $04
| routine main {
|    ldy four
|    repeat bne {
|       inc screen
|       dey
|       cpy four
|    }
|    sty screen
| }
= main:
=   ldy four
=   
= _repeat_1:
=   inc screen
=   dey
=   cpy four
=   BNE _repeat_1
=   sty screen
=   rts
= 
= four: .byte 4
= .data
= .alias screen 1024

Nested ifs.

| routine main {
|   if beq {
|     if bcc {
|       lda #0
|     } else {
|       if bvs {
|         lda #1
|       } else {
|         lda #2
|       }
|     }
|   } else {
|     lda #3
|   }
| }
= main:
=   BEQ _label_3
=   lda #3
=   jmp _past_3
= _label_3:
=   BCC _label_2
=   BVS _label_1
=   lda #2
=   jmp _past_1
= _label_1:
=   lda #1
= _past_1:
=   jmp _past_2
= _label_2:
=   lda #0
= _past_2:
= _past_3:
=   rts

Installing an interrupt handler (at the Kernal level, i.e. with CINV)

| assign byte screen 1024
| assign vector cinv 788
| reserve vector save_cinv
| 
| routine main {
|   with sei {
|     copy cinv save_cinv
|     copy routine our_cinv to cinv
|   }
| }
| 
| routine our_cinv {
|   inc screen
|   jmp (save_cinv)
| }
= main:
=   sei
=   lda cinv
=   sta save_cinv
=   lda cinv+1
=   sta save_cinv+1
=   lda #<our_cinv
=   sta cinv
=   lda #>our_cinv
=   sta cinv+1
=   cli
=   rts
= 
= our_cinv:
=   inc screen
=   jmp (save_cinv)
=   rts
= 
= .data
= .alias screen 1024
= .alias cinv 788
= .space save_cinv 2

Copy command: immediate -> byte

| reserve byte position
| routine main {
|     copy #23 position
| }
= main:
=   lda #23
=   sta position
=   rts
= 
= .data
= .space position 1

Copy command: immediate -> word

| reserve word position 
| routine main {
|     copy #$0400 position
| }
= main:
=   lda #0
=   sta position
=   lda #4
=   sta position+1
=   rts
= 
= .data
= .space position 2

Copy command: byte-sized immediate -> word

Disabled for now.

    | reserve word position
    | routine main {
    |     copy #1 position
    | }
    = main:
    =   lda #1
    =   sta position
    =   lda #0
    =   sta position+1
    =   rts
    = 
    = .data
    = .space position 2

Copy command: word -> word

| reserve word position1
| reserve word position2
| routine main {
|     copy position1 position2
| }
= main:
=   lda position1
=   sta position2
=   lda position1+1
=   sta position2+1
=   rts
= 
= .data
= .space position1 2
= .space position2 2

Copy command: word -> word indexed

| reserve word loc
| reserve word[4] locs
| routine main {
|     ldy #0
|     copy loc locs, y
| }
= main:
=   ldy #0
=   lda loc
=   sta locs_lo, y
=   lda loc+1
=   sta locs_hi, y
=   rts
= 
= .data
= .space loc 2
= .space locs_lo 4
= .space locs_hi 4

Copy command: word INDEXED -> word

| reserve word loc
| reserve word[4] locs
| routine main {
|     ldx #0
|     copy locs, x loc
| }
= main:
=   ldx #0
=   lda locs_lo, x
=   sta loc
=   lda locs_hi, x
=   sta loc+1
=   rts
= 
= .data
= .space loc 2
= .space locs_lo 4
= .space locs_hi 4

Copy command: byte -> indexed word table -> error.

| reserve byte bbb
| reserve word[4] locs
| routine main {
|     ldx #0
|     copy bbb locs, x
| }
? incompatible types 'Byte' and 'Table Word 4'

Copy command: byte -> low byte of indexed word table

| reserve byte bbb
| reserve word[4] locs
| routine main {
|     ldx #0
|     copy bbb <locs, x
| }
= main:
=   ldx #0
=   lda bbb
=   sta locs_lo, x
=   rts
= 
= .data
= .space bbb 1
= .space locs_lo 4
= .space locs_hi 4

Copy command: byte -> high byte of indexed word table

| reserve byte bbb
| reserve word[4] locs
| routine main {
|     ldx #0
|     copy bbb >locs, x
| }
= main:
=   ldx #0
=   lda bbb
=   sta locs_hi, x
=   rts
= 
= .data
= .space bbb 1
= .space locs_lo 4
= .space locs_hi 4

Copy command: low byte of indexed word table -> byte

| reserve byte bbb
| reserve word[4] locs
| routine main {
|     ldx #0
|     copy <locs, x bbb
| }
= main:
=   ldx #0
=   lda locs_lo, x
=   sta bbb
=   rts
= 
= .data
= .space bbb 1
= .space locs_lo 4
= .space locs_hi 4

Copy command: high byte of indexed word table -> byte

| reserve byte bbb
| reserve word[4] locs
| routine main {
|     ldx #0
|     copy >locs, x bbb
| }
= main:
=   ldx #0
=   lda locs_hi, x
=   sta bbb
=   rts
= 
= .data
= .space bbb 1
= .space locs_lo 4
= .space locs_hi 4

main is always emitted first.

| reserve word position 
| routine foo {
|     inx
| }
| routine main {
|     jsr foo
|     jsr foo
| }
= main:
=   jsr foo
=   jsr foo
=   rts
= 
= foo:
=   inx
=   rts
= 
= .data
= .space position 2

Reserving and assigning byte tables.

| reserve byte[16] frequencies
| assign byte[256] screen $0400
| routine main {
|     lda #0
|     ldy #0
|     sta frequencies, y
|     sta screen, y
| }
= main:
=   lda #0
=   ldy #0
=   sta frequencies, y
=   sta screen, y
=   rts
= 
= .data
= .space frequencies 16
= .alias screen 1024

Reserving things with initial values.

| reserve byte lives : 3
| reserve word screen : $0400
| reserve byte[8] frequencies : (0 1 2 4 5 8 9 10)
| reserve byte[13] message : "Hello, world!"
| routine main {
| }
= main:
=   rts
= 
= lives: .byte 3
= screen: .word 1024
= frequencies: .byte 0, 1, 2, 4, 5, 8, 9, 10
= message: .byte 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33

Temporary storage, in the form of block-local declarations. Note that these temporaries are not unioned yet, but they could be.

| routine a {
|     reserve byte foo
|     reserve word bar
|     lda foo
|     sta >bar
| }
| routine b {
|     reserve byte baz
|     reserve word quuz
|     lda baz
|     sta <quuz
| }
| routine main {
|     jsr a
|     jsr b
| }
= main:
=   jsr a
=   jsr b
=   rts
= 
= a:
=   lda _temp_1
=   sta _temp_2+1
=   rts
= 
= b:
=   lda _temp_3
=   sta _temp_4
=   rts
= 
= .data
= .space _temp_3 1
= .space _temp_4 2
= .space _temp_1 1
= .space _temp_2 2

Declaring and calling an external routine.

| external chrout 65490
| routine main {
|     lda #72
|     jsr chrout
|     lda #73
|     jsr chrout
|     lda #13
|     jsr chrout
| }
= main:
=   lda #72
=   jsr chrout
=   lda #73
=   jsr chrout
=   lda #13
=   jsr chrout
=   rts
= 
= .data
= .alias chrout 65490