mirror of
https://gitlab.com/octospacc/MultiSpaccSDK
synced 2025-02-15 03:20:55 +01:00
792 lines
9.4 KiB
Plaintext
792 lines
9.4 KiB
Plaintext
;NES hardware-dependent functions by Shiru (shiru@mail.ru)
|
|
;with improvements by VEG
|
|
;Feel free to do anything you want with this code, consider it Public Domain
|
|
|
|
|
|
.export _pal_all,_pal_bg,_pal_spr,_pal_col,_pal_clear
|
|
.export _pal_bright,_pal_spr_bright,_pal_bg_bright
|
|
.export _ppu_off,_ppu_on_all,_ppu_on_bg,_ppu_on_spr,_ppu_mask,_ppu_system
|
|
.export _oam_clear,_oam_size,_oam_hide_rest
|
|
.export _ppu_wait_frame,_ppu_wait_nmi
|
|
.export _scroll
|
|
.export _bank_spr,_bank_bg
|
|
.export _vram_write
|
|
.export _vram_adr,_vram_put,_vram_fill,_vram_inc
|
|
.export _set_vram_update,_flush_vram_update
|
|
.export _delay
|
|
.export _get_ppu_ctrl_var,_set_ppu_ctrl_var
|
|
.export _nesclock
|
|
.export _nmi_set_callback
|
|
|
|
|
|
;NMI handler
|
|
|
|
nmi:
|
|
pha
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
|
|
lda <PPU_MASK_VAR ;if rendering is disabled, do not access the VRAM at all
|
|
and #%00011000
|
|
bne @doUpdate
|
|
jmp @skipAll
|
|
|
|
@doUpdate:
|
|
|
|
lda #>OAM_BUF ;update OAM
|
|
sta PPU_OAM_DMA
|
|
|
|
lda <PAL_UPDATE ;update palette if needed
|
|
bne @updPal
|
|
jmp @updVRAM
|
|
|
|
@updPal:
|
|
|
|
ldx #0
|
|
stx <PAL_UPDATE
|
|
|
|
lda #$3f
|
|
sta PPU_ADDR
|
|
stx PPU_ADDR
|
|
|
|
ldy PAL_BUF ;background color, remember it in X
|
|
lda (PAL_BG_PTR),y
|
|
sta PPU_DATA
|
|
tax
|
|
|
|
.repeat 3,I
|
|
ldy PAL_BUF+1+I
|
|
lda (PAL_BG_PTR),y
|
|
sta PPU_DATA
|
|
.endrepeat
|
|
|
|
.repeat 3,J
|
|
stx PPU_DATA ;background color
|
|
.repeat 3,I
|
|
ldy PAL_BUF+5+(J*4)+I
|
|
lda (PAL_BG_PTR),y
|
|
sta PPU_DATA
|
|
.endrepeat
|
|
.endrepeat
|
|
|
|
.repeat 4,J
|
|
stx PPU_DATA ;background color
|
|
.repeat 3,I
|
|
ldy PAL_BUF+17+(J*4)+I
|
|
lda (PAL_SPR_PTR),y
|
|
sta PPU_DATA
|
|
.endrepeat
|
|
.endrepeat
|
|
|
|
@updVRAM:
|
|
|
|
lda <VRAM_UPDATE
|
|
beq @skipUpd
|
|
lda #0
|
|
sta <VRAM_UPDATE
|
|
|
|
lda <NAME_UPD_ENABLE
|
|
beq @skipUpd
|
|
|
|
jsr _flush_vram_update_nmi
|
|
|
|
@skipUpd:
|
|
|
|
lda #0
|
|
sta PPU_ADDR
|
|
sta PPU_ADDR
|
|
|
|
lda <SCROLL_X
|
|
sta PPU_SCROLL
|
|
lda <SCROLL_Y
|
|
sta PPU_SCROLL
|
|
|
|
lda <PPU_CTRL_VAR
|
|
sta PPU_CTRL
|
|
|
|
@skipAll:
|
|
|
|
lda <PPU_MASK_VAR
|
|
sta PPU_MASK
|
|
|
|
inc <FRAME_CNT1
|
|
inc <FRAME_CNT2
|
|
lda <FRAME_CNT2
|
|
cmp #6
|
|
bne skipNtsc
|
|
lda #0
|
|
sta <FRAME_CNT2
|
|
|
|
skipNtsc:
|
|
|
|
jsr NMICallback
|
|
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
pla
|
|
rti
|
|
|
|
; IRQ: jumps to NMICallback, passing -1 as argument
|
|
irq:
|
|
pha
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
lda #$ff
|
|
jmp skipNtsc
|
|
|
|
;void __fastcall__ nmi_set_callback(void (*callback)());
|
|
|
|
_nmi_set_callback:
|
|
sta NMICallback+1
|
|
stx NMICallback+2
|
|
HandyRTS:
|
|
rts
|
|
|
|
|
|
;void __fastcall__ pal_all(const char *data);
|
|
|
|
_pal_all:
|
|
|
|
sta <PTR
|
|
stx <PTR+1
|
|
ldx #$00
|
|
lda #$20
|
|
|
|
pal_copy:
|
|
|
|
sta <LEN
|
|
|
|
ldy #$00
|
|
|
|
@0:
|
|
|
|
lda (PTR),y
|
|
sta PAL_BUF,x
|
|
inx
|
|
iny
|
|
dec <LEN
|
|
bne @0
|
|
|
|
inc <PAL_UPDATE
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ pal_bg(const char *data);
|
|
|
|
_pal_bg:
|
|
|
|
sta <PTR
|
|
stx <PTR+1
|
|
ldx #$00
|
|
lda #$10
|
|
bne pal_copy ;bra
|
|
|
|
|
|
|
|
;void __fastcall__ pal_spr(const char *data);
|
|
|
|
_pal_spr:
|
|
|
|
sta <PTR
|
|
stx <PTR+1
|
|
ldx #$10
|
|
txa
|
|
bne pal_copy ;bra
|
|
|
|
|
|
|
|
;void __fastcall__ pal_col(unsigned char index,unsigned char color);
|
|
|
|
_pal_col:
|
|
|
|
sta <PTR
|
|
jsr popa
|
|
and #$1f
|
|
tax
|
|
lda <PTR
|
|
sta PAL_BUF,x
|
|
inc <PAL_UPDATE
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ pal_clear(void);
|
|
|
|
_pal_clear:
|
|
|
|
lda #$0f
|
|
ldx #0
|
|
|
|
@1:
|
|
|
|
sta PAL_BUF,x
|
|
inx
|
|
cpx #$20
|
|
bne @1
|
|
stx <PAL_UPDATE
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ pal_spr_bright(unsigned char bright);
|
|
|
|
_pal_spr_bright:
|
|
|
|
tax
|
|
lda palBrightTableL,x
|
|
sta <PAL_SPR_PTR
|
|
lda palBrightTableH,x ;MSB is never zero
|
|
sta <PAL_SPR_PTR+1
|
|
sta <PAL_UPDATE
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ pal_bg_bright(unsigned char bright);
|
|
|
|
_pal_bg_bright:
|
|
|
|
tax
|
|
lda palBrightTableL,x
|
|
sta <PAL_BG_PTR
|
|
lda palBrightTableH,x ;MSB is never zero
|
|
sta <PAL_BG_PTR+1
|
|
sta <PAL_UPDATE
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ pal_bright(unsigned char bright);
|
|
|
|
_pal_bright:
|
|
|
|
jsr _pal_spr_bright
|
|
txa
|
|
jmp _pal_bg_bright
|
|
|
|
|
|
|
|
;void __fastcall__ ppu_off(void);
|
|
|
|
_ppu_off:
|
|
|
|
lda <PPU_MASK_VAR
|
|
and #%11100111
|
|
sta <PPU_MASK_VAR
|
|
jmp _ppu_wait_nmi
|
|
|
|
|
|
|
|
;void __fastcall__ ppu_on_all(void);
|
|
|
|
_ppu_on_all:
|
|
|
|
lda <PPU_MASK_VAR
|
|
ora #%00011000
|
|
|
|
ppu_onoff:
|
|
|
|
sta <PPU_MASK_VAR
|
|
jmp _ppu_wait_nmi
|
|
|
|
|
|
|
|
;void __fastcall__ ppu_on_bg(void);
|
|
|
|
_ppu_on_bg:
|
|
|
|
lda <PPU_MASK_VAR
|
|
ora #%00001000
|
|
bne ppu_onoff ;bra
|
|
|
|
|
|
|
|
;void __fastcall__ ppu_on_spr(void);
|
|
|
|
_ppu_on_spr:
|
|
|
|
lda <PPU_MASK_VAR
|
|
ora #%00010000
|
|
bne ppu_onoff ;bra
|
|
|
|
|
|
|
|
;void __fastcall__ ppu_mask(unsigned char mask);
|
|
|
|
_ppu_mask:
|
|
|
|
sta <PPU_MASK_VAR
|
|
rts
|
|
|
|
|
|
|
|
;unsigned char __fastcall__ ppu_system(void);
|
|
|
|
_ppu_system:
|
|
|
|
lda <NTSC_MODE
|
|
ldx #$00
|
|
rts
|
|
|
|
;unsigned char __fastcall__ get_ppu_ctrl_var(void);
|
|
|
|
_get_ppu_ctrl_var:
|
|
|
|
lda <PPU_CTRL_VAR
|
|
ldx #$00
|
|
rts
|
|
|
|
;void __fastcall__ set_ppu_ctrl_var(unsigned char var);
|
|
|
|
_set_ppu_ctrl_var:
|
|
|
|
sta <PPU_CTRL_VAR
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ oam_clear(void);
|
|
|
|
_oam_clear:
|
|
|
|
ldx #0
|
|
lda #$ff
|
|
@1:
|
|
sta OAM_BUF,x
|
|
inx
|
|
inx
|
|
inx
|
|
inx
|
|
bne @1
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ oam_size(unsigned char size);
|
|
|
|
_oam_size:
|
|
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
and #$20
|
|
sta <TEMP
|
|
lda <PPU_CTRL_VAR
|
|
and #$df
|
|
ora <TEMP
|
|
sta <PPU_CTRL_VAR
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ oam_hide_rest(unsigned char sprid);
|
|
|
|
_oam_hide_rest:
|
|
|
|
tax
|
|
lda #240
|
|
|
|
@1:
|
|
|
|
sta OAM_BUF,x
|
|
inx
|
|
inx
|
|
inx
|
|
inx
|
|
bne @1
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ ppu_wait_frame(void);
|
|
|
|
_ppu_wait_frame:
|
|
|
|
lda #1
|
|
sta <VRAM_UPDATE
|
|
lda <FRAME_CNT1
|
|
|
|
@1:
|
|
|
|
cmp <FRAME_CNT1
|
|
beq @1
|
|
lda <NTSC_MODE
|
|
beq @3
|
|
|
|
@2:
|
|
|
|
lda <FRAME_CNT2
|
|
cmp #5
|
|
beq @2
|
|
|
|
@3:
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ ppu_wait_nmi(void);
|
|
|
|
_ppu_wait_nmi:
|
|
|
|
lda #1
|
|
sta <VRAM_UPDATE
|
|
lda <FRAME_CNT1
|
|
@1:
|
|
|
|
cmp <FRAME_CNT1
|
|
beq @1
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ scroll(unsigned int x,unsigned int y);
|
|
|
|
_scroll:
|
|
|
|
sta <TEMP
|
|
|
|
txa
|
|
bne @1
|
|
lda <TEMP
|
|
cmp #240
|
|
bcs @1
|
|
sta <SCROLL_Y
|
|
lda #0
|
|
sta <TEMP
|
|
beq @2 ;bra
|
|
|
|
@1:
|
|
|
|
sec
|
|
lda <TEMP
|
|
sbc #240
|
|
sta <SCROLL_Y
|
|
lda #2
|
|
sta <TEMP
|
|
|
|
@2:
|
|
|
|
jsr popax
|
|
sta <SCROLL_X
|
|
txa
|
|
and #$01
|
|
ora <TEMP
|
|
sta <TEMP
|
|
lda <PPU_CTRL_VAR
|
|
and #$fc
|
|
ora <TEMP
|
|
sta <PPU_CTRL_VAR
|
|
rts
|
|
|
|
|
|
;void __fastcall__ bank_spr(unsigned char n);
|
|
|
|
_bank_spr:
|
|
|
|
and #$01
|
|
asl a
|
|
asl a
|
|
asl a
|
|
sta <TEMP
|
|
lda <PPU_CTRL_VAR
|
|
and #%11110111
|
|
ora <TEMP
|
|
sta <PPU_CTRL_VAR
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ bank_bg(unsigned char n);
|
|
|
|
_bank_bg:
|
|
|
|
and #$01
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
sta <TEMP
|
|
lda <PPU_CTRL_VAR
|
|
and #%11101111
|
|
ora <TEMP
|
|
sta <PPU_CTRL_VAR
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ vram_write(unsigned char *src,unsigned int size);
|
|
|
|
_vram_write:
|
|
|
|
sta <TEMP
|
|
stx <TEMP+1
|
|
|
|
jsr popax
|
|
sta <TEMP+2
|
|
stx <TEMP+3
|
|
|
|
ldy #0
|
|
|
|
@1:
|
|
|
|
lda (TEMP+2),y
|
|
sta PPU_DATA
|
|
inc <TEMP+2
|
|
bne @2
|
|
inc <TEMP+3
|
|
|
|
@2:
|
|
|
|
lda <TEMP
|
|
bne @3
|
|
dec <TEMP+1
|
|
|
|
@3:
|
|
|
|
dec <TEMP
|
|
lda <TEMP
|
|
ora <TEMP+1
|
|
bne @1
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ set_vram_update(unsigned char *buf);
|
|
|
|
_set_vram_update:
|
|
|
|
sta <NAME_UPD_ADR+0
|
|
stx <NAME_UPD_ADR+1
|
|
ora <NAME_UPD_ADR+1
|
|
sta <NAME_UPD_ENABLE
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ flush_vram_update(unsigned char *buf);
|
|
|
|
_flush_vram_update:
|
|
|
|
sta <NAME_UPD_ADR+0
|
|
stx <NAME_UPD_ADR+1
|
|
|
|
_flush_vram_update_nmi:
|
|
|
|
ldy #0
|
|
|
|
@updName:
|
|
|
|
lda (NAME_UPD_ADR),y
|
|
iny
|
|
cmp #$40 ;is it a non-sequental write?
|
|
bcs @updNotSeq
|
|
sta PPU_ADDR
|
|
lda (NAME_UPD_ADR),y
|
|
iny
|
|
sta PPU_ADDR
|
|
lda (NAME_UPD_ADR),y
|
|
iny
|
|
sta PPU_DATA
|
|
jmp @updName
|
|
|
|
@updNotSeq:
|
|
|
|
tax
|
|
lda <PPU_CTRL_VAR
|
|
cpx #$80 ;is it a horizontal or vertical sequence?
|
|
bcc @updHorzSeq
|
|
cpx #$ff ;is it end of the update?
|
|
beq @updDone
|
|
|
|
@updVertSeq:
|
|
|
|
ora #$04
|
|
bne @updNameSeq ;bra
|
|
|
|
@updHorzSeq:
|
|
|
|
and #$fb
|
|
|
|
@updNameSeq:
|
|
|
|
sta PPU_CTRL
|
|
|
|
txa
|
|
and #$3f
|
|
sta PPU_ADDR
|
|
lda (NAME_UPD_ADR),y
|
|
iny
|
|
sta PPU_ADDR
|
|
lda (NAME_UPD_ADR),y
|
|
iny
|
|
tax
|
|
|
|
@updNameLoop:
|
|
|
|
lda (NAME_UPD_ADR),y
|
|
iny
|
|
sta PPU_DATA
|
|
dex
|
|
bne @updNameLoop
|
|
|
|
lda <PPU_CTRL_VAR
|
|
sta PPU_CTRL
|
|
|
|
jmp @updName
|
|
|
|
@updDone:
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ vram_adr(unsigned int adr);
|
|
|
|
_vram_adr:
|
|
|
|
stx PPU_ADDR
|
|
sta PPU_ADDR
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ vram_put(unsigned char n);
|
|
|
|
_vram_put:
|
|
|
|
sta PPU_DATA
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ vram_fill(unsigned char n,unsigned int len);
|
|
|
|
_vram_fill:
|
|
|
|
sta <LEN
|
|
stx <LEN+1
|
|
jsr popa
|
|
ldx <LEN+1
|
|
beq @2
|
|
ldx #0
|
|
|
|
@1:
|
|
|
|
sta PPU_DATA
|
|
dex
|
|
bne @1
|
|
dec <LEN+1
|
|
bne @1
|
|
|
|
@2:
|
|
|
|
ldx <LEN
|
|
beq @4
|
|
|
|
@3:
|
|
|
|
sta PPU_DATA
|
|
dex
|
|
bne @3
|
|
|
|
@4:
|
|
|
|
rts
|
|
|
|
|
|
|
|
;void __fastcall__ vram_inc(unsigned char n);
|
|
|
|
_vram_inc:
|
|
|
|
ora #0
|
|
beq @1
|
|
lda #$04
|
|
|
|
@1:
|
|
|
|
sta <TEMP
|
|
lda <PPU_CTRL_VAR
|
|
and #$fb
|
|
ora <TEMP
|
|
sta <PPU_CTRL_VAR
|
|
sta PPU_CTRL
|
|
|
|
rts
|
|
|
|
|
|
;unsigned char __fastcall__ nesclock(void);
|
|
|
|
_nesclock:
|
|
lda <FRAME_CNT1
|
|
ldx #$00
|
|
rts
|
|
|
|
;void __fastcall__ delay(unsigned char frames);
|
|
|
|
_delay:
|
|
|
|
tax
|
|
|
|
@1:
|
|
|
|
jsr _ppu_wait_nmi
|
|
dex
|
|
bne @1
|
|
|
|
rts
|
|
|
|
|
|
|
|
palBrightTableL:
|
|
|
|
.byte <palBrightTable0,<palBrightTable1,<palBrightTable2
|
|
.byte <palBrightTable3,<palBrightTable4,<palBrightTable5
|
|
.byte <palBrightTable6,<palBrightTable7,<palBrightTable8
|
|
|
|
palBrightTableH:
|
|
|
|
.byte >palBrightTable0,>palBrightTable1,>palBrightTable2
|
|
.byte >palBrightTable3,>palBrightTable4,>palBrightTable5
|
|
.byte >palBrightTable6,>palBrightTable7,>palBrightTable8
|
|
|
|
palBrightTable0:
|
|
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f ;black
|
|
palBrightTable1:
|
|
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
|
|
palBrightTable2:
|
|
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
|
|
palBrightTable3:
|
|
.byte $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
|
|
palBrightTable4:
|
|
.byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0f,$0f,$0f ;normal colors
|
|
palBrightTable5:
|
|
.byte $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1a,$1b,$1c,$00,$00,$00
|
|
palBrightTable6:
|
|
.byte $10,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$10,$10,$10 ;$10 because $20 is the same as $30
|
|
palBrightTable7:
|
|
.byte $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$20,$20,$20
|
|
palBrightTable8:
|
|
.byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30 ;white
|
|
.byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30
|
|
.byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30
|
|
.byte $30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30
|
|
|