Posted By
Giuseppe on 2010-11-09 16:51:12
| Re: Assembly and interrupts: my first attempt. Help needed!
I post here the source code of my small program, so you guys can have a look at it without downloading the zip above:
; ** File: RASTER.ASM ; ** Version: v0.9 - 08/11/2010 ; ** Author: Giuseppe Mignogna ; ; Code written in Assembly 6502 for the AS65 compiler. ; Load into Plus/4 emulator and run with "SYS 8192". ; This code is for studying purposes and it's not optimized at all!
; -- Macro macroSR ------------------------------ macroSR macro ; Save registers to stack PHA TXA PHA TYA PHA endm ; -----------------------------------------------
; -- Macro macroRR ------------------------------ macroRR macro ; Restore registers from stack PLA TAY PLA TAX PLA endm ; -----------------------------------------------
; -- Initializing ------------------------------- ; Locate code at $2000 org $2000
; Set the first sprite to be processed LDA #$00 STA spriteIndex ; Set the buffer as not ready STA isBufferReady
; Modify the VBLANK vector to point at a custom routine SEI LDA #VBLANKIRQ & 255 STA $0312 LDA #VBLANKIRQ >> 8 STA $0313 CLI ; -----------------------------------------------
; -- Main ---------------------------------------- MAIN ; The MAIN routine is looped endlessley. It fills a screen buffer ; located at $3000 with characters (sprites) moving from right to ; left. Sprites data are defined into a table below. Some data is ; not used at the moment.
; Check if the buffer is ready to be copied into screen memory LDA isBufferReady BNE jumpOver02 ; Buffer is not ready, then clear the screen buffer LDA #$20 LDX #$00 erase01 STA $3000,X STA $3100,X STA $3200,X STA $3300,X DEX BNE erase01 drawSprites ; Calculate spriteindex*8 LDA spriteIndex ASL A ASL A ASL A TAY ; Get screen address from X,Y coords stored into sprites table JSR xy2addr ; Put sprite character into screen buffer ; Address is stored at $d2,$d3 LDX #$00 LDA sprites+4,y ; sprite character STA ($D2,X)
; Manage delay TYA TAX DEC sprites+6,x ; delay counter BNE jumpOver01 ; Restore delay value LDA sprites+5,x ; original delay value STA sprites+6,x ; Decrease X coord (sprite moves left) DEC sprites,x BNE jumpOver01 ; Restore X coord LDA #$27 ; column 39 STA sprites,x
jumpOver01 ; Set spriteindex to next sprite INC spriteIndex LDA spriteIndex CMP maxSprites BNE drawSprites
; Buffer has been filled with sprites and now ; it's ready to be written into screen memory ; by the VBLANK routine. Meanwhile, the MAIN ; program will do nothing, besides checking the ; isBufferReady variable to be zero again. LDA #$00 STA spriteIndex LDA #$01 STA isBufferReady jumpOver02 JMP MAIN ; ------------------------------------------------
; -- VBLANK routine ------------------------------ VBLANKIRQ ; Check if the buffer is ready to be copied into screen memory LDA isBufferReady BEQ jumpOver04 ; Copy the buffer into screen memory LDX #$00 copyBuffer LDA $3000,X STA $0c00,X LDA $3100,X STA $0d00,X LDA $3200,X STA $0e00,X LDA $3300,X STA $0f00,X DEX BNE copyBuffer
; Buffer now is not ready again and must be filled by the MAIN routine LDA #$00 STA isBufferReady jumpOver04 JMP $CE42 ; ------------------------------------------------
; -- Subroutine xy2addr -------------------------- ; Input: register Y = nr. sprite*8 ; (each sprite has 8 bytes of data in the table)
xy2addr macroSR ; save registers
; Calculate the memory address corresponding to the ; X and Y coordinates using a table that stores all the ; 25 addresses of the column zero LDA sprites+1,y ; Y coord from sprite table ASL A ; Y = Y * 2 TAX LDA columnZero,x ; low byte address STA $D2 INX LDA columnZero,x ; high byte address STA $D3 ; Add X coord to address LDA sprites,y ; X coord from sprite table ADC $D2 ; add to low byte STA $D2 BCC jumpOver03 ; if carry is clear, do nothing INC $D3 ; on carry set, increase high byte (next page)
jumpOver03 macroRR ; restore registers RTS ; ------------------------------------------------
; -- Data --------------------------------------- columnZero DW $3000, $3028, $3050, $3078, $30A0, $30C8, $30F0, $3118 DW $3140, $3168, $3190, $31B8, $31E0, $3208, $3230, $3258 DW $3280, $32A8, $32D0, $32F8, $3320, $3348, $3370, $3398 DW $33C0
maxSprites DB $10
sprites ; x y ofs col chr dly dlv sts DB $27,$02,$00,$00,$D1,$14,$14,$00 DB $27,$03,$00,$00,$D0,$03,$03,$00 DB $27,$04,$00,$00,$D0,$04,$04,$00 DB $27,$05,$00,$00,$D1,$07,$07,$00 DB $27,$06,$00,$00,$D0,$01,$01,$00 DB $27,$07,$00,$00,$D0,$02,$02,$00 DB $27,$08,$00,$00,$D1,$06,$06,$00 DB $27,$09,$00,$00,$D1,$01,$01,$00 DB $27,$0A,$00,$00,$D0,$14,$14,$00 DB $27,$0B,$00,$00,$D0,$03,$03,$00 DB $27,$0C,$00,$00,$D1,$04,$04,$00 DB $27,$0D,$00,$00,$D0,$07,$07,$00 DB $27,$0E,$00,$00,$D1,$01,$01,$00 DB $27,$0F,$00,$00,$D1,$02,$02,$00 DB $27,$10,$00,$00,$D0,$06,$06,$00 DB $27,$11,$00,$00,$D1,$01,$01,$00
spriteIndex DB $00
isBufferReady DB $00 ; -----------------------------------------------
|