mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-01-10 02:29:23 +00:00
Move tests to own files in doc.
This commit is contained in:
parent
cfbc840195
commit
d8d3b283bf
480
README.markdown
480
README.markdown
@ -2,9 +2,9 @@ SixtyPical
|
||||
==========
|
||||
|
||||
SixtyPical is a very low-level programming language, similar to 6502 assembly,
|
||||
with block structure and static analysis through abstract interpretation.
|
||||
with static analysis through type-checking and abstract interpretation.
|
||||
|
||||
It is a work in progress, currently at the proof-of-concept stage.
|
||||
It is a **work in progress**, currently at the **proof-of-concept** stage.
|
||||
|
||||
It is expected that a common use case for SixtyPical would be retroprogramming
|
||||
for the Commodore 64 and other 6502-based computers such as the VIC-20.
|
||||
@ -19,8 +19,8 @@ opcodes, but generate slightly different (safer, but intuitively related)
|
||||
sequences of opcodes. Et cetera.
|
||||
|
||||
`sixtypical` is the reference implementation of SixtyPical. It is written in
|
||||
Haskell. It can currently parse and analyze a SixtyPical program, and will
|
||||
eventually be able to compile it to an Ophis assembler listing.
|
||||
Haskell. It can currently parse and check a SixtyPical program, and can
|
||||
emit an Ophis assembler listing for it.
|
||||
|
||||
Concepts
|
||||
--------
|
||||
@ -131,11 +131,13 @@ Note to self, the `pl` opcodes *do* change flags.
|
||||
Instruction Support so far
|
||||
--------------------------
|
||||
|
||||
A `X` indicates unsupported. A `!` indicates will-not-support.
|
||||
A `X` indicates unsupported.
|
||||
|
||||
Funny syntax indicates use of a special form.
|
||||
|
||||
In these, `absolute` must be a `reserve`d or `locate`d address.
|
||||
`immediate` must be a literal decimal or hexadecimal number
|
||||
(or in future, a declared constant.)
|
||||
|
||||
.
|
||||
adc #immediate
|
||||
@ -268,472 +270,4 @@ TODO
|
||||
* give length for tables, must be there for reserved
|
||||
* Character tables ("strings" to everybody else)
|
||||
* Work out the analyses again and document them
|
||||
* lda wordaddress --> is not legal. use lda <wordaddr or lda >wordaddr
|
||||
* Addressing modes; rename instructions to match
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
||||
-> Tests for functionality "Parse SixtyPical program"
|
||||
|
||||
-> Functionality "Parse SixtyPical program" is implemented by
|
||||
-> shell command "bin/sixtypical parse %(test-file)"
|
||||
|
||||
-> Tests for functionality "Check SixtyPical program"
|
||||
|
||||
-> Functionality "Check SixtyPical program" is implemented by
|
||||
-> shell command "bin/sixtypical check %(test-file)"
|
||||
|
||||
`main` must be present.
|
||||
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
= True
|
||||
|
||||
| routine frog {
|
||||
| nop
|
||||
| }
|
||||
? missing 'main' routine
|
||||
|
||||
A comment may appear at the start of a block.
|
||||
|
||||
| routine main {
|
||||
| ; this program does nothing
|
||||
| nop
|
||||
| }
|
||||
= True
|
||||
|
||||
A comment may appear after each command.
|
||||
|
||||
| routine main {
|
||||
| lda #1 ; we assemble the fnord using
|
||||
| ldx #1 ; multiple lorem ipsums which
|
||||
| ldy #1
|
||||
| lda #1 ; we
|
||||
| ldx #1 ; found under the bridge by the old mill yesterday
|
||||
| }
|
||||
= True
|
||||
|
||||
A comment may appear after each declaration.
|
||||
|
||||
| reserve byte lives ; fnord
|
||||
| assign byte gdcol 647 ; fnord
|
||||
| external blastoff 4 ; fnnnnnnnnnnnnnnnnfffffffff
|
||||
|
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
= True
|
||||
|
||||
A program may `reserve` and `assign`.
|
||||
|
||||
| reserve byte lives
|
||||
| assign byte gdcol 647
|
||||
| reserve word score
|
||||
| assign word memstr 641
|
||||
| reserve vector v
|
||||
| assign vector cinv 788
|
||||
| reserve byte table frequencies
|
||||
| assign byte table screen 1024
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
= True
|
||||
|
||||
A program may declare an `external`.
|
||||
|
||||
| external blastoff 49152
|
||||
| routine main {
|
||||
| jsr blastoff
|
||||
| }
|
||||
= True
|
||||
|
||||
All declarations (`reserve`s and `assign`s) must come before any `routines`.
|
||||
|
||||
| routine main {
|
||||
| lda score
|
||||
| }
|
||||
| reserve word score
|
||||
? expecting "routine"
|
||||
|
||||
All locations used in all routines must be declared first.
|
||||
|
||||
| reserve byte score
|
||||
| routine main {
|
||||
| lda score
|
||||
| cmp screen
|
||||
| }
|
||||
? undeclared location
|
||||
|
||||
Even in inner blocks.
|
||||
|
||||
| reserve byte score
|
||||
| assign byte screen 1024
|
||||
| routine main {
|
||||
| lda score
|
||||
| cmp screen
|
||||
| if beq {
|
||||
| lda score
|
||||
| } else {
|
||||
| lda fnord
|
||||
| }
|
||||
| }
|
||||
? undeclared location
|
||||
|
||||
All routines jsr'ed to must be defined, or external.
|
||||
|
||||
| routine main {
|
||||
| jsr blastoff
|
||||
| }
|
||||
? undeclared routine
|
||||
|
||||
No duplicate location names in declarations.
|
||||
|
||||
| reserve word score
|
||||
| assign word score 4000
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
? duplicate location name
|
||||
|
||||
No duplicate routine names.
|
||||
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
| routine main {
|
||||
| txa
|
||||
| }
|
||||
? duplicate routine name
|
||||
|
||||
No duplicate routine names, including externals.
|
||||
|
||||
| external main 7000
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
? duplicate routine name
|
||||
|
||||
We can jump to a vector.
|
||||
|
||||
| reserve vector blah
|
||||
| routine main {
|
||||
| jmp blah
|
||||
| }
|
||||
= True
|
||||
|
||||
We can't jump to a word.
|
||||
|
||||
| reserve word blah
|
||||
| routine main {
|
||||
| jmp blah
|
||||
| }
|
||||
? jmp to non-vector
|
||||
|
||||
We can't jump to a byte.
|
||||
|
||||
| assign byte screen 1024
|
||||
| routine main {
|
||||
| jmp screen
|
||||
| }
|
||||
? jmp to non-vector
|
||||
|
||||
We can absolute-indexed a byte table.
|
||||
|
||||
| assign byte table screen 1024
|
||||
| routine main {
|
||||
| sta screen, x
|
||||
| }
|
||||
= True
|
||||
|
||||
We cannot absolute-indexed a byte.
|
||||
|
||||
| assign byte screen 1024
|
||||
| routine main {
|
||||
| sta screen, x
|
||||
| }
|
||||
? indexed access of non-table
|
||||
|
||||
We cannot absolute-indexed a word.
|
||||
|
||||
| assign word screen 1024
|
||||
| routine main {
|
||||
| sta screen, x
|
||||
| }
|
||||
? indexed access of non-table
|
||||
|
||||
We cannot absolute access a word.
|
||||
|
||||
| assign word screen 1024
|
||||
| routine main {
|
||||
| ldx screen
|
||||
| }
|
||||
? incompatible types 'Word' and 'Byte'
|
||||
|
||||
No, not even with `ora`.
|
||||
|
||||
| assign word screen 1024
|
||||
| routine main {
|
||||
| ora screen
|
||||
| }
|
||||
? incompatible types 'Byte' and 'Word'
|
||||
|
||||
Instead, we have to do this.
|
||||
|
||||
| assign word screen 1024
|
||||
| routine main {
|
||||
| lda <screen
|
||||
| lda >screen
|
||||
| }
|
||||
= True
|
||||
|
||||
We cannot absolute access a vector.
|
||||
|
||||
| assign vector screen 1024
|
||||
| routine main {
|
||||
| lda screen
|
||||
| }
|
||||
? incompatible types 'Vector' and 'Byte'
|
||||
|
||||
-> Tests for functionality "Emit ASM for SixtyPical program"
|
||||
|
||||
-> Functionality "Emit ASM for SixtyPical program" is implemented by
|
||||
-> shell command "bin/sixtypical emit %(test-file)"
|
||||
|
||||
| reserve word vword
|
||||
| reserve byte vbyte
|
||||
| assign byte table table 1024
|
||||
| routine main {
|
||||
| lda #4
|
||||
| ldx #0
|
||||
| ldy #$FF
|
||||
| lda vbyte
|
||||
| lda table, x
|
||||
| lda table, y
|
||||
| lda (vword), y
|
||||
| lda <vword
|
||||
| lda >vword
|
||||
| inc vbyte
|
||||
| tax
|
||||
| inx
|
||||
| dex
|
||||
| stx vbyte
|
||||
| tay
|
||||
| iny
|
||||
| dey
|
||||
| sty vbyte
|
||||
| cmp vbyte
|
||||
| cmp #30
|
||||
| cmp <vword
|
||||
| cmp >vword
|
||||
| ldx vbyte
|
||||
| cpx vbyte
|
||||
| cpx #31
|
||||
| txa
|
||||
| ldy vbyte
|
||||
| cpy vbyte
|
||||
| cpy #32
|
||||
| tya
|
||||
| sta vbyte
|
||||
| sta table, x
|
||||
| sta table, y
|
||||
| sta (vword), y
|
||||
| sta <vword
|
||||
| sta >vword
|
||||
| dec vbyte
|
||||
| clc
|
||||
| cld
|
||||
| clv
|
||||
| sec
|
||||
| sed
|
||||
| adc #8
|
||||
| adc vbyte
|
||||
| and #8
|
||||
| and vbyte
|
||||
| sbc #8
|
||||
| sbc vbyte
|
||||
| ora #8
|
||||
| ora vbyte
|
||||
| }
|
||||
= main:
|
||||
= lda #4
|
||||
= ldx #0
|
||||
= ldy #255
|
||||
= lda vbyte
|
||||
= lda table, x
|
||||
= lda table, y
|
||||
= lda (vword), y
|
||||
= lda vword
|
||||
= lda vword+1
|
||||
= inc vbyte
|
||||
= tax
|
||||
= inx
|
||||
= dex
|
||||
= stx vbyte
|
||||
= tay
|
||||
= iny
|
||||
= dey
|
||||
= sty vbyte
|
||||
= cmp vbyte
|
||||
= cmp #30
|
||||
= cmp vword
|
||||
= cmp vword+1
|
||||
= ldx vbyte
|
||||
= cpx vbyte
|
||||
= cpx #31
|
||||
= txa
|
||||
= ldy vbyte
|
||||
= cpy vbyte
|
||||
= cpy #32
|
||||
= tya
|
||||
= sta vbyte
|
||||
= sta table, x
|
||||
= sta table, y
|
||||
= sta (vword), y
|
||||
= sta vword
|
||||
= sta vword+1
|
||||
= dec vbyte
|
||||
= clc
|
||||
= cld
|
||||
= clv
|
||||
= sec
|
||||
= sed
|
||||
= adc #8
|
||||
= adc vbyte
|
||||
= and #8
|
||||
= and vbyte
|
||||
= sbc #8
|
||||
= sbc vbyte
|
||||
= ora #8
|
||||
= ora vbyte
|
||||
= rts
|
||||
=
|
||||
= vword: .word 0
|
||||
= vbyte: .byte 0
|
||||
= .alias table 1024
|
||||
|
||||
| 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
|
||||
=
|
||||
= .alias screen 1024
|
||||
|
||||
| assign byte screen 1024
|
||||
| reserve byte zero
|
||||
| routine main {
|
||||
| ldy zero
|
||||
| repeat bne {
|
||||
| inc screen
|
||||
| dey
|
||||
| cpy zero
|
||||
| }
|
||||
| sty screen
|
||||
| }
|
||||
= main:
|
||||
= ldy zero
|
||||
=
|
||||
= _repeat_1:
|
||||
= inc screen
|
||||
= dey
|
||||
= cpy zero
|
||||
= BNE _repeat_1
|
||||
= sty screen
|
||||
= rts
|
||||
=
|
||||
= .alias screen 1024
|
||||
= zero: .byte 0
|
||||
|
||||
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 {
|
||||
| sei {
|
||||
| copy vector cinv to 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
|
||||
=
|
||||
= .alias screen 1024
|
||||
= .alias cinv 788
|
||||
= save_cinv: .word 0
|
||||
|
224
doc/Checking.markdown
Normal file
224
doc/Checking.markdown
Normal file
@ -0,0 +1,224 @@
|
||||
Checking SixtyPical Programs
|
||||
============================
|
||||
|
||||
-> Tests for functionality "Parse SixtyPical program"
|
||||
|
||||
-> Functionality "Parse SixtyPical program" is implemented by
|
||||
-> shell command "bin/sixtypical parse %(test-file)"
|
||||
|
||||
-> Tests for functionality "Check SixtyPical program"
|
||||
|
||||
-> Functionality "Check SixtyPical program" is implemented by
|
||||
-> shell command "bin/sixtypical check %(test-file)"
|
||||
|
||||
`main` must be present.
|
||||
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
= True
|
||||
|
||||
| routine frog {
|
||||
| nop
|
||||
| }
|
||||
? missing 'main' routine
|
||||
|
||||
A comment may appear at the start of a block.
|
||||
|
||||
| routine main {
|
||||
| ; this program does nothing
|
||||
| nop
|
||||
| }
|
||||
= True
|
||||
|
||||
A comment may appear after each command.
|
||||
|
||||
| routine main {
|
||||
| lda #1 ; we assemble the fnord using
|
||||
| ldx #1 ; multiple lorem ipsums which
|
||||
| ldy #1
|
||||
| lda #1 ; we
|
||||
| ldx #1 ; found under the bridge by the old mill yesterday
|
||||
| }
|
||||
= True
|
||||
|
||||
A comment may appear after each declaration.
|
||||
|
||||
| reserve byte lives ; fnord
|
||||
| assign byte gdcol 647 ; fnord
|
||||
| external blastoff 4 ; fnnnnnnnnnnnnnnnnfffffffff
|
||||
|
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
= True
|
||||
|
||||
A program may `reserve` and `assign`.
|
||||
|
||||
| reserve byte lives
|
||||
| assign byte gdcol 647
|
||||
| reserve word score
|
||||
| assign word memstr 641
|
||||
| reserve vector v
|
||||
| assign vector cinv 788
|
||||
| reserve byte table frequencies
|
||||
| assign byte table screen 1024
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
= True
|
||||
|
||||
A program may declare an `external`.
|
||||
|
||||
| external blastoff 49152
|
||||
| routine main {
|
||||
| jsr blastoff
|
||||
| }
|
||||
= True
|
||||
|
||||
All declarations (`reserve`s and `assign`s) must come before any `routines`.
|
||||
|
||||
| routine main {
|
||||
| lda score
|
||||
| }
|
||||
| reserve word score
|
||||
? expecting "routine"
|
||||
|
||||
All locations used in all routines must be declared first.
|
||||
|
||||
| reserve byte score
|
||||
| routine main {
|
||||
| lda score
|
||||
| cmp screen
|
||||
| }
|
||||
? undeclared location
|
||||
|
||||
Even in inner blocks.
|
||||
|
||||
| reserve byte score
|
||||
| assign byte screen 1024
|
||||
| routine main {
|
||||
| lda score
|
||||
| cmp screen
|
||||
| if beq {
|
||||
| lda score
|
||||
| } else {
|
||||
| lda fnord
|
||||
| }
|
||||
| }
|
||||
? undeclared location
|
||||
|
||||
All routines jsr'ed to must be defined, or external.
|
||||
|
||||
| routine main {
|
||||
| jsr blastoff
|
||||
| }
|
||||
? undeclared routine
|
||||
|
||||
No duplicate location names in declarations.
|
||||
|
||||
| reserve word score
|
||||
| assign word score 4000
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
? duplicate location name
|
||||
|
||||
No duplicate routine names.
|
||||
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
| routine main {
|
||||
| txa
|
||||
| }
|
||||
? duplicate routine name
|
||||
|
||||
No duplicate routine names, including externals.
|
||||
|
||||
| external main 7000
|
||||
| routine main {
|
||||
| nop
|
||||
| }
|
||||
? duplicate routine name
|
||||
|
||||
We can jump to a vector.
|
||||
|
||||
| reserve vector blah
|
||||
| routine main {
|
||||
| jmp blah
|
||||
| }
|
||||
= True
|
||||
|
||||
We can't jump to a word.
|
||||
|
||||
| reserve word blah
|
||||
| routine main {
|
||||
| jmp blah
|
||||
| }
|
||||
? jmp to non-vector
|
||||
|
||||
We can't jump to a byte.
|
||||
|
||||
| assign byte screen 1024
|
||||
| routine main {
|
||||
| jmp screen
|
||||
| }
|
||||
? jmp to non-vector
|
||||
|
||||
We can absolute-indexed a byte table.
|
||||
|
||||
| assign byte table screen 1024
|
||||
| routine main {
|
||||
| sta screen, x
|
||||
| }
|
||||
= True
|
||||
|
||||
We cannot absolute-indexed a byte.
|
||||
|
||||
| assign byte screen 1024
|
||||
| routine main {
|
||||
| sta screen, x
|
||||
| }
|
||||
? indexed access of non-table
|
||||
|
||||
We cannot absolute-indexed a word.
|
||||
|
||||
| assign word screen 1024
|
||||
| routine main {
|
||||
| sta screen, x
|
||||
| }
|
||||
? indexed access of non-table
|
||||
|
||||
We cannot absolute access a word.
|
||||
|
||||
| assign word screen 1024
|
||||
| routine main {
|
||||
| ldx screen
|
||||
| }
|
||||
? incompatible types 'Word' and 'Byte'
|
||||
|
||||
No, not even with `ora`.
|
||||
|
||||
| assign word screen 1024
|
||||
| routine main {
|
||||
| ora screen
|
||||
| }
|
||||
? incompatible types 'Byte' and 'Word'
|
||||
|
||||
Instead, we have to do this.
|
||||
|
||||
| assign word screen 1024
|
||||
| routine main {
|
||||
| lda <screen
|
||||
| lda >screen
|
||||
| }
|
||||
= True
|
||||
|
||||
We cannot absolute access a vector.
|
||||
|
||||
| assign vector screen 1024
|
||||
| routine main {
|
||||
| lda screen
|
||||
| }
|
||||
? incompatible types 'Vector' and 'Byte'
|
244
doc/Emitting.markdown
Normal file
244
doc/Emitting.markdown
Normal file
@ -0,0 +1,244 @@
|
||||
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)"
|
||||
|
||||
| reserve word vword
|
||||
| reserve byte vbyte
|
||||
| assign byte table table 1024
|
||||
| routine main {
|
||||
| lda #4
|
||||
| ldx #0
|
||||
| ldy #$FF
|
||||
| lda vbyte
|
||||
| lda table, x
|
||||
| lda table, y
|
||||
| lda (vword), y
|
||||
| lda <vword
|
||||
| lda >vword
|
||||
| inc vbyte
|
||||
| tax
|
||||
| inx
|
||||
| dex
|
||||
| stx vbyte
|
||||
| tay
|
||||
| iny
|
||||
| dey
|
||||
| sty vbyte
|
||||
| cmp vbyte
|
||||
| cmp #30
|
||||
| cmp <vword
|
||||
| cmp >vword
|
||||
| ldx vbyte
|
||||
| cpx vbyte
|
||||
| cpx #31
|
||||
| txa
|
||||
| ldy vbyte
|
||||
| cpy vbyte
|
||||
| cpy #32
|
||||
| tya
|
||||
| sta vbyte
|
||||
| sta table, x
|
||||
| sta table, y
|
||||
| sta (vword), y
|
||||
| sta <vword
|
||||
| sta >vword
|
||||
| dec vbyte
|
||||
| clc
|
||||
| cld
|
||||
| clv
|
||||
| sec
|
||||
| sed
|
||||
| adc #8
|
||||
| adc vbyte
|
||||
| and #8
|
||||
| and vbyte
|
||||
| sbc #8
|
||||
| sbc vbyte
|
||||
| ora #8
|
||||
| ora vbyte
|
||||
| }
|
||||
= main:
|
||||
= lda #4
|
||||
= ldx #0
|
||||
= ldy #255
|
||||
= lda vbyte
|
||||
= lda table, x
|
||||
= lda table, y
|
||||
= lda (vword), y
|
||||
= lda vword
|
||||
= lda vword+1
|
||||
= inc vbyte
|
||||
= tax
|
||||
= inx
|
||||
= dex
|
||||
= stx vbyte
|
||||
= tay
|
||||
= iny
|
||||
= dey
|
||||
= sty vbyte
|
||||
= cmp vbyte
|
||||
= cmp #30
|
||||
= cmp vword
|
||||
= cmp vword+1
|
||||
= ldx vbyte
|
||||
= cpx vbyte
|
||||
= cpx #31
|
||||
= txa
|
||||
= ldy vbyte
|
||||
= cpy vbyte
|
||||
= cpy #32
|
||||
= tya
|
||||
= sta vbyte
|
||||
= sta table, x
|
||||
= sta table, y
|
||||
= sta (vword), y
|
||||
= sta vword
|
||||
= sta vword+1
|
||||
= dec vbyte
|
||||
= clc
|
||||
= cld
|
||||
= clv
|
||||
= sec
|
||||
= sed
|
||||
= adc #8
|
||||
= adc vbyte
|
||||
= and #8
|
||||
= and vbyte
|
||||
= sbc #8
|
||||
= sbc vbyte
|
||||
= ora #8
|
||||
= ora vbyte
|
||||
= rts
|
||||
=
|
||||
= vword: .word 0
|
||||
= vbyte: .byte 0
|
||||
= .alias table 1024
|
||||
|
||||
| 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
|
||||
=
|
||||
= .alias screen 1024
|
||||
|
||||
| assign byte screen 1024
|
||||
| reserve byte zero
|
||||
| routine main {
|
||||
| ldy zero
|
||||
| repeat bne {
|
||||
| inc screen
|
||||
| dey
|
||||
| cpy zero
|
||||
| }
|
||||
| sty screen
|
||||
| }
|
||||
= main:
|
||||
= ldy zero
|
||||
=
|
||||
= _repeat_1:
|
||||
= inc screen
|
||||
= dey
|
||||
= cpy zero
|
||||
= BNE _repeat_1
|
||||
= sty screen
|
||||
= rts
|
||||
=
|
||||
= .alias screen 1024
|
||||
= zero: .byte 0
|
||||
|
||||
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 {
|
||||
| sei {
|
||||
| copy vector cinv to 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
|
||||
=
|
||||
= .alias screen 1024
|
||||
= .alias cinv 788
|
||||
= save_cinv: .word 0
|
@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
./build.sh || exit 1
|
||||
bin/sixtypical emit $1 > tmp.oph || exit 1
|
||||
cat lib/basic_header.oph tmp.oph > tmp2.oph || exit 1
|
||||
ophis tmp2.oph -o tmp.prg || exit 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user