qasm/testdata/1003-flags-and-branches.S

261 lines
5.5 KiB
ArmAsm

; Copyright 2018 faddenSoft. All Rights Reserved.
; See the LICENSE.txt file for distribution terms (Apache 2.0).
;
; Assembler: Merlin 32
xc off
xc
xc
org $1000
clc
xce
sep #$ff ;set all flags
mx %11
; clear individual flags with instructions
; (this has no effect on the assembled output, but you can see the
; effects on the "status" column in the display list)
clv
cld
cli
clc
lda #$80 ;clear Z
lda #$01 ;clear N
sed
sei
sec
lda #$ff ;set N
adc #$00 ;set V, Z (actually scrambles NVZC)
; clear individual flags with REP
sep #$ff
rep #$80
rep #$40
rep #$20
rep #$10
rep #$08
rep #$04
rep #$02
rep #$01
; exercise SEP/REP with #$00
sep #$00
sep #$ff
rep #$00
rep #$ff
; confirm emulation behavior
mx %00 ;long regs
lda #$feed ;check it
sec
xce ;emulation mode
lda #$ff ;check it
rep #$30 ;should have no effect...
mx %11 ;...but Merlin32 doesn't know that
lda #$ff
clc
xce ;back to native, should set M/X=1
lda #$ff ;check it
; try one long, one short
rep #$20 ;long a
sep #$10 ;short x/y
mx %01
lda #$0000
ldx #$01
ldy #$02
sep #$20 ;short a
rep #$10 ;long x/y
mx %10
lda #$01
ldx #$0000
ldy #$0000
; check branch instructions; NVMXDIZC
sep #$30
mx %11
lda #$00
pha
plp ;without a nearby PHP, flags will be scrambled
rep #$80
bpl ok_bpl
brk $00
ok_bpl sep #$80
bpl :bad ;branch never taken
bmi ok_bmi
:bad brk $00
ok_bmi rep #$40
bvc ok_bvc
brk $00
ok_bvc sep #$40
bvs ok_bvs
brk $00
ok_bvs rep #$01
bcc ok_bcc
brk $00
ok_bcc sep #$01
bcs ok_bcs
brk $00
ok_bcs rep #$02
bne ok_bne
brk $00
ok_bne sep #$02
beq ok_beq
brk $00
ok_beq
; check NZ flags set by immediate load
sep #$ff ;set all
mx %11
lda #$01
bne ok_nzero
brk $db
ok_nzero
lda #$00
beq ok_zero
brk $db
ok_zero
bpl ok_pos
brk $db
ok_pos
lda #$80
bmi ok_neg
brk $db
ok_neg
; check NZ flags set by immediate AND
lda #$ff
and #$00
beq ok_andZ1
brk $db
ok_andZ1
lda #$00
and #$ff
beq ok_andZ1A
brk $db
ok_andZ1A
lda #$ff
and #$7f
bne ok_andZ0
brk $db
ok_andZ0
bpl ok_andN0
brk $db
ok_andN0
lda #$ff
and #$80
bmi ok_andN1
brk $db
ok_andN1
; check NZ flags set by immediate ORA
lda #$00
ora #$00
beq ok_oraZ1
brk $db
ok_oraZ1
ora #$01
bne ok_oraZ0
brk $db
ok_oraZ0
lda #$00
ora #$7f
bpl ok_oraN0
brk $db
ok_oraN0
ora #$80
bmi ok_oraN1
brk $db
ok_oraN1
; check rol/ror
:foo lda :foo ;scramble N/V
sec
ror A ;rotates the carry into the hi bit (N)
bmi ok_ror1
brk $dc
ok_ror1
clc
ror A ;now try with carry clear
bpl ok_ror2
brk $dc
ok_ror2
lda #$00 ;set Z=1
sec
rol A ;set Z=0 (could also set C=0)
bne ok_rol1
brk $dc
ok_rol1
; simple php/plp pair test
clc
php
sec
plp ;should restore cleared carry
bcc ok_plp
brk $00
ok_plp
; regression test for bug in analyzer
sec ;here carry is clear
bcs flg2
flg1 clc
flg2 lda $33
beq flg1
bcs flg3 ;this should NOT be branch-always
lda $44
flg3 nop
; test tracking across subroutine calls
rep #$20 ;long a
sep #$10 ;short x/y
mx %01
jsr long_subr ;confirm flag propagation
rep #$30
mx %00
jsr ambig_subr
sep #$30
mx %11
jsr ambig_subr
rep #$20 ;long a
sep #$10 ;short x/y
mx %01
jsr long_subr ;call it again
; leave the main routine with short flags set
sep #$30
mx %11
rts
; only called with longm/shortx
mx %01
long_subr
lda #$1234
ldx #$ff
rts
; this is called with different values for M/X, so it defaults to short
mx %11
ambig_subr
lda #$ff
ldx #$ee
ldy #$dd
rts