This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

My first assembly program :D

My first assembly program :D
by on (#34383)
I'm proud to show here my first assembly program :D

I tried to find informations about NES PPU in the forums (because well I don't fully understand it) and then I found this simulator in a thread I don't remember. The online simulator can be found here : http://www.6502asm.com

Press '0' to '9' to print digits to the screen.
Press 'f' to change the font color, 'b' to change the background color.
Press 'c' to clear the screen.

In fact, it's only printing small 4x6 bitmaps 1-bit depth color. when pressing 'b' or 'f' it simply inc the color entry for the conresponding bit value in the bitmap, where '0' is for background and '1' is for the font.


Code:
;  $8000= back color
;  $8001= font color
;  $8002= column
;  $8003= row
 
 
lda #$0
sta $8000   ;back=0 (black)

lda #$1
sta $8001   ;font=1 (white)

lda #0
sta $8002   ;column=0
lda #0
sta $8003   ;row=0


main:

    jsr GetKey

is_b:
    cmp #$62    ;key is 'b'?
    bne is_c
        inc $8000    ;inc color back
    jmp main
is_c:
    cmp #$63    ;key is 'c'?
    bne is_f
        jsr ClrScr   ;Clear screen
    jmp main
is_f:
    cmp #$66    ;key is 'f'?
    bne call_Putch
        inc $8001    ;inc color font
    jmp main
call_Putch:
    jsr PutCh
    jmp main
 

 

;-------------------------------------------

GetKey:

    lda #0       ;reset key read
    sta $ff

while_not_kbhit:

    lda $ff      ;read key
    beq while_not_kbhit

                 ;loop if NULL

    rts          ;leave key read in A

;-------------------------------------------

ClrScr:
    lda #2
    sta $11    ;HI address of screen begin
    lda #0
    sta $10    ;LO address
    tay
Next_Pts:
    sta ($10),y
    inc $10    ;increment LO address
    bne Next_Pts
    inc $11    ;increment HI address
    lda $11
    cmp #6     ;if HI address==6
    beq exit_ClrScr  ;exit

               
    tya     ; same as lda #0
    jmp Next_Pts

exit_ClrScr:
    rts
;-------------------------------------------
PutCh:

;  $10  = screen write
;  $12  = chr read index
;  $13  = temp mem for display
;  $14  = down counter for shift reg

    sec
    sbc #$30       ;subtract by '0'

    bmi Error_Exit ; if negative,
                   ; the ASCII value
                   ;is less than '0',
                   ; so it isn't a
                   ;number

    cmp #10
    bmi OK_Continue

                   ;this time, if the
                   ;value in accumula-
                   ;tor is less than
                   ;10, it's a number

Error_Exit:

    jmp exit

OK_Continue:

    sta $12       
    ldy #2   

Multiply_chr:      ;this loop multiplies
                   ;by three the number.
                   ;this is for calcula-
                   ;ting the offset from

        adc $12    ;the first bitmap.
        dey
        bne Multiply_chr
    sta $12
;
; Calculate the memory offset of the first pt
;

    lda $8002       ;load X coord
    jmp while_greater_than_8

 

; while(col>=8)
;{
;    col-=8;
;    row++;
;}
Subtract:
        sec
        sbc #8
        inc $8003   
while_greater_than_8:
        cmp #8
        bpl Subtract

    sta $8002
    asl         ;multiply by four
    asl
    sta $10     ;the 3 LSB of address
                ;are now calculated
    lda #0
    sta $11     ;clear the HI address
                ;this is important because
                ;later a value will be ROL'ed
                ;in.
    lda $8003
    cmp #5      ;if row is greater than 4,
    bmi Continue;row will be set to 0
        lda #0
        sta $8003
Continue:
    clc
    ldy #5
multiply_1:     ;this loop multiplies by 6
                ;the row's value
        adc $8003
        dey
        bne multiply_1
    ldy #5
multiply_2:     ;this loop multiplies by 32 the
                ;previous value calculated in
                ;the accumulator.

                ;since the screen is 32x32,
                ;and the bitmap 6 pts height,
                ;row*6*32 will give the
                ;correct memory offset for
                ;a vertical position.
        asl
        rol $011  ;since rol zeropage is buggy,
                  ;I use absolute mode instead
        dey
        bne multiply_2
    ora $10
    sta $10

    lda $11
    clc
    adc #2      ;add 2 to HI address so it
                ;effectively access screen
    sta $11

;
; Display the bitmap
;   

    ldx $12       ;x holds offset from
                  ;CHR_0
    inc $12       ;and $12 then holds the
                  ;offset of the next
                  ;caracter
    inc $12
    inc $12
    ldy #0

loop_fetch_byte:
    lda #8
    sta $14       ;this memory location
                  ;holds the remaining
                  ;bit to shift
    lda CHR_0,x   ;load a byte of
                  ;bitmap

loop_byte_scan:

    asl
    sta $13       ;save accumulator for
                  ;later use
    bcs FontPoint ; if Carry=1, Font
                  ;else Background
    lda $8000     ;Load background
                  ;color
    jmp Next_Point

FontPoint:
    lda $8001     ;Load Font color

Next_Point:
    sta ($10),y   ;store color to
                  ;pixel
    iny
    cpy #4     
    bne cccontinue
                  ;if y==4
    ldy #0        ;reset y
    lda $10
    clc
    adc #$20      ;and add 32 to
                  ;LO address, thus
                  ;moving down       
    sta $10
    bcc cccontinue
    inc $11       ;if crossing page
                  ;boundary ;)

cccontinue:
    dec $14       ;dec the bit counter
                  ;for shifter
    bne load_0x13
                  ;if the shifter is
                  ;empty             
    inx           ;increment offset
    cpx $12       ;finished?
    beq done      ;yes quit

    jmp loop_fetch_byte

load_0x13:
    lda $13       ;reload value to
                  ;shift   
    jmp loop_byte_scan   

done:
    inc $8002     ;increment column

exit:
    rts   

;-------------------------------------------
 

;characters from '0' to '9', bitmaps 1-bit 4x6

CHR_0:
     dcb $02,$55,$52
CHR_1:
     dcb $02,$62,$27
CHR_2:
     dcb $06,$13,$47
CHR_3:
     dcb $06,$12,$16
CHR_4:
     dcb $05,$57,$11
CHR_5:
     dcb $07,$47,$16
CHR_6:
     dcb $03,$47,$57
CHR_7:
     dcb $07,$12,$44
CHR_8:
     dcb $07,$57,$57
CHR_9:
     dcb $07,$57,$16


Speaking of which, I proved that I know very well 6502 assembly language, but I still don't know assembler directives (like doing macros, naming memory location, etc). Is directives unique to each assemblers?
What are they? Maybe just put some links to read about. Thanks and thank for reading...

by on (#34385)
Quote:
Is directives unique to each assemblers?

Yes they are completely unique to each assemblers, but some have similarities. Typically, .db is used on almost every assembler to define bytes (but some have .dcb or .dsb). You should read each assembler's docuumentation to know more. If you're going to write something complex you should read the doccumentation of every assembler and try them to see which is the one with most features, which is a never-ending debate.