zoukankan      html  css  js  c++  java
  • FC/NES PPU 示例汇编程序 简易画图

    程序:简易画图
    编写:女孩不哭, 6502汇编, 6502通用汇编器1.2.6
    使用方法:
      上下左右:移动画笔坐标
      选择  :切换命名表#0,#3(因为是水平镜像)
      开始  :清空当前命名表
      BB     :加速移动
      AA     :画图, 像素切换

    源代码:

    ; start:$BFF0
    ; end:  $FFFF
    ; size: $4010
            .start  reset
            .org    $BFF0   ; 文件头
            .db     "NES",$1A,$01,$01,$00,$00
            .dw     $00,$00,$00,$00
            
    JOY_NOW = $00
    JOY_LAST = $01
    BTN_TIME = $04
    NT_NOW = $05            ; Cur NT: 0:$2000,1:$2800
    PPU_ADDR_LOW = $02
    PPU_ADDR_HI = $03

            .org    $C000
    pal_data:               ; 调色板数据
            .db     $0F,$03,$11,$1A
            .db     $0F,$1A,$11,$03
    reset:
            sei
            cld
            ldx     $ff     ; 初始化堆栈SP
            txs
    _main_vb1:              ; PPU预热2次
            lda     $2002
            bpl     _main_vb1
    _main_vb2:
            lda     $2002
            bpl     _main_vb2       
            inx             ; 关nmi, 关屏幕
            stx     $2000
            stx     $2001   
            stx     JOY_NOW ; 内存初始化
            stx     JOY_LAST
            stx     PPU_ADDR_LOW
            stx     PPU_ADDR_HI
            stx     BTN_TIME
            stx     NT_NOW
            jsr     set_pal ; 设置调色板
            jsr     clr_spr ; 清空精灵
            jsr     clr_nt  ; 清空命名表
            lda     #$07    ; 初始化精灵
            sta     $0200+0
            lda     #$01
            sta     $0200+1
            lda     #$00    ; 卷轴归位
            sta     $2005
            sta     $2005
            lda     #$1e    ; 开屏幕
            sta     $2001
            lda     #$80    ; 开nmi中断
            sta     $2000
    main:
            jmp     main    ; reset中断无限循环
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    nmi:
            lda     #$00
            sta     $2001
            jsr     read_joy
            jsr     check_btn
            jsr     move_spr
            jsr     draw_item
            lda     #$02    ; DMA方式更新精灵
            sta     $4014
            lda     #$1e
            sta     $2001
            rti
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    check_btn:
            lda     JOY_NOW
            cmp     #$10
            beq     _cb_st1
            cmp     #$20
            beq     _cb_n1
            rts
    _cb_st1:
            cmp     JOY_LAST
            bne     _cb_st2
            rts
    _cb_st2:
            lda     NT_NOW
            cmp     #$00    ; NT:$2000
            bne     _cb_nt1
            lda     #$20
            jsr     _sub_clr_nt
            rts
    _cb_nt1:
            lda     #$28
            jsr     _sub_clr_nt
            rts
    _cb_n1:
            cmp     JOY_LAST
            bne     _cb_n2
            rts
    _cb_n2:
            lda     NT_NOW
            cmp     #$00
            bne     _cb_nodraw
            ; 没有画
            lda     #$01    ; 已经画了
            sta     NT_NOW
            lda     #$82
            sta     $2000
            rts
    _cb_nodraw:
            ; 已经画
            lda     #$00    ; 没有画
            sta     NT_NOW
            lda     #$80
            sta     $2000
            rts
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    draw_item:
            lda     JOY_NOW
            and     #$80    ; 同时按下了A?
            beq     _di_rts ; 没有按下
            lda     JOY_NOW
            cmp     JOY_LAST
            beq     _di_rts
            lda     #$00    ; 初始化
            sta     PPU_ADDR_LOW
            lda     NT_NOW
            cmp     #$01    ; NT:$2800
            bne     _di_nt1
            lda     #$28
            sta     PPU_ADDR_HI
            jmp     _di_nt2
    _di_nt1:
            lda     #$20    
            sta     PPU_ADDR_HI
    _di_nt2:
            ldy     $0200+0 ; Y坐标
            iny             ; 因为是Y-1
            tya
            lsr             ; A/=8
            lsr
            lsr
            tax             ; 计算乘法, x*$20=>A
            lda     #$00
    _di_loop1:
            clc
            adc     #$20
            bcc     _di_lab1
            inc     PPU_ADDR_HI
    _di_lab1:
            dex
            bne     _di_loop1
            sta     PPU_ADDR_LOW
            lda     $0200+3 ; X坐标
            lsr             ; X/=8
            lsr
            lsr
            clc
            adc     PPU_ADDR_LOW    ; X偏移
            bcc     _di_lab2
            inc     PPU_ADDR_HI
    _di_lab2:
            sta     PPU_ADDR_LOW
            
    _skip:
            lda     PPU_ADDR_HI
            sta     $2006
            lda     PPU_ADDR_LOW
            sta     $2006
            lda     $2007
            lda     $2007
            cmp     #$00    ; 被画了吗?
            beq     _di_draw ; 没有
            lda     PPU_ADDR_HI
            sta     $2006
            lda     PPU_ADDR_LOW
            sta     $2006
            lda     #$00
            sta     $2007
            jmp     _di_rts
    _di_draw:
            lda     PPU_ADDR_HI
            sta     $2006
            lda     PPU_ADDR_LOW
            sta     $2006
            lda     #$01
            sta     $2007
    _di_rts:
            lda     #$00
            sta     $2005
            sta     $2005
            rts
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    move_spr:
            lda     JOY_NOW
            cmp     JOY_LAST
            bne     _ms_n0
            ldx     BTN_TIME
            cpx     #$14
            bne     _ms_n4
    _ms_n0:
            cmp     #$01    ; 右
            bne     _ms_n1
            lda     $0200+3
            clc
            adc     #$08
            sta     $0200+3
            rts
    _ms_n1:
            cmp     #$02    ; 左
            bne     _ms_n2
            lda     $0200+3
            sec
            sbc     #$08
            sta     $0200+3
            rts
    _ms_n2:
            cmp     #$04    ; 下
            bne     _ms_n3
            lda     $0200+0
            clc
            adc     #$08
            cmp     #$e7
            bne     _unk_1
            lda     #$07
    _unk_1:
            sta     $0200+0
            rts
    _ms_n3:
            cmp     #$08    ; 上
            bne     _ms_n4
            lda     $0200+0
            sec
            sbc     #$08
            cmp     #$ff
            bne     _unk_2
            lda     #$df
    _unk_2:
            sta     $0200+0
            rts
    _ms_n4:
            rts
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    read_joy:
            lda     JOY_NOW
            pha
            lda     #$01
            sta     $4016
            lsr
            sta     $4016
            ldx     #$08
            sta     JOY_NOW
            sta     JOY_LAST
    joy_loop:
            lda     $4016
            and     #$01
            sta     JOY_LAST
            lda     JOY_NOW
            asl
            ora     JOY_LAST
            sta     JOY_NOW
            dex
            bne     joy_loop
            pla
            cmp     JOY_NOW ; 和前一次相比较
            bne     _rj_n1  ; 不相等清除计数器
            cmp     #$00
            beq     _rj_rts
            inc     BTN_TIME
            ldy     BTN_TIME
            cpy     #$15    ; 延迟长度
            bne     _rj_rts
            stx     JOY_LAST
    _rj_n1:
            stx     BTN_TIME
    _rj_rts:
            sta     JOY_LAST
            rts
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<       
    set_pal:
            lda     #$3f
            sta     $2006
            lda     #$00
            sta     $2006
            ldx     #$00
    _sp_loop1:
            lda     pal_data,x
            sta     $2007
            inx
            cpx     #$04
            bne     _sp_loop1
            
            lda     #$3f
            sta     $2006
            lda     #$10
            sta     $2006
            ldx     #$00
    _sp_loop2:
            lda     pal_data+4,x
            sta     $2007
            inx
            cpx     #$04
            bne     _sp_loop2
            rts
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    clr_spr:
            lda     #$00
            tax
    _cs_cs: sta     $0200,x
            inx
            bne     _cs_cs
            
            lda     #$ef
    _cs_hide:
            sta     $0200,x
            inx
            inx
            inx
            inx
            bne     _cs_hide
            rts
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    clr_nt:
            lda     #$20
            jsr     _sub_clr_nt
            lda     #$28
    _sub_clr_nt:
            sta     $2006
            lda     #$00
            sta     $2006
            ldy     #$04
            ldx     #$00
    _clr_nt_loop1:
            sta     $2007
            inx
            bne     _clr_nt_loop1
            dey
            bne     _clr_nt_loop1
            lda     #$00
            sta     $2005
            sta     $2005
            rts
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    irq:
            rti
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
            .org    $FFFA
            .dw     nmi,reset,irq

    点阵字模数据:

    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, 
    $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $00, $00, $00, $00, $00, $00, $00, $00
  • 相关阅读:
    【BZOJ5306】染色(HAOI2018)-容斥原理+NTT
    【BZOJ3129】方程(SDOI2013)-容斥原理+扩展Lucas定理
    【BZOJ3876】支线剧情(AHOI&JSOI2014)-有上下界费用流
    【POJ1149】PIGS-最大流+优化建模
    【BZOJ1941】Hide and Seek(SDOI2010)-KD树
    【BZOJ1834】网络扩容(ZJOI2010)-最大流+费用流+拆边
    【BZOJ1927】星际竞速(SCOI2010)-费用流+拆点
    【BZOJ4872】分手是祝愿(六省联考2017)-期望DP
    【BZOJ2879】美食节(NOI2012)-费用流+拆点+动态加边
    JQ简单图片轮播
  • 原文地址:https://www.cnblogs.com/memset/p/2636595.html
Copyright © 2011-2022 走看看