I'm using nesasm and i can successfully compile a rom but i get squat when i run it on NesterJ
what is the problem?
Code:
; INES header setup
.inesprg 1 ; One 16k prg bank
.ineschr 1 ; One 8k chr bank
.inesmir 1 ; Vertical map mirroring
.inesmap 0 ; Use mapper 0
;Colour bars program by Mark Knibbs
.bank 0
.org $C000 ;16Kb PRG-ROM, 8Kb CHR-ROM
.db "Colour bars display program v1.1 14-Nov-97 © 1997 by Mark Knibbs <mark_k@iname.com>"
Reset_Routine:
cld ;Clear decimal flag
sei ;Disable interrupts
.WaitV:
lda $2002
bpl .WaitV ;Wait for vertical blanking interval
ldx #$00
stx $2000
stx $2001 ;Screen display off, amongst other things
dex
txs ;Top of stack at $1FF
;Clear the NES' WRAM. This routine is ripped from "Duck Hunt" - I should probably clear all $800 bytes.
ldy #$06 ;To clear 7 x $100 bytes, from $000 to $6FF?
sty <$01 ;Store count value in $01
ldy #$00
sty <$00
lda #$00
.Clear:
sta [$00],y ;Clear $100 bytes
dey
bne .Clear
dec <$01 ;Decrement "banks" left counter
bpl .Clear ;Do next if >= 0
;Now we need to set up the palette and colour bar data.
jsr SetTables ;Set up name and attribute table data
ldy #$00 ;Initial palette "position"
;Next instruction unnecessary since memory has just been cleared
; sty <$02 ;Store palette position
jsr SetPalette ;Set initial palette data
;Enable vblank interrupts, etc.
lda #$80
sta $2000
lda #$0B ;Screen on, sprites off, show leftmost 8 pixels, colour
sta $2001
; cli ;Enable interrupts(?)
;Now just loop forever?
.Loop:
jmp .Loop
;We only need 4 distinct characters, like this:
;
;For low 2 bits of colour number = %00. Character byte number = 0.
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
;
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
;
;For low 2 bits = %01. Character byte number = 1.
;
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
;
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
;
;For low 2 bits = %10. Character byte number = 2.
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
;
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
;
;For low 2 bits = %11. Character byte number = 3.
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
;
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
;
;----------
;
;The display is 256 pixels across. This is 8 columns of 32 pixels, or 16 columns of 16 pixels.
;I'll start off by using 8 columns of 32 pixels.
;
;NOTE: Need to carefully choose which colours to use for the bars. This is because of the "palette
;mirroring" effect (i.e., $3F00 mirrored to $3F04, $3F08 & $3F0C)
;Suitable palette entries to use would be:
; 1 2 3 5 6 7 9 10
;Initially these contain these colour numbers (see palette-setting routine below):
; 0 1 2 3 4 5 6 7
;We'll initially have colour #0 on the left, and colour #7 on the right. So the bytes of the name
;table (at $2000 in PPU space) need to be like this:
;
;Entry1 Entry2 Entry3 Entry5 Entry6 Entry7 Entry9 Entry10
;
;1 1 1 1 2 2 2 2 3 3 3 3 1 1 1 1 2 2 2 2 3 3 3 3 1 1 1 1 2 2 2 2
;
;Fill all 30 rows with this pattern.
;
;
;Now for the attribute table layout. The attr table is 64 bytes long, at $23C0 in PPU space.
;So all 8 rows of the attribute table will be filled with these bytes:
;
; %00000000 %00000000 %00000000 %01010101 %01010101 %01010101 %10101010 %10101010
;In decimal:
; 0 0 0 85 85 85 170 170
;Set the name ($2000) & attribute tables ($23C0)
;-----------------------------------------------
SetTables:
;Set the PPU memory address
ldx #$20 ;High byte of $2000
stx $2006
ldx #$00 ;Low byte of $2000
stx $2006
ldy #30 ;30 rows to do
.Row:
jsr Set3columns ;Do the first 3 columns
jsr Set3columns ;Do the next 3 columns
;Now we do the last two bars (last 8 bytes in the row); these are set to 1 1 1 1 2 2 2 2.
ldx #$01
jsr Set2Columns
dey
bne .Row
;We've set all name table bytes. Now for the attribute table. PPU memory address is already in
;the right place when we get here.
ldy #8 ;8 attribute rows to do
.AttrRow:
ldx #%00000000
jsr Store3 ;Store 0 0 0 in attr table
ldx #%01010101
jsr Store3 ;Store 85 85 85 in attr table
ldx #%10101010
jsr Store2 ;Store 170 170 in attr table
dey
bne .AttrRow
rts ;That's it!
Set3columns:
ldx #$01 ;Start row with 1 1 1 1 bytes
jsr Store4
inx ;Then 2 2 2 2
Set2Columns
jsr Store4
inx ;Then 3 3 3 3
Store4:
stx $2007
Store3:
stx $2007
Store2:
stx $2007
stx $2007
rts
;Image palette is at $3F00 in PPU space. We just fill the $10 bytes of it like this initially:
;
;Palette entry # Colour code
;--------------- -----------
;0 irrelevant
;1 0
;2 1
;3 2
;4 irrelevant
;5 3
;6 4
;7 5
;8 irrelevant
;9 6
;10 7
;11-15 irrelevant
;
;When we want to "rotate" the colour bars, just add 1 to each entry, or subtract 1 from each
;entry. This routine sets the palette data, given an initial colour # in Y
;
;Palette values are contained in the PPU memory space, at:
;$3F00 - image palette
;$3F10 - sprite palette - not used here
;To set the PPU memory address, write high byte and then low byte to $2006.
;Then write to $2007 to "poke" the memory. The auto-increment depends on whether
;bit 2 of $2000 is set. If clear, increment = 1. If set, increment = 32.
SetPalette:
;Set PPU memory address to $3F01 (first palette entry not used)
ldx #HIGH($3F01) ;High byte of $3F01
stx $2006
ldx #LOW($3F01);Low byte of $3F01
stx $2006
ldx #3 ;Set three groups of (3 entries + 1 irrelevant)
.Write:
sty $2007
iny
sty $2007
iny
sty $2007
iny
sty $2007 ;The irrelevant one
dex
bne .Write
rts ;Done!
NMI_Routine:
;Read the controller buttons. Move to the next "colour set" if pressed.
;By shifting the palette values by 1, or -1, we can achieve a "scrolling" effect
;when buttons A & B are pressed.
;Re-write the image palette array if necessary. No need to modify name table data.
;First, save the registers
php
pha
txa
pha
tya
pha
ldx <$00 ;Get previous button status byte
stx <$01 ;Put it in $01
;Controller read routine, by Kevin Horton.
;Returns following bits in A:
; Bit Button
; --- ------
; 0 Right
; 1 Left
; 2 Down
; 3 Up
; 4 Start
; 5 Select
; 6 B
; 7 A
ldy #$08 ;Number of iterations
ldx #$01
stx $4016 ;store 1 out the strobe
dex
stx $4016 ;store 0 out the strobe
.ReadBit:
lda $4016 ;read the button
ror A ;transfer it to the carry flag
txa
rol A
tax ;rotate X left, storing the bit into the lowest pos.
dey
bne .ReadBit ;loop 8 times for all 8 buttons
; rts ;return acc with status of all 8 buttons
;Now we compare the current and previous button values. We want to see if either button A or B
;is pressed, *AND* that button was *NOT* pressed last time.
;To do this:
;· get the current button status.
;· Logical AND with %11000000 (= $C0), giving "CBS", to see if either A or B is pressed. If not,
; nothing to do.
;· Now we know that at least one of A, B is pressed.
;· get the previous button status.
;· NOT this previous status, giving "NPBS"
;· Logical AND "NPBS" with "CBS".
;· Then bits 6 & 7 are set iff the button is pressed now, but was not pressed last frame. So take
; action based on this.
and #$C0 ;Only interested in A & B at the moment
sta <$00 ;Use location 0 for storing current controller button data
;Next inst unnecessary since last inst was sta $00
; lda <$00 ;Get current button status
beq .DoNothing ;If neither button pressed
lda <$01 ;Get previous button status
eor #$FF ;NOT it
and <$00 ;AND this with current status
beq .DoNothing ;If no change from last time, do nothing
;Now we can see what action to take.
;If A pressed, shift bars one to the right (i.e., increment palette settings).
;If B pressed, shift bars one to the left (i.e., decrement palette settintgs).
ldy <$02 ;Get current palette base
rol A ;So button A status in carry
bcc .NotA
;Shift palette "up by one"
iny
.NotA:
rol A ;So button B status in carry
bcc .NotB
;Shift palette "down by one"
dey
.NotB:
sty <$02
jsr SetPalette
.DoNothing: ;Restore registers and exit.
pla
tay
pla
tax
pla
plp
IRQ_Routine: ;Dummy label
rti
;That's all the code. Now we just need to set the vector table approriately.
.bank 1
.org $FFFA
.dw NMI_Routine
.dw Reset_Routine
.dw IRQ_Routine ;Not used, just points to RTI
.bank 2
.org $0000
.incbin "color.chr"
.inesprg 1 ; One 16k prg bank
.ineschr 1 ; One 8k chr bank
.inesmir 1 ; Vertical map mirroring
.inesmap 0 ; Use mapper 0
;Colour bars program by Mark Knibbs
.bank 0
.org $C000 ;16Kb PRG-ROM, 8Kb CHR-ROM
.db "Colour bars display program v1.1 14-Nov-97 © 1997 by Mark Knibbs <mark_k@iname.com>"
Reset_Routine:
cld ;Clear decimal flag
sei ;Disable interrupts
.WaitV:
lda $2002
bpl .WaitV ;Wait for vertical blanking interval
ldx #$00
stx $2000
stx $2001 ;Screen display off, amongst other things
dex
txs ;Top of stack at $1FF
;Clear the NES' WRAM. This routine is ripped from "Duck Hunt" - I should probably clear all $800 bytes.
ldy #$06 ;To clear 7 x $100 bytes, from $000 to $6FF?
sty <$01 ;Store count value in $01
ldy #$00
sty <$00
lda #$00
.Clear:
sta [$00],y ;Clear $100 bytes
dey
bne .Clear
dec <$01 ;Decrement "banks" left counter
bpl .Clear ;Do next if >= 0
;Now we need to set up the palette and colour bar data.
jsr SetTables ;Set up name and attribute table data
ldy #$00 ;Initial palette "position"
;Next instruction unnecessary since memory has just been cleared
; sty <$02 ;Store palette position
jsr SetPalette ;Set initial palette data
;Enable vblank interrupts, etc.
lda #$80
sta $2000
lda #$0B ;Screen on, sprites off, show leftmost 8 pixels, colour
sta $2001
; cli ;Enable interrupts(?)
;Now just loop forever?
.Loop:
jmp .Loop
;We only need 4 distinct characters, like this:
;
;For low 2 bits of colour number = %00. Character byte number = 0.
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
;
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
;
;For low 2 bits = %01. Character byte number = 1.
;
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
;
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
;
;For low 2 bits = %10. Character byte number = 2.
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
; %00000000
;
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
;
;For low 2 bits = %11. Character byte number = 3.
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
;
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
; %11111111
;
;----------
;
;The display is 256 pixels across. This is 8 columns of 32 pixels, or 16 columns of 16 pixels.
;I'll start off by using 8 columns of 32 pixels.
;
;NOTE: Need to carefully choose which colours to use for the bars. This is because of the "palette
;mirroring" effect (i.e., $3F00 mirrored to $3F04, $3F08 & $3F0C)
;Suitable palette entries to use would be:
; 1 2 3 5 6 7 9 10
;Initially these contain these colour numbers (see palette-setting routine below):
; 0 1 2 3 4 5 6 7
;We'll initially have colour #0 on the left, and colour #7 on the right. So the bytes of the name
;table (at $2000 in PPU space) need to be like this:
;
;Entry1 Entry2 Entry3 Entry5 Entry6 Entry7 Entry9 Entry10
;
;1 1 1 1 2 2 2 2 3 3 3 3 1 1 1 1 2 2 2 2 3 3 3 3 1 1 1 1 2 2 2 2
;
;Fill all 30 rows with this pattern.
;
;
;Now for the attribute table layout. The attr table is 64 bytes long, at $23C0 in PPU space.
;So all 8 rows of the attribute table will be filled with these bytes:
;
; %00000000 %00000000 %00000000 %01010101 %01010101 %01010101 %10101010 %10101010
;In decimal:
; 0 0 0 85 85 85 170 170
;Set the name ($2000) & attribute tables ($23C0)
;-----------------------------------------------
SetTables:
;Set the PPU memory address
ldx #$20 ;High byte of $2000
stx $2006
ldx #$00 ;Low byte of $2000
stx $2006
ldy #30 ;30 rows to do
.Row:
jsr Set3columns ;Do the first 3 columns
jsr Set3columns ;Do the next 3 columns
;Now we do the last two bars (last 8 bytes in the row); these are set to 1 1 1 1 2 2 2 2.
ldx #$01
jsr Set2Columns
dey
bne .Row
;We've set all name table bytes. Now for the attribute table. PPU memory address is already in
;the right place when we get here.
ldy #8 ;8 attribute rows to do
.AttrRow:
ldx #%00000000
jsr Store3 ;Store 0 0 0 in attr table
ldx #%01010101
jsr Store3 ;Store 85 85 85 in attr table
ldx #%10101010
jsr Store2 ;Store 170 170 in attr table
dey
bne .AttrRow
rts ;That's it!
Set3columns:
ldx #$01 ;Start row with 1 1 1 1 bytes
jsr Store4
inx ;Then 2 2 2 2
Set2Columns
jsr Store4
inx ;Then 3 3 3 3
Store4:
stx $2007
Store3:
stx $2007
Store2:
stx $2007
stx $2007
rts
;Image palette is at $3F00 in PPU space. We just fill the $10 bytes of it like this initially:
;
;Palette entry # Colour code
;--------------- -----------
;0 irrelevant
;1 0
;2 1
;3 2
;4 irrelevant
;5 3
;6 4
;7 5
;8 irrelevant
;9 6
;10 7
;11-15 irrelevant
;
;When we want to "rotate" the colour bars, just add 1 to each entry, or subtract 1 from each
;entry. This routine sets the palette data, given an initial colour # in Y
;
;Palette values are contained in the PPU memory space, at:
;$3F00 - image palette
;$3F10 - sprite palette - not used here
;To set the PPU memory address, write high byte and then low byte to $2006.
;Then write to $2007 to "poke" the memory. The auto-increment depends on whether
;bit 2 of $2000 is set. If clear, increment = 1. If set, increment = 32.
SetPalette:
;Set PPU memory address to $3F01 (first palette entry not used)
ldx #HIGH($3F01) ;High byte of $3F01
stx $2006
ldx #LOW($3F01);Low byte of $3F01
stx $2006
ldx #3 ;Set three groups of (3 entries + 1 irrelevant)
.Write:
sty $2007
iny
sty $2007
iny
sty $2007
iny
sty $2007 ;The irrelevant one
dex
bne .Write
rts ;Done!
NMI_Routine:
;Read the controller buttons. Move to the next "colour set" if pressed.
;By shifting the palette values by 1, or -1, we can achieve a "scrolling" effect
;when buttons A & B are pressed.
;Re-write the image palette array if necessary. No need to modify name table data.
;First, save the registers
php
pha
txa
pha
tya
pha
ldx <$00 ;Get previous button status byte
stx <$01 ;Put it in $01
;Controller read routine, by Kevin Horton.
;Returns following bits in A:
; Bit Button
; --- ------
; 0 Right
; 1 Left
; 2 Down
; 3 Up
; 4 Start
; 5 Select
; 6 B
; 7 A
ldy #$08 ;Number of iterations
ldx #$01
stx $4016 ;store 1 out the strobe
dex
stx $4016 ;store 0 out the strobe
.ReadBit:
lda $4016 ;read the button
ror A ;transfer it to the carry flag
txa
rol A
tax ;rotate X left, storing the bit into the lowest pos.
dey
bne .ReadBit ;loop 8 times for all 8 buttons
; rts ;return acc with status of all 8 buttons
;Now we compare the current and previous button values. We want to see if either button A or B
;is pressed, *AND* that button was *NOT* pressed last time.
;To do this:
;· get the current button status.
;· Logical AND with %11000000 (= $C0), giving "CBS", to see if either A or B is pressed. If not,
; nothing to do.
;· Now we know that at least one of A, B is pressed.
;· get the previous button status.
;· NOT this previous status, giving "NPBS"
;· Logical AND "NPBS" with "CBS".
;· Then bits 6 & 7 are set iff the button is pressed now, but was not pressed last frame. So take
; action based on this.
and #$C0 ;Only interested in A & B at the moment
sta <$00 ;Use location 0 for storing current controller button data
;Next inst unnecessary since last inst was sta $00
; lda <$00 ;Get current button status
beq .DoNothing ;If neither button pressed
lda <$01 ;Get previous button status
eor #$FF ;NOT it
and <$00 ;AND this with current status
beq .DoNothing ;If no change from last time, do nothing
;Now we can see what action to take.
;If A pressed, shift bars one to the right (i.e., increment palette settings).
;If B pressed, shift bars one to the left (i.e., decrement palette settintgs).
ldy <$02 ;Get current palette base
rol A ;So button A status in carry
bcc .NotA
;Shift palette "up by one"
iny
.NotA:
rol A ;So button B status in carry
bcc .NotB
;Shift palette "down by one"
dey
.NotB:
sty <$02
jsr SetPalette
.DoNothing: ;Restore registers and exit.
pla
tay
pla
tax
pla
plp
IRQ_Routine: ;Dummy label
rti
;That's all the code. Now we just need to set the vector table approriately.
.bank 1
.org $FFFA
.dw NMI_Routine
.dw Reset_Routine
.dw IRQ_Routine ;Not used, just points to RTI
.bank 2
.org $0000
.incbin "color.chr"
what is the problem?