the board says 'Upload failed. You are not permitted to upload this type of file'...
The project in it's current state:
It's a modified 'hello' demo. Maybe It's ugly, and not cleaned up... Please shoot on it
File main3.asm:
processor 6502
include vcs.h
include macro.h
include lines.h
org $F000
Temp = $80
PlayfieldY = $90
Direction = $91
ScanLine = $92
SubLineCount = $93
offsetLine0_7 = $94
offsetLine8_15 = $95
offsetLine16_19 = $96
PositionX = $97
invert = $98
Start
SEI ; Disable interrupts, if there are any.
CLD ; Clear BCD math bit.
LDX #$FF
TXS ; Set stack to beginning.
;
; Now the memory and TIA registers must be cleared. You may feel the
; need to write a subroutine that only clears out a certain section of
; memory, but for now a simple loop will suffice.
;
; Since X is already loaded to 0xFF, our task becomes simply to ocunt
; everything off.
;
LDA #0
B1 STA 0,X
DEX
BNE B1
;
; The above routine does not clear location 0, which is VSYNC. We will
; take care of that later.
;
; At this point in the code we would set up things like the data
; direction registers for the joysticks and such.
;
JSR GameInit
;
; Here is a representation of our program flow.
;
MainLoop
JSR VerticalBlank ;Execute the vertical blank.
JSR CheckSwitches ;Check console switches.
JSR GameCalc ;Do calculations during Vblank
JSR DrawScreen ;Draw the screen
JSR OverScan ;Do more calculations during overscan
JMP MainLoop ;Continue forever.
VerticalBlank ;*********************** VERTICAL BLANK HANDLER
LDX #0
LDA #2
STA WSYNC
STA WSYNC
STA WSYNC
STA VSYNC ;Begin vertical sync.
STA WSYNC ; First line of VSYNC
STA WSYNC ; Second line of VSYNC.
;
; But before we finish off the third line of VSYNC, why don't we
; use this time to set the timer? This will save us a few cycles
; which would be more useful in the overscan area.
;
; To insure that we begin to draw the screen at the proper time,
; we must set the timer to go off just slightly before the end of
; the vertical blank space, so that we can WSYNC up to the ACTUAL
; end of the vertical blank space. Of course, the scanline we're
; going to omit is the same scanline we were about to waste VSYNCing,
; so it all evens out.
;
; Atari says we have to have 37 scanlines of VBLANK time. Since
; each scanline uses 76 cycles, that makes 37*76=2888 cycles.
; We must also subtract the five cycles it will take to set the
; timer, and the three cycles it will take to STA WSYNC to the next
; line. Plus the checking loop is only accurate to six cycles, making
; a total of fourteen cycles we have to waste. 2888-14=2876.
;
; We almost always use TIM64T for this, since the math just won't
; work out with the other intervals. 2880/64=44.something. It
; doesn't matter what that something is, we have to round DOWN.
;
LDA #44
STA TIM64T
;
; And now's as good a time as any to clear the collision latches.
;
LDA #0
STA CXCLR
;
; Now we can end the VSYNC period.
;
STA WSYNC ; Third line of VSYNC.
STA VSYNC ; (0)
;
; At this point in time the screen is scanning normally, but
; the TIA's output is suppressed. It will begin again once
; 0 is written back into VBLANK.
;
RTS
;
; Checking the game switches is relatively simple.
;
; It just so happens that I'm not going to check any game switches
; here. I'm just going to set up the colors, without even checking
; the B&W switch! HA!
;
CheckSwitches ;*************************** CONSOLE SWITCH HANDLER
LDA #0
STA COLUBK ; Background will be black.
RTS
;
; Minimal game calculations, just to get the ball rolling.
;
GameCalc ;******************************* GAME CALCULATION ROUTINES
CLC
LDX PositionX
LDA SWCHA ;read joystick
AND #$80
CMP #$80
BCS CONT
INX
STX PositionX
CPX #20
BCC CONT
LDA invert
EOR #$01
STA invert
LDX #0
STX PositionX
CONT
LDA SWCHA ;read joystick
AND #$40
CMP #$40
BCS CONT2
DEX
STX PositionX
CPX #255
BCC CONT2
LDA invert
EOR #$01
STA invert
LDX #19
STX PositionX
CONT2
LDA OFFSET_DATA_0_7,X
STA offsetLine0_7
LDA OFFSET_DATA_8_15,X
STA offsetLine8_15
LDA OFFSET_DATA_16_19,X
STA offsetLine16_19
RTS
ChangeDir
LDA Direction
EOR #$FE
STA Direction
RTS
;
; This is the scariest thing I've done all month.
;
DrawScreen ;**************************** SCREEN DRAWING ROUTINES
LDA INTIM
BNE DrawScreen ; Whew!
STA WSYNC
STA VBLANK ;End the VBLANK period with a zero.
LDA #2
STA CTRLPF
LDA #171
STA ScanLine
BlueLines
JSR BlueLine
DEC ScanLine
LDA ScanLine
CMP #120
BNE BlueLines
LDA #$88
STA COLUBK
DEC ScanLine
STA WSYNC
LDA #$8A
STA COLUBK
DEC ScanLine
LDX invert
LDY #$CC
LDX #$C4
LDA invert
CMP #$01
BNE NOT_INVERT
LDX #$CC
LDY #$C4
NOT_INVERT
STA WSYNC
LDA #$9B
STA COLUBK
DEC ScanLine
LDA PositionX
CMP #07
BCS Skip1
Skip1
CMP #14
BCS Skip2
Skip2
SLEEP 62
;LINE 0
SLEEP 12
LINEX 3
LINEY 3
LINEX 3
LINEY 3
LINEX 3
LINEY 3
LINEX 3
LINEY 3
LINEX 3
LINEY 3
LINEX 3
LINEY 3
LINEX 3
LINEY 3
LINEX 3
LINEY 3
LINEX 3
LINEY 3
LINEX 3
SLEEP 14
LINEX 4
LINEY 3
LINEX 4
LINEY 3
LINEX 4
LINEY 3
LINEX 4
LINEY 3
LINEX 4 ; center L
LINEY 3 ;center R
LINEX 3
LINEY 4
LINEX 3
LINEY 4
LINEX 3
LINEY 4
LINEX 3
LINEY 4
;LINE 1
LDA offsetLine0_7
AND #%00000010
BNE Line1NoOffset
Line1NoOffset
SLEEP 13
LINEY 4
LINEX 4
LINEY 4
LINEX 4
LINEY 4
LINEX 4
LINEY 4
LINEX 4
LINEY 4
LINEX 4
LINEY 4
LINEX 4
LINEY 4
SLEEP 18
STX.w COLUBK
STY.w COLUBK
STX.w COLUBK
nop
STY COLUBK
STX.w COLUBK
STY.w COLUBK
nop
STX COLUBK ;L
STY.w COLUBK ;R
STX.w COLUBK
nop
STY COLUBK
STX.w COLUBK
STY.w COLUBK
STX.w COLUBK
STY.w COLUBK
;LINEX 4
;LINEY 4
;LINEX 4
;LINEY 4
;LINEX 4
;LINEY 4
;LINEX 5;L
;LINEY 4;R
;LINEX 4
;LINEY 4
;LINEX 4
;LINEY 4
;LINEX 4
;LINEY 4
;LINE 2
LDA offsetLine0_7
AND #%00000100
BNE Line2NoOffset
Line2NoOffset
SLEEP 11
LINEY 5
LINEX 5
LINEY 5
LINEX 5
LINEY 5
LINEX 5 ;L
LINEY 5 ;R
LINEX 5
LINEY 5
LINEX 5
LINEY 5
LINEX 5
SLEEP 13
LINEY 5
LINEX 6
LINEY 5
LINEX 6
LINEY 5
LINEX 6 ;L
LINEY 5 ;R
LINEX 5
LINEY 6
LINEX 5
LINEY 6
LINEX 5
;LINE 3
LDA offsetLine0_7
AND #%00001000
BNE Line3NoOffset
Line3NoOffset
SLEEP 12
LINEY 6
LINEX 6
LINEY 6
LINEX 6
LINEY 6
LINEX 6
LINEY 6
LINEX 6
SLEEP 27
LINEY 6
LINEX 6
LINEY 6
nop
LINEX 5;L
LINEY 6;R
LINEX 6
nop
LINEY 5
LINEX 5
;LINE 4
LDA offsetLine0_7
AND #%00010000
BNE Line4NoOffset
Line4NoOffset
SLEEP 18
LINEY 7
LINEX 7
LINEY 7
LINEX 7
LINEY 7
LINEX 7
LINEY 7
LINEX 7
SLEEP 19
LINEY 7
LINEX 7
LINEY 7
LINEX 8;R
LINEY 7;L
LINEX 7
LINEY 8
LINEX 7
;LINE 5
LDA offsetLine0_7
AND #%00100000
BNE Line5NoOffset
Line5NoOffset
SLEEP 7
LINEY 8
LINEX 8
LINEY 8
LINEX 8
LINEY 8
LINEX 8
LINEY 8
LINEX 4
SLEEP 15
LINEY 8
LINEX 8
LINEY 8
nop
LINEX 7 ;L
LINEY 8 ;R
LINEX 8
nop
LINEY 7
LINEX 8
LINEY 4
;LINE 6
LDA offsetLine0_7
AND #%01000000
BNE Line6NoOffset
Line6NoOffset
SLEEP 6
LINEX 9
LINEY 9
LINEX 9
LINEY 9
LINEX 9
LINEY 9
LINEX 9
LINEY 3
SLEEP 9
LINEX 9
LINEY 9
LINEX 10 ;L
LINEY 9 ;R
LINEX 9
LINEY 10
;LINE 7
LDA offsetLine0_7
AND #%10000000
BNE Line7NoOffset
Line7NoOffset
SLEEP 10
LINEX 10
LINEY 10
LINEX 10
LINEY 10
LINEX 10
LINEY 10
SLEEP 16
LINEX 10
LINEY 10
LINEX 10
LINEY 10
LINEX 10
LINEY 10
;line 8
LDA offsetLine8_15
AND #%00000001
BNE Line8NoOffset
Line8NoOffset
SLEEP 7
LINEX 11
LINEY 11
LINEX 11
LINEY 11
LINEX 11
LINEY 5
SLEEP 15
LINEX 11
LINEY 11
LINEX 10 ;L
nop
LINEY 11 ;R
LINEX 11
LINEY 3
;line 9
LDA offsetLine8_15
AND #%00000010
BNE Line9NoOffset
Line9NoOffset
SLEEP 7
LINEX 12
LINEY 12
LINEX 12
LINEY 12
LINEX 12
LINEY 4
SLEEP 12
LINEX 12
LINEY 12
LINEX 12
LINEY 12
LINEX 12
LINEY 4
LINEX 8
;line 10
LDA offsetLine8_15
AND #%00000100
BNE Line10NoOffset
Line10NoOffset
SLEEP 8
LINEY 13
LINEX 13
LINEY 13
LINEX 13
LINEY 3
LINEX 3
SLEEP 18
LINEY 13
LINEX 13
LINEY 13
LINEX 13
LINEY 3
LINEX 3
;line 11
LDA offsetLine8_15
AND #%00001000
BNE Line11NoOffset
Line11NoOffset
;SLEEP 18
SLEEP 8
LINEY 14
LINEX 14
LINEY 14
LINEX 14
SLEEP 20
LINEY 14
LINEX 14
LINEY 14
LINEX 4
;line 12
LDA offsetLine8_15
AND #%00010000
BNE Line12NoOffset
Line12NoOffset
SLEEP 22
LINEY 15
LINEX 15
LINEY 15
LINEX 3
SLEEP 28
LINEY 15
LINEX 15
LINEY 15
LINEX 3
;line 13
LDA offsetLine8_15
AND #%00100000
BNE Line13NoOffset
Line13NoOffset
SLEEP 18
LINEY 16
LINEX 16
LINEY 16
LINEX 4
SLEEP 24
LINEY 16
LINEX 16
LINEY 16
LINEX 4
;line 14
LDA offsetLine8_15
AND #%01000000
BNE Line14NoOffset
Line14NoOffset
SLEEP 16
LINEY 17
LINEX 17
LINEY 17
LINEX 3
SLEEP 22
LINEY 17
LINEX 17
LINEY 17
LINEX 3
;line 15
LDA offsetLine8_15
AND #%10000000
BNE Line15NoOffset
Line15NoOffset
SLEEP 12
LINEY 18
LINEX 18
LINEY 18
LINEX 4
SLEEP 18
LINEY 18
LINEX 18
LINEY 18
LINEX 4
;line 16
LDA offsetLine16_19
AND #%00000001
BNE Line16NoOffset
Line16NoOffset
SLEEP 10
LINEY 19
LINEX 19
LINEY 19
LINEX 3
SLEEP 16
LINEY 19
LINEX 19
LINEY 19
LINEX 3
;line 17
LDA offsetLine16_19
AND #%00000010
BNE Line17NoOffset
Line17NoOffset
SLEEP 6
LINEY 20
LINEX 20
LINEY 20
LINEX 4
SLEEP 12
LINEY 20
LINEX 20
LINEY 20
LINEX 4
;line 18
LDA offsetLine16_19
AND #%00000100
BNE Line18NoOffset
Line18NoOffset
SLEEP 4
LINEY 21
LINEX 21
LINEY 21
LINEX 3
SLEEP 10
LINEY 21
LINEX 21
LINEY 21
LINEX 3
;line 19
LDA offsetLine16_19
AND #%00001000
BNE Line19NoOffset
Line19NoOffset
;SLEEP 7
LINEY 22
LINEX 22
LINEY 22
LINEX 4
SLEEP 6
LINEY 22
LINEX 22
LINEY 22
LINEX 6
LDA #$0
STA COLUBK
; Draw other lines
DrawLines
STA WSYNC
DEC ScanLine
BNE DrawLines
STA WSYNC ;Finish this scanline.
STA VBLANK ; Make TIA output invisible,
RTS
;
; For the Overscan routine, one might take the time to process such
; things as collisions. I, however, would rather waste a bunch of
; scanlines, since I haven't drawn any players yet.
;
OverScan ;***************************** OVERSCAN CALCULATIONS
LDX #30
KillLines
STA WSYNC
DEX
BNE KillLines
RTS
BlueLine
LDA #$85
STA COLUBK
STA WSYNC
RTS
Line1
STA COLUBK
NOP
SLEEP 4
LINEX 5
LINEY 5
LINEX 5
LINEY 5
LINEX 5
LINEY 5
LINEX 5
LINEY 5
LINEX 5
LINEY 5
STA WSYNC
RTS
Line2
STX.w COLUBK
SLEEP 5
LINEY 6
LINEX 6
LINEY 6
LINEX 6
LINEY 6
LINEX 6
LINEY 6
LINEX 6
STA WSYNC
RTS
Line3
SLEEP 6
LINEY 7
LINEX 7
LINEY 7
LINEX 7
LINEY 7
LINEX 7
LINEY 7
LINEX 3
STA WSYNC
RTS
Line4
SLEEP 9
LINEX 8
LINEY 8
LINEX 8
LINEY 8
LINEX 8
LINEY 8
LINEX 3
STA WSYNC
RTS
Line5
SLEEP 7
LINEX 9
LINEY 9
LINEX 9
LINEY 9
LINEX 9
LINEY 9
STA WSYNC
RTS
Line6
SLEEP 3
LINEX 10
LINEY 10
LINEX 10
LINEY 10
LINEX 10
LINEY 8
STA WSYNC
RTS
Line7
;SLEEP 1
LINEX 12
LINEY 11
LINEX 11
LINEY 11
LINEX 11
LINEY 3
STA WSYNC
RTS
Line8
;SLEEP 1
LINEX 9
LINEY 12
LINEX 12
LINEY 12
LINEX 12
LINEY 4
STA WSYNC
RTS
Line9
;SLEEP 1
LINEX 8
LINEY 13
LINEX 13
LINEY 13
LINEX 3
STA WSYNC
RTS
Line10
;SLEEP 1
LINEX 5
LINEY 14
LINEX 14
LINEY 4
LINEY 11
LINEX 3
STA WSYNC
RTS
;
; GameInit could conceivably be called when the Select key is pressed,
; or some other event.
;
GameInit
LDA #0
STA PlayfieldY
LDA #1
STA Direction; Set Direction to 1
LDA #0
STA PositionX
LDA #0
STA invert
RTS
;
; Graphics are placed so that the extra cycle in the PFData,X indexes
; is NEVER taken, by making sure it never has to index across a page
; boundary. This way our cycle count holds true.
;
org $FF00 ; *********************** GRAPHICS DATA
;
; This is the tricky part of drawing a playfield: actually
; drawing it. Well, the display routine and all that binary
; math was a bit tricky, too, but still, listen up.
;
; Playfield data isn't stored the way most bitmaps are, even
; one-dimensional bitmaps. We will use the left side of the
; screen only, knowing that the right side is either repeated
; or reflected from it.
;
; In PF0 and PF2, the most significant bit (bit 7) is on the RIGHT
; side. In PF1, the most significant bit is on the LEFT side. This
; means that relative to PF0 and PF2, PF1 has a reversed bit order.
; It's just really weird.
;
; PF0 | PF1 | PF2
; 4 5 6 7|7 6 5 4 3 2 1 0|0 1 2 3 4 5 6 7
;
; This is important to remember when doing calculations on bytes intended
; for the PF registers. Defender gives a good example of this.
;
; It will become necessary to write a program that makes this easier,
; because it is easy to become confused when dealing with this system.
;
OFFSET_DATA_0_7
.byte $0,$0,$80,$20,$10,$88,$48,$24,$94,$54,$B4,$AC,$6C,$DA,$BA,$76,$F6,$DE,$FE,$FE
OFFSET_DATA_8_15
.byte $0,$4,$20,$84,$11,$24,$4A,$95,$2A,$55,$AA,$B5,$DB,$6E,$BB,$DF,$FB,$7F,$FB,$FF
OFFSET_DATA_16_19
.byte $0,$0,$0,$0,$2,$4,$4,$8,$2A,$A,$2A,$C,$C,$36,$36,$1A,$3A,$3E,$1E,$1E
org $FFFC
.word Start
.word Start
File Lines.h:
MAC LINEY
.CYCLES SET {1}
IF .CYCLES < 3
ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2"
ERR
ENDIF
IF .CYCLES & 1
STY COLUBK
.CYCLES SET .CYCLES - 3
ELSE
STY.w COLUBK
.CYCLES SET .CYCLES - 4
ENDIF
REPEAT .CYCLES / 2
nop
REPEND
ENDM
MAC LINEX
.CYCLES SET {1}
IF .CYCLES < 3
ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2"
ERR
ENDIF
IF .CYCLES & 1
STX COLUBK
.CYCLES SET .CYCLES - 3
ELSE
STX.w COLUBK
.CYCLES SET .CYCLES - 4
ENDIF
REPEAT .CYCLES / 2
nop
REPEND
ENDM
MAC LINEY2
.CYCLES SET {1}
IF .CYCLES < 3
ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2"
ERR
ENDIF
IF .CYCLES & 1
.CYCLES2 SET .CYCLES - 3
ELSE
.CYCLES2 SET .CYCLES - 4
ENDIF
REPEAT .CYCLES2 / 2
nop
REPEND
IF .CYCLES & 1
STY COLUBK
ELSE
STY.w COLUBK
ENDIF
ENDM
MAC LINEX2
.CYCLES SET {1}
IF .CYCLES < 3
ECHO "MACRO ERROR: 'SLEEP': Duration must be > 2"
ERR
ENDIF
IF .CYCLES & 1
.CYCLES2 SET .CYCLES - 3
ELSE
.CYCLES2 SET .CYCLES - 4
ENDIF
REPEAT .CYCLES2 / 2
nop
REPEND
IF .CYCLES & 1
STX COLUBK
ELSE
STX.w COLUBK
ENDIF
ENDM
; EOF