Jump to content

Photo

VCS Skeleton Kernel - Source


2 replies to this topic

#1 Curt Vendel OFFLINE  

Curt Vendel

    River Patroller

  • 4,481 posts
  • Location:Carmel, New York

Posted Sat Sep 10, 2005 11:28 PM

.title VCS Skeleton Program
.enable ama
.asect ;absolute addressing
.radix 16 ;default base
.LIST MEB ;DISPLAY ALL OF ANY MACROS
;
romstr = 0f000 ;rom start addr
; SKLTON.MAC
; copyright Atari, 1982
.nlist
.sbttl Stella Hardware Regs
.list
.page
; *
; **
;********** **********************************
;*********** * TIA and PIA Register Addresses *
;********** **********************************
; **
; *


;
; TIA Addresses
vsync = 00 ;bit 1 vertical sync set-clr 1=>start
vblank = 01 ;bit 76 1 vblank set-clr, port ctl (inpt0-5)
wsync = 02 ;strobe wait for horiz blank
rsync = 03 ;strobe reset horiz sync counter
nusiz0 = 04 ;bits 54 210 number-size player/missile 0
nusiz1 = 05 ;bits 54 210 number-size player/missile 1
colup0 = 06 ;bits 7654321 color(4)-lum(3) player 0
colup1 = 07 ;bits 7654321 color(4)-lum(3) player 1
colupf = 08 ;bits 7654321 color(4)-lum(3) playfield
colubk = 09 ;bits 7654321 color(4)-lum(3) background
ctrlpf = 0a ;bits 54 210 playfield control & ball
refp0 = 0b ;bit 3 reflect player 0. 1=>reflect
refp1 = 0c ;bit 3 reflect player 1
pf0 = 0d ;bits 7654 playfield reg byte 0 (reversed)
pf1 = 0e ;bits all playfield reg byte 1
pf2 = 0f ;bits all playfield reg byte 2 (reversed)
resp0 = 10 ;strobe reset player 0
resp1 = 11 ;strobe reset player 1
resm0 = 12 ;strobe reset missile 0
resm1 = 13 ;strobe reset missile 1
resbl = 14 ;strobe reset ball
audc0 = 15 ;bits 3210 audio control 0
audc1 = 16 ;bits 3210 audio control 1
audf0 = 17 ;bits 3210 audio frequency 0
audf1 = 18 ;bits 3210 audio frequency 1
audv0 = 19 ;bits 3210 audio volume 0
audv1 = 1a ;bits 3210 audio volume 1
grp0 = 1b ;bits all graphics for player 0
grp1 = 1c ;bits all graphics for player 1
enam0 = 1d ;bit 1 enable missile 0. 1=> enable
enam1 = 1e ;bit 1 enable missile 1
enabl = 1f ;bit 1 enable ball
hmp0 = 20 ;bits 7654 horiz motion player 0. 0-7 => left
hmp1 = 21 ;bits 7654 horiz motion player 1. f-8 => right
hmm0 = 22 ;bits 7654 horiz motion missile 0
hmm1 = 23 ;bits 7654 horiz motion missile 1
hmbl = 24 ;bits 7654 horiz motion ball
vdelp0 = 25 ;bit 0 vertical delay player 0. 1=> vdel on
vdelp1 = 26 ;bit 0 vertical delay player 1
vdelbl = 27 ;bit 0 vertical delay ball
resmp0 = 28 ;bit 1 reset missile to player 0
resmp1 = 29 ;bit 1 reset missile to player 1
hmove = 2a ;strobe act on horiz motion
hmclr = 2b ;strobe clear all hm registers
cxclr = 2c ;strobe clear collision latches
;
; Read Addresses - bits 7 & 6 only
cxm0p = 30 ;m0*p1 m0*p0
cxm1p = 31 ;m1*p0 m1*p1
cxp0fb = 32 ;p0*pf p0*bl
cxp1fb = 33 ;p1*pf p1*bl
cxm0fb = 34 ;m0*pf m0*bl
cxm1fb = 35 ;m1*pf m1*bl
cxblpf = 36 ;bl*pf
cxppmm = 37 ;p0*p1 m0*m1
inpt0 = 38 ;pot 0. bit7=1 => pot cap is charged
inpt1 = 39 ;pot 1
inpt2 = 3a ;pot 2
inpt3 = 3b ;pot 3
inpt4 = 3c ;joystick 0 button. b7=0 => button pressed
inpt5 = 3d ;joystick 1 button
;
; PIA and Timer (6532) Locations
swcha = 280 ;p0,p1 sticks (rldu), pot triggers, kbd, driving ctl
ctlswa = 281 ;swcha i/o control 1=output
swchb = 282 ;console switches (read only) p1b,p0b,x,x,b/w,x,select, reset
ctlswb = 283 ;unused
intim = 284 ;interval timer input =>timer up
tim1t = 294 ;timer output: 1 mc/tick (.838 microsec)
tim8t = 295 ;8 machine cycles/tick
tim64t = 296 ;64 mc's/tick
t1024t = 297 ;1024 machine cycles/tick (858.2 microseconds)
.nlist
.sbttl Equates
.list
.page
; *
; **
;********** ********************
;*********** * Assorted Equates *
;********** ********************
; **
; *


gscon = 45. ;game select timer initial value
ovrcon = 25 ;overscan timer initial value
vblcon = 2b ;vblank timer initial value
gmax = 03 ;highest game # +1
.nlist
.sbttl Ram Variables
.list
.page
; *
; **
;********** *****************************
;*********** * Variables (ram page zero) *
;********** *****************************
; **
; *


.=80
tcol: .=.+1 ;top score color
bcol: .=.+1 ;bottom score color
gflg1: .=.+1 ;game status bits
;80 1= game is in play
;40 1= bonzo (easy) game
;20 1= one-player game
;10 1= select mode
;08 1= color-shifting attract mode
;04 not used yet
;02 not used yet
;01 not used yet
gamno: .=.+1 ;game number (decimal)
gstim: .=.+1 ;game select timer
tscr: .=.+2 ;top player's score
bscr: .=.+2 ;bottom player's score
rand: .=.+1 ;"random" number seed/last number
rndind: .=.+1 ;"random" number index
frame: .=.+1 ;frame counter
hfram: .=.+1 ;hi byte of frame counter
atim: .=.+1 ;attract timer
atmask: .=.+1 ;attract lum mask
t0: .=.+1 ;temporary variables
t1: .=.+1
.NLIST
.SBTTL MACROS
.LIST
.PAGE
; *
; **
;********** ******************
;*********** * MACROS *
;********** ******************
; **
; *
;
; PALIGN WILL AUTOMATICALLY ALIGN FOLLOWING CODE WITH A PAGE VOUNDARY.
; IT WILL USUALLY BE USED AT THE TOP OF TABLES, SO THAT A TABLE WON'T
; CROSS A BOUNDARY AND FUCK UP A KERNEL.
;
.MACRO PALIGN
.=<.+0FF>&0FF00
.ENDM
;
;
; .INTSET ENABLES INTERRUPTS WHEN IN A RAM VERSION, BUT ALLOWS INTERRUPTS
; TO BE DISABLED IN THE ROMMED VERSION, BY THE USE OF THE TERM ZZZROM.
; AS LONG AS ZZZROM IS UNDEFINED, INTERRUPTS WILL BE ENABLED, AND A
; PROGRAM CAN BE HALTED BY CONTROL-C. BEFORE ROMMING THE PROGRAM, MERELY
; INSERT A DEFINITION FOR ZZZROM, SUCH AS ZZZROM = 1.
;
.MACRO .INTSET
.IF NDF,ZZZROM
CLI
.IFF
SEI
.ENDC
.ENDM
;
;
; LINE WILL DECREMENT THE LINE COUNT, IF REQUESTED, WILL SET UP A
; PLAYER, IF REQUESTED, AND WILL SET UP A MISSILE OR BALL DURING A
; KERNEL LINE. THE LINE COUNT MAY BE DECREMENTED BY ANY VALUE, SET
; AS ARGUMENT A1. IF A1 IS ZERO, THAT PART OF THE CODE IS NOT
; ASSEMBLED. ARGUMENT A2 SPECIFIES THE VERTICAL POSITION OF THE
; PLAYER, BY NAME OF RAM POSITION WHERE THAT VALUE IS LOCATED. IF
; THAT ARGUMENT IS SET TO ZERO, THE CODE FOR HANDLING THE PLAYER
; IS LEFT OUT.
;
; THERE ARE EIGHT ARGUMENTS, BUT A8 MUST NOT BE SPECIFIED WHEN
; INVOKING THE MACRO. IT IS A DUMMY FOR CREATING A JUMP ADDRESS.
; THE OTHERS MUST BE USED, AT LEAST TO THE POINT OF PUTTING IN A
; COMMA AS A PLACE-HOLDER. THE ARGUMENTS AND THEIR MEANINGS ARE:
;
; A1 LINE COUNT DECREMENT AMOUNT (USUALLY 1 OR 2; IF 0, CODE IS
; SKIPPED)
; A2 NAME OF RAM LOCATION FOR VERT. POSITION OF A PLAYER. IF 0,
; CODE FOR PLAYER SETUP IS LEFT OUT
; A3 PLAYER'S HEIGHT
; A4 NAME OF PLAYER'S GRAPHICS TABLE
; A5 NAME OF A TEMPORARY STORAGE LOCATION FOR THAT PLAYER'S GRAPHICS
; A6 NAME OF LOCATION FOR MISSILE'S OR BALL'S VERTICAL POSITION
; A7 HEIGHT OF MISSILE OR BALL
; A8 DUMMY JUMP ADDRESS -- DON'T PUT A VALUE IN FOR THIS ARGUMENT!!!
;
; AN EXAMPLE FOR THE FIRST LINE OF A DOUBLE-LINE KERNEL MIGHT BE:
;
; LINE 2,VP0,8,P0TAB,GP0,VM0,14.
;
; THE SECOND LINE OF THE KERNEL MIGHT LOOK LIKE:
;
; LINE 0,VP1,10.,P1TAB,GP1,VBL,4
;
; A LINE WITH NO PLAYER MIGHT BE CALLED AS FOLLOWS:
;
; LINE 1,0,,,,VM1,6
;
; NOTE THAT ALL NUMERIC VALUES ARE IN HEX, AND DECIMAL VALUES MUST END
; WITH A DOT. THIS MACRO USES THE ACCUMULATOR AND Y REGISTER, BUT LEAVES
; THE X REGISTER FREE.
;
; THE RESULTS OF THIS MACRO MUST BE INVOKED AT THE START OF THE NEXT LINE,
; PROBABLY IMMEDIATELY AFTER AT STA WSYNC, OR AFTER STA WSYNC, STA HMOVE.
; IF THE PLAYER GRAPHICS HAS BEEN STORED IN GP1, FOR INSTANCE, AND YOU
; ARE ABOUT TO PUT UP THAT PLAYER AND THE BALL, AS IN THE SECOND EXAMPLE
; ABOVE, YOU WOULD PUT IN CODE:
; STY ENABL
; LDY GP1
; STY GRP1
; AND THEN CONTINUE WITH REST OF CODE FOR THAT LINE. THERE SHOULD BE
; ENOUGH TIME TO GET A PLAYFIELD STARTED, BUT DON'T DECREMENT LINE
; COUNTS WHERE THERE WILL BE NEW PLAYFIELD. THERE ISN'T ENOUGH TIME.
; PUT A 0 IN A1 FOR THOSE LINES, IN A TWO-LINE KERNEL, AND PUT A 2 IN
; A1 ON THE NEXT LINE, WHERE THERE WILL BE MORE TIME.
;
; THE ROUTINE WALKS DOWN THROUGH THE PLAYER GRAPHICS TABLE AS IT MOVES
; DOWN THE SCREEN, SO THE FIRST VALUE OF THE TABLE SHOULD BE 0, TO SET
; THAT VALUE INTO THE GRAPHICS STORE LOCATION WHEN THE PLAYER ISN'T TO
; APPEAR.
;
.MACRO LINE A1,A2,A3,A4,A5,A6,A7,?A8
.IF NE,A2
LDA A2
SEC
SBC LNCNT
CMP #A3
BCS A8
TAY
LDA A4(Y)
STA A5
.ENDC
A8: LDY #0
LDA LNCNT
SEC
.IF NE,A1
SBC #A1
STA LNCNT
.ENDC
SBC A6
CMP #-A7
BCC .+4
LDY #2
.ENDM
;
;
.nlist
.sbttl Initialization
.list
.page
; *
; **
;********** ******************
;*********** * Initialization *
;********** ******************
; **
; *


.=romstr
init: sei ;disable interrupts
cld ;binary arithmetic
ldx #0
txa
sta ctlswa ;set porta for input
10$: sta 0(x) ;clear hardware registers and ram
inx
bne 10$
dex ;ff
stx gflg1 ;set select mode flag
txs ;init stack ptr
;
; Perform a Game Select, Game # 1
;
jsr initsl ;simulate select lever press
;
; End of Initialization
;
jmp oversc ;go start with overscan
.nlist
.sbttl video kernel
.list
.page
; *
; **
;********** ****************
;*********** * Video Kernel *
;********** ****************
; **
; *


kernel: sta wsync ;0
lda #82 ;2 load background color
eor atim ;5 comp for attract mode
and #0f7 ;7
sta colubk ;10
ldx #180. ;12 load number of lines
10$: sta wsync ;0 finish the line
dex ;2 done?
bne 10$ ;4,5 no, go
lda gflg1 ;7 are we in select mode?
and #10 ;9
bne copy ;11,12 yes, go do copyright notice
ldx #11. ;13 load number of lines
20$: sta wsync ;0 end the line
dex ;2 done?
bne 20$ ;4,5 no, go
jmp oversc ;7 yes, exit
;
; Display Copyright Notice
;
copy: sta wsync ;0 sync up
stx pf0 ;3 clear playfield regs
stx pf1 ;6
stx pf2 ;9
nop ;11 waste some cycles
sta t0 ;14 waste some more
lda bcol ;17 set up player color
eor atim ;20 adjust for attract colors
and atmask ;23 ensure low lum if attract colors
sta colup0 ;26
sta colup1 ;29
nop ;31 waste 2 cycles here
lda #0f0 ;33 set up fine positioning in advance
sta hmp0 ;36
ldx #0 ;38
stx hmp1 ;41
sta resp0 ;44 reset player zero...
sta resp1 ;47 ...and player one
sta wsync ;0
sta hmove ;3 execute fine adjustment
lda #0cb ;5 set nusiz for small players
sta nusiz0 ;8 and proper number of copies
ldx #1 ;10
stx nusiz1 ;13
; do display
ldx #07 ;15 for 8 lines of the screen...
1$: stx t1 ;18,66 save index because x is used later
sta wsync ;0
ldy #2 ;2 time out to center of screen
dey ;4;9
bne .-1 ;7;11
sta t0 ;14 waste 3 cycles to get timing right
lda col1-1(x) ;18 get graphics for first store
sta grp0 ;21 store it
lda col2-1(x) ;25 same for p1
sta grp1 ;28
ldy col3-1(x) ;32 now get tricky to save time...
lda col4-1(x) ;36 use X and Y and A to their fullest
sta t0 ;39 use temp 0 also for time savings
lda col5-1(x) ;43 now load up all 3 regs
ldx t0 ;46
sty grp0 ;49 and store 'em as fast as possible
stx grp1 ;52 (timing is very crucial here)
sta grp0 ;55
ldx t1 ;58 now restore index
dex ;60
bne 1$ ;62,63 and branch back till done
stx grp0 ;65 clear player graphics for neatness
stx grp1 ;68
sta wsync ;0 display two blank lines
sta wsync ;0 (bottom margin)
jmp oversc
;
; End of Kernel
;
.nlist
.sbttl Overscan
.list
.page
; *
; **
;********** ***************************
;*********** * Overscan: 30 Scan Lines *
;********** ***************************
; **
; *


;
; Tie Up Screen Loose Ends
;
oversc: ldx #0
stx colubk ;turn off background
lda #ovrcon ;set up overscan timer
sta tim64t
lda #82 ;turn on vblank, ground the pots
sta vblank
;
; Update Frame Counter
;
inc frame
bne 10$ ;go if no overflow
inc hfram
lda #30 ;time to go into attract?
cmp hfram
bne 10$ ;no, go
lda gflg1 ;yes, set the flag
ora #08
sta gflg1
10$:
;
; Check For Reset/Game Select
;
jsr gsrst ;check levers...
bcs 99$ ;if lever was pressed...
jmp intst ;skip game play this frame
99$:
;
;
;********************************************
; put overscan calcs here *
;********************************************
;
;
;
; End of Overscan
;
intst: ldx intim ;overscan done yet?
bne intst ;no, go back
vsnc: ldx #02 ;yes, do vsync
stx vsync
sta wsync ;send 4 lines of vsync
sta wsync
sta wsync
sta wsync
lda #0
sta vsync ;turn off vsync (a=0)
.nlist
.sbttl Vblank Calculations
.list
.page
; *
; **
;********** *************************
;*********** * Vblank: 37 Scan Lines *
;********** *************************
; **
; *


;
; Start Vblank Timer
;
vblnk: lda #vblcon ;set up vblank timer
sta tim64t
;
;
;********************************************
; put vblank calcs here *
;********************************************
;
;
; Color-Shift Attract Mode
;
shft: ldy #0ff ;assume no attract mask
lda gflg1 ;are we in color attract?
and #08
bne 5$ ;yes, go
sta atim ;no, reset attract shift key to zero
beq 99$ ;always taken
5$: ldy #0f7 ;load attract mask
lda frame ;is it time to shift?
bne 99$ ;no, go
inc atim ;set new color-shift mask
99$: sty atmask ;store current lum mask
;
; End of Vblank
;
intst2: lda intim ;done with vblank yet?
bne intst2 ;no, go back
sta wsync ;yes, get ready for kernel
sta vblank ;turn off vblank, and start charging pots
sta hmclr ;reset horiz. motion regs to 0
sta cxclr ;clear collisions
jmp kernel ;go for it
.nlist
.sbttl Game Reset/Select
.list
.page
; *
; **
;********** ******************************
;*********** * Game Select and Game Reset *
;********** ******************************
; **
; *


; Check to see if game select or game reset levers are being
; pressed. If yes, then check to see if time-out has occurred. If
; yes, then execute the function. Otherwise return with carry set,
; indicating that no action was taken. If game select or reset did
; take place, return with carry clear, so that the overscan calcs will
; be skipped (reset or select usually takes a long time to do).
gsrst: lda swchb ;read console switches
ror
bcc grs ;go if reset lever pressed
gs2: ror
bcc gsel ;go if game select lever pressed
ldx #1
stx gstim
gsex: sec
rts ;rts with carry set means no action
;
; Game Select
gsel: dec gstim ;time to execute?
bne gsex ;no, go
initsl: lda #2d ;reset timer
sta gstim
lda gflg1 ;are we in select mode?
and #10
beq 12$ ;no, don't inc game number
sed ;new game number
lda gamno
clc
adc #1 ;add 1 to old number
cmp #gmax ;too high?
bne 10$ ;no, skip reset
lda #1 ;yes, reset to 1
10$: sta gamno
cld ;restore binary functioning
;***************************************
; put game select logic here *
;***************************************
12$: ldx gamno ;set gflg1 from table
lda gf1sel-1(x)
sta gflg1
bne gsrs ;always taken
;
; Game Reset
grs: dec gstim ;time to execute?
bne gsex ;no, exit
ldx #10 ;reset timer
stx gstim
ldx gamno ;set gflg1 from table
lda gf1rst-1(x)
sta gflg1
;**************************************
; put game reset logic here *
;**************************************
ldx #0 ;reset scores
stx tscr
stx tscr+1
stx bscr
stx bscr+1
;
; Both Functions
gsrs: lda #05 ;set up hardware
sta nusiz0
sta nusiz1
lda #21
sta ctrlpf
lda #4
sta audc0
sta cxclr
lda #0
sta hfram ;turn off color attract
ldx #1 ;set up screen colors
20$: lda misc(x)
sta tcol(x)
dex
bpl 20$
99$: clc ;return with clear carry
rts
.nlist
.sbttl Assorted Subroutines
.list
.page
; *
; **
;********** ************************
;*********** * Assorted Subroutines *
;********** ************************
; **
; *


;
; "Random" Number Routine
;
; Returns a "random" number in the accumulator. If it doesn't
; seem very random try playing around with the base address of the first
; two exclusive or's... find very varied pieces of your program to use,
; and it should return very unpredictable results. Another trick is to
; somehow do an eor with your game controllers... this is about
; as random as data can get, and usually makes a difference.
rndno: lda rand ;get seed (last number)
ldx rndind ;and index
eor oversc(x) ;"randomize"
eor kernel(x)
asl ;rotate to avoid single-bit
adc #0 ;state preferences
inx
stx rndind ;save new index
eor hfram ;and use frame counter for
eor frame ;long repeat time
sta rand ;save new seed
rts ;exit
;
; Score Addition Routine
;
; Adds value found in accumulator to the player whose offset is in
; y-reg. Keep in mind that player zero should be y-reg = 0 and player
; one should be y-reg = 2. Also, remember the amount to add (in the acc.)
; should be a decimal number. This routine allows four decimal digits
; of score for each player.
adscr: sed ;add to score of a player
clc
adc tscr+1(y)
sta tscr+1(y)
txa
adc tscr(y)
sta tscr(y)
cld
rts
.nlist
.sbttl Tables
.list
.page
; *
; **
;********** **********************
;*********** * Relocatable Tables *
;********** **********************
; **
; *


misc: .byte 7c,46 ;misc information for initialization
;
; Frcmov is a table used for smooth movement of objects at
; fractional speeds. To use it, assume speed byte is xxxx.xxxx
; (in pixels per frame) and do the following:
; lda #0 ;init number of pixels to move to 0
; sta t0
; lda frame ;get frame number
; and #0f ;use only low nybble
; tay ;index into frcmov
; lda frcmov(y) ;get table value
; and speed ;time to let fractional speed overflow
; ;into a pixel movement?
; beq 10$ ;no, skip it
; inc t0 ;yes, t0 is now 1
;10$: lda speed ;get speed again
; lsr ;shift out fractional portion
; lsr
; lsr
; lsr
; clc ;add to overflow from fractional part
; adc t0
;
; accumulator now contains the number of pixels to move this frame.
frcmov: .byte 1,8,4,8,2,8,4,8,0,8,4,8,2,8,4,8
gf1rst: .byte 0a0,80 ;gflg1 values after game reset
gf1sel: .byte 30,10 ;gflg1 values after game select
;
; copyright notice graphics tables
col1: .byte 79,85,0b5,0a5,0b5,85,79
col2: .byte 17,15,15,77,55,55,77
col3: .byte 71,41,41,71,11,11,70
col4: .byte 49,49,49,0c9,49,49,0be
col5: .byte 55,55,55,0d9,55,55,99
.page
; *
; **
;********** *******************************
;*********** * Fixed (Page-aligned) Tables *
;********** *******************************
; **
; *


PALIGN
;
; Hmvtab contains reset counts and hmove values for objects on the
; screen. To use it, do the following (this example positions the ball):
;
; lda posn ;get horizontal position of ball
; sta wsync ;0 sync up for reset line
; tax ;2 index into hmvtab
; lda hmvtab(x) ;6 get table value
; sta hmbl ;9 set hmove value from high nybble
; and #0f ;11 keep low nybble for time loop
; tay ;13 tfr to y for loop
; nop ;15 waste 2 cycles
; dey ;17;22 etc. timing loop
; bpl .-1 ;20;25 etc.
; sta resbl ;set the ball's position right here
; sta wsync ;finish the line
; sta hmove ;execute the fine positioning hmove
;
; remember, hmvtab must not cross a page boundary, because if it does
; it could cause the instruction "lda hmvtab(x)" to take 5 cycles instead of
; 4, and that would throw off the timing of the reset line.
hmvtab: .byte 60,50,40,30,20,10,00,0f0,0e0,0d0,0c0,0b0,0a0,90
.byte 71,61,51,41,31,21,11,01,0f1,0e1,0d1,0c1,0b1,0a1,91
.byte 72,62,52,42,32,22,12,02,0f2,0e2,0d2,0c2,0b2,0a2,92
.byte 73,63,53,43,33,23,13,03,0f3,0e3,0d3,0c3,0b3,0a3,93
.byte 74,64,54,44,34,24,14,04,0f4,0e4,0d4,0c4,0b4,0a4,94
.byte 75,65,55,45,35,25,15,05,0f5,0e5,0d5,0c5,0b5,0a5,95
.byte 76,66,56,46,36,26,16,06,0f6,0e6,0d6,0c6,0b6,0a6,96
.byte 77,67,57,47,37,27,17,07,0f7,0e7,0d7,0c7,0b7,0a7,97
.byte 78,68,58,48,38,28,18,08,0f8,0e8,0d8,0c8,0b8,0a8,98
.byte 79,69,59,49,39,29,19,09,0f9,0e9,0d9,0c9
;
; End of Memory
;
.=0fffc
.word init ;start vector
.word init
.end

#2 Cybergoth OFFLINE  

Cybergoth

    Quadrunner

  • 8,796 posts
  • This is Sparta!
  • Location:Bavaria

Posted Sun Sep 11, 2005 2:28 AM

Hi there!

; .INTSET ENABLES INTERRUPTS WHEN IN A RAM VERSION, BUT ALLOWS INTERRUPTS
; TO BE DISABLED IN THE ROMMED VERSION, BY THE USE OF THE TERM ZZZROM.
; AS LONG AS ZZZROM IS UNDEFINED, INTERRUPTS WILL BE ENABLED, AND A
; PROGRAM CAN BE HALTED BY CONTROL-C.  BEFORE ROMMING THE PROGRAM, MERELY
; INSERT A DEFINITION FOR ZZZROM, SUCH AS ZZZROM = 1.


:-o :-o :-o

Greetings,
Manuel

#3 Cybergoth OFFLINE  

Cybergoth

    Quadrunner

  • 8,796 posts
  • This is Sparta!
  • Location:Bavaria

Posted Sun Sep 11, 2005 2:57 AM

Hi there!

Uihjah...

Skeleton = 4K-Template

Phew... and I thought this were some parts of an unfinished game... :twisted:

Anyway, DASM'd:


; VCS SKELETON PROGRAM
; COPYRIGHT ATARI, 1982

    PROCESSOR 6502
    INCLUDE VCS.H

; *
; **
;********** ********************
;*********** * ASSORTED EQUATES *
;********** ********************
; **
; *

GSCON   = 45;GAME SELECT TIMER INITIAL VALUE
OVRCON  = $25;OVERSCAN TIMER INITIAL VALUE
VBLCON  = $2B;VBLANK TIMER INITIAL VALUE
GMAX    = $03;HIGHEST GAME # +1

; *
; **
;********** *****************************
;*********** * VARIABLES (RAM PAGE ZERO) *
;********** *****************************
; **
; *

    SEG.U VARS
    ORG $80

TCOL    DS 1   ;TOP SCORE COLOR
BCOL    DS 1   ;BOTTOM SCORE COLOR
GFLG1   DS 1   ;GAME STATUS BITS
               ;80 1= GAME IS IN PLAY
               ;40 1= BONZO (EASY) GAME
               ;20 1= ONE-PLAYER GAME
               ;10 1= SELECT MODE
               ;08 1= COLOR-SHIFTING ATTRACT MODE
               ;04 NOT USED YET
               ;02 NOT USED YET
               ;01 NOT USED YET
GAMNO   DS 1   ;GAME NUMBER (DECIMAL)
GSTIM   DS 1   ;GAME SELECT TIMER
TSCR    DS 2   ;TOP PLAYER'S SCORE
BSCR    DS 2   ;BOTTOM PLAYER'S SCORE
RAND    DS 1   ;"RANDOM" NUMBER SEED/LAST NUMBER
RNDIND  DS 1   ;"RANDOM" NUMBER INDEX
FRAME   DS 1   ;FRAME COUNTER
HFRAM   DS 1   ;HI BYTE OF FRAME COUNTER
ATIM    DS 1   ;ATTRACT TIMER
ATMASK  DS 1   ;ATTRACT LUM MASK
T0      DS 1   ;TEMPORARY VARIABLES
T1      DS 1

;; *
;; **
;;********** ******************
;;*********** * MACROS *
;;********** ******************
;; **
;; *
;;
;; PALIGN WILL AUTOMATICALLY ALIGN FOLLOWING CODE WITH A PAGE VOUNDARY.
;; IT WILL USUALLY BE USED AT THE TOP OF TABLES, SO THAT A TABLE WON'T
;; CROSS A BOUNDARY AND FUCK UP A KERNEL.
;;
;.MACRO PALIGN
;.=<.+0FF>&0FF00
;.ENDM
;;
;;
;; .INTSET ENABLES INTERRUPTS WHEN IN A RAM VERSION, BUT ALLOWS INTERRUPTS
;; TO BE DISABLED IN THE ROMMED VERSION, BY THE USE OF THE TERM ZZZROM.
;; AS LONG AS ZZZROM IS UNDEFINED, INTERRUPTS WILL BE ENABLED, AND A
;; PROGRAM CAN BE HALTED BY CONTROL-C. BEFORE ROMMING THE PROGRAM, MERELY
;; INSERT A DEFINITION FOR ZZZROM, SUCH AS ZZZROM = 1.
;;
;.MACRO .INTSET
;.IF NDF,ZZZROM
;CLI
;.IFF
;SEI
;.ENDC
;.ENDM
;;
;;
;; LINE WILL DECREMENT THE LINE COUNT, IF REQUESTED, WILL SET UP A
;; PLAYER, IF REQUESTED, AND WILL SET UP A MISSILE OR BALL DURING A
;; KERNEL LINE. THE LINE COUNT MAY BE DECREMENTED BY ANY VALUE, SET
;; AS ARGUMENT A1. IF A1 IS ZERO, THAT PART OF THE CODE IS NOT
;; ASSEMBLED. ARGUMENT A2 SPECIFIES THE VERTICAL POSITION OF THE
;; PLAYER, BY NAME OF RAM POSITION WHERE THAT VALUE IS LOCATED. IF
;; THAT ARGUMENT IS SET TO ZERO, THE CODE FOR HANDLING THE PLAYER
;; IS LEFT OUT.
;;
;; THERE ARE EIGHT ARGUMENTS, BUT A8 MUST NOT BE SPECIFIED WHEN
;; INVOKING THE MACRO. IT IS A DUMMY FOR CREATING A JUMP ADDRESS.
;; THE OTHERS MUST BE USED, AT LEAST TO THE POINT OF PUTTING IN A
;; COMMA AS A PLACE-HOLDER. THE ARGUMENTS AND THEIR MEANINGS ARE:
;;
;; A1 LINE COUNT DECREMENT AMOUNT (USUALLY 1 OR 2; IF 0, CODE IS
;; SKIPPED)
;; A2 NAME OF RAM LOCATION FOR VERT. POSITION OF A PLAYER. IF 0,
;; CODE FOR PLAYER SETUP IS LEFT OUT
;; A3 PLAYER'S HEIGHT
;; A4 NAME OF PLAYER'S GRAPHICS TABLE
;; A5 NAME OF A TEMPORARY STORAGE LOCATION FOR THAT PLAYER'S GRAPHICS
;; A6 NAME OF LOCATION FOR MISSILE'S OR BALL'S VERTICAL POSITION
;; A7 HEIGHT OF MISSILE OR BALL
;; A8 DUMMY JUMP ADDRESS -- DON'T PUT A VALUE IN FOR THIS ARGUMENT!!!
;;
;; AN EXAMPLE FOR THE FIRST LINE OF A DOUBLE-LINE KERNEL MIGHT BE:
;;
;; LINE 2,VP0,8,P0TAB,GP0,VM0,14.
;;
;; THE SECOND LINE OF THE KERNEL MIGHT LOOK LIKE:
;;
;; LINE 0,VP1,10.,P1TAB,GP1,VBL,4
;;
;; A LINE WITH NO PLAYER MIGHT BE CALLED AS FOLLOWS:
;;
;; LINE 1,0,,,,VM1,6
;;
;; NOTE THAT ALL NUMERIC VALUES ARE IN HEX, AND DECIMAL VALUES MUST END
;; WITH A DOT. THIS MACRO USES THE ACCUMULATOR AND Y REGISTER, BUT LEAVES
;; THE X REGISTER FREE.
;;
;; THE RESULTS OF THIS MACRO MUST BE INVOKED AT THE START OF THE NEXT LINE,
;; PROBABLY IMMEDIATELY AFTER AT STA WSYNC, OR AFTER STA WSYNC, STA HMOVE.
;; IF THE PLAYER GRAPHICS HAS BEEN STORED IN GP1, FOR INSTANCE, AND YOU
;; ARE ABOUT TO PUT UP THAT PLAYER AND THE BALL, AS IN THE SECOND EXAMPLE
;; ABOVE, YOU WOULD PUT IN CODE:
;; STY ENABL
;; LDY GP1
;; STY GRP1
;; AND THEN CONTINUE WITH REST OF CODE FOR THAT LINE. THERE SHOULD BE
;; ENOUGH TIME TO GET A PLAYFIELD STARTED, BUT DON'T DECREMENT LINE
;; COUNTS WHERE THERE WILL BE NEW PLAYFIELD. THERE ISN'T ENOUGH TIME.
;; PUT A 0 IN A1 FOR THOSE LINES, IN A TWO-LINE KERNEL, AND PUT A 2 IN
;; A1 ON THE NEXT LINE, WHERE THERE WILL BE MORE TIME.
;;
;; THE ROUTINE WALKS DOWN THROUGH THE PLAYER GRAPHICS TABLE AS IT MOVES
;; DOWN THE SCREEN, SO THE FIRST VALUE OF THE TABLE SHOULD BE 0, TO SET
;; THAT VALUE INTO THE GRAPHICS STORE LOCATION WHEN THE PLAYER ISN'T TO
;; APPEAR.
;;
;.MACRO LINE A1,A2,A3,A4,A5,A6,A7,?A8
;.IF NE,A2
;LDA A2
;SEC
;SBC LNCNT
;CMP #A3
;BCS A8
;TAY
;LDA A4(Y)
;STA A5
;.ENDC
;A8: LDY #0
;LDA LNCNT
;SEC
;.IF NE,A1
;SBC #A1
;STA LNCNT
;.ENDC
;SBC A6
;CMP #-A7
;BCC .+4
;LDY #2
;.ENDM
;;

; *
; **
;********** ******************
;*********** * INITIALIZATION *
;********** ******************
; **
; *


    SEG Bank0
    ORG $F000
START
    SEI;DISABLE INTERRUPTS
    CLD;BINARY ARITHMETIC
    LDX #0
    TXA
    STA SWACNT;SET PORTA FOR INPUT
10$: STA 0,X;CLEAR HARDWARE REGISTERS AND RAM
    INX
    BNE 10$
    DEX;FF
    STX GFLG1;SET SELECT MODE FLAG
    TXS;INIT STACK PTR
;
; PERFORM A GAME SELECT, GAME # 1
;
    JSR INITSL;SIMULATE SELECT LEVER PRESS
;
; END OF INITIALIZATION
;
    JMP OVERSC;GO START WITH OVERSCAN

; *
; **
;********** ****************
;*********** * VIDEO KERNEL *
;********** ****************
; **
; *


KERNEL: STA WSYNC;0
    LDA #$82;2 LOAD BACKGROUND COLOR
    EOR ATIM;5 COMP FOR ATTRACT MODE
    AND #$F7;7
    STA COLUBK;10
    LDX #180;12 LOAD NUMBER OF LINES
10$: STA WSYNC;0 FINISH THE LINE
    DEX;2 DONE?
    BNE 10$;4,5 NO, GO
    LDA GFLG1;7 ARE WE IN SELECT MODE?
    AND #$10;9
    BNE COPY;11,12 YES, GO DO COPYRIGHT NOTICE
    LDX #$11;13 LOAD NUMBER OF LINES
20$: STA WSYNC;0 END THE LINE
    DEX;2 DONE?
    BNE 20$;4,5 NO, GO
    JMP OVERSC;7 YES, EXIT
;
; DISPLAY COPYRIGHT NOTICE
;
COPY: STA WSYNC;0 SYNC UP
    STX PF0;3 CLEAR PLAYFIELD REGS
    STX PF1;6
    STX PF2;9
    NOP;11 WASTE SOME CYCLES
    STA T0;14 WASTE SOME MORE
    LDA BCOL;17 SET UP PLAYER COLOR
    EOR ATIM;20 ADJUST FOR ATTRACT COLORS
    AND ATMASK;23 ENSURE LOW LUM IF ATTRACT COLORS
    STA COLUP0;26
    STA COLUP1;29
    NOP;31 WASTE 2 CYCLES HERE
    LDA #$F0;33 SET UP FINE POSITIONING IN ADVANCE
    STA HMP0;36
    LDX #0;38
    STX HMP1;41
    STA RESP0;44 RESET PLAYER ZERO...
    STA RESP1;47 ...AND PLAYER ONE
    STA WSYNC;0
    STA HMOVE;3 EXECUTE FINE ADJUSTMENT
    LDA #$CB;5 SET NUSIZ FOR SMALL PLAYERS
    STA NUSIZ0;8 AND PROPER NUMBER OF COPIES
    LDX #1;10
    STX NUSIZ1;13
; DO DISPLAY
    LDX #$07;15 FOR 8 LINES OF THE SCREEN...
1$: STX T1;18,66 SAVE INDEX BECAUSE X IS USED LATER
    STA WSYNC;0
    LDY #2;2 TIME OUT TO CENTER OF SCREEN
    DEY;4;9
    BNE .-1;7;11
    STA T0;14 WASTE 3 CYCLES TO GET TIMING RIGHT
    LDA COL1-1,X;18 GET GRAPHICS FOR FIRST STORE
    STA GRP0;21 STORE IT
    LDA COL2-1,X;25 SAME FOR P1
    STA GRP1;28
    LDY COL3-1,X;32 NOW GET TRICKY TO SAVE TIME...
    LDA COL4-1,X;36 USE X AND Y AND A TO THEIR FULLEST
    STA T0;39 USE TEMP 0 ALSO FOR TIME SAVINGS
    LDA COL5-1,X;43 NOW LOAD UP ALL 3 REGS
    LDX T0;46
    STY GRP0;49 AND STORE 'EM AS FAST AS POSSIBLE
    STX GRP1;52 (TIMING IS VERY CRUCIAL HERE)
    STA GRP0;55
    LDX T1;58 NOW RESTORE INDEX
    DEX;60
    BNE 1$;62,63 AND BRANCH BACK TILL DONE
    STX GRP0;65 CLEAR PLAYER GRAPHICS FOR NEATNESS
    STX GRP1;68
    STA WSYNC;0 DISPLAY TWO BLANK LINES
    STA WSYNC;0 (BOTTOM MARGIN)
    JMP OVERSC
;
; END OF KERNEL
;

; *
; **
;********** ***************************
;*********** * OVERSCAN: 30 SCAN LINES *
;********** ***************************
; **
; *


;
; TIE UP SCREEN LOOSE ENDS
;
OVERSC: LDX #0
    STX COLUBK;TURN OFF BACKGROUND
    LDA #OVRCON;SET UP OVERSCAN TIMER
    STA TIM64T
    LDA #$82;TURN ON VBLANK, GROUND THE POTS
    STA VBLANK
;
; UPDATE FRAME COUNTER
;
    INC FRAME
    BNE 10$;GO IF NO OVERFLOW
    INC HFRAM
    LDA #$30;TIME TO GO INTO ATTRACT?
    CMP HFRAM
    BNE 10$;NO, GO
    LDA GFLG1;YES, SET THE FLAG
    ORA #$08
    STA GFLG1
10$:
;
; CHECK FOR RESET/GAME SELECT
;
    JSR GSRST;CHECK LEVERS...
    BCS 99$;IF LEVER WAS PRESSED...
    JMP INTST;SKIP GAME PLAY THIS FRAME
99$:
;
;
;********************************************
; PUT OVERSCAN CALCS HERE *
;********************************************
;
;
;
; END OF OVERSCAN
;
INTST:
    LDX INTIM;OVERSCAN DONE YET?
    BNE INTST;NO, GO BACK
VSNC: LDX #$02;YES, DO VSYNC
    STX VSYNC
    STA WSYNC;SEND 4 LINES OF VSYNC
    STA WSYNC
    STA WSYNC
    STA WSYNC
    LDA #0
    STA VSYNC;TURN OFF VSYNC (A=0)

; *
; **
;********** *************************
;*********** * VBLANK: 37 SCAN LINES *
;********** *************************
; **
; *


;
; START VBLANK TIMER
;
VBLNK: LDA #VBLCON;SET UP VBLANK TIMER
    STA TIM64T
;
;
;********************************************
; PUT VBLANK CALCS HERE *
;********************************************
;
;
; COLOR-SHIFT ATTRACT MODE
;
SHFT: LDY #$FF;ASSUME NO ATTRACT MASK
    LDA GFLG1;ARE WE IN COLOR ATTRACT?
    AND #$08
    BNE 5$;YES, GO
    STA ATIM;NO, RESET ATTRACT SHIFT KEY TO ZERO
    BEQ 99$;ALWAYS TAKEN
5$: LDY #$F7;LOAD ATTRACT MASK
    LDA FRAME;IS IT TIME TO SHIFT?
    BNE 99$;NO, GO
    INC ATIM;SET NEW COLOR-SHIFT MASK
99$: STY ATMASK;STORE CURRENT LUM MASK
;
; END OF VBLANK
;
INTST2:
    LDA INTIM;DONE WITH VBLANK YET?
    BNE INTST2;NO, GO BACK
    STA WSYNC;YES, GET READY FOR KERNEL
    STA VBLANK;TURN OFF VBLANK, AND START CHARGING POTS
    STA HMCLR;RESET HORIZ. MOTION REGS TO 0
    STA CXCLR;CLEAR COLLISIONS
    JMP KERNEL;GO FOR IT

; *
; **
;********** ******************************
;*********** * GAME SELECT AND GAME RESET *
;********** ******************************
; **
; *


; CHECK TO SEE IF GAME SELECT OR GAME RESET LEVERS ARE BEING
; PRESSED. IF YES, THEN CHECK TO SEE IF TIME-OUT HAS OCCURRED. IF
; YES, THEN EXECUTE THE FUNCTION. OTHERWISE RETURN WITH CARRY SET,
; INDICATING THAT NO ACTION WAS TAKEN. IF GAME SELECT OR RESET DID
; TAKE PLACE, RETURN WITH CARRY CLEAR, SO THAT THE OVERSCAN CALCS WILL
; BE SKIPPED (RESET OR SELECT USUALLY TAKES A LONG TIME TO DO).
GSRST: LDA SWCHB;READ CONSOLE SWITCHES
    ROR
    BCC GRS;GO IF RESET LEVER PRESSED
GS2: ROR
    BCC GSEL;GO IF GAME SELECT LEVER PRESSED
    LDX #1
    STX GSTIM
GSEX: SEC
    RTS;RTS WITH CARRY SET MEANS NO ACTION
;
; GAME SELECT
GSEL: DEC GSTIM;TIME TO EXECUTE?
    BNE GSEX;NO, GO
INITSL: LDA #$2D;RESET TIMER
    STA GSTIM
    LDA GFLG1;ARE WE IN SELECT MODE?
    AND #$10
    BEQ 12$;NO, DON'T INC GAME NUMBER
    SED;NEW GAME NUMBER
    LDA GAMNO
    CLC
    ADC #1;ADD 1 TO OLD NUMBER
    CMP #GMAX;TOO HIGH?
    BNE 10$;NO, SKIP RESET
    LDA #1;YES, RESET TO 1
10$: STA GAMNO
    CLD;RESTORE BINARY FUNCTIONING
;***************************************
; PUT GAME SELECT LOGIC HERE *
;***************************************
12$: LDX GAMNO;SET GFLG1 FROM TABLE
    LDA GF1SEL-1,X
    STA GFLG1
    BNE GSRS;ALWAYS TAKEN
;
; GAME RESET
GRS: DEC GSTIM;TIME TO EXECUTE?
    BNE GSEX;NO, EXIT
    LDX #$10;RESET TIMER
    STX GSTIM
    LDX GAMNO;SET GFLG1 FROM TABLE
    LDA GF1RST-1,X
    STA GFLG1
;**************************************
; PUT GAME RESET LOGIC HERE *
;**************************************
    LDX #0;RESET SCORES
    STX TSCR
    STX TSCR+1
    STX BSCR
    STX BSCR+1
;
; BOTH FUNCTIONS
GSRS: LDA #$05;SET UP HARDWARE
    STA NUSIZ0
    STA NUSIZ1
    LDA #$21
    STA CTRLPF
    LDA #4
    STA AUDC0
    STA CXCLR
    LDA #0
    STA HFRAM;TURN OFF COLOR ATTRACT
    LDX #1;SET UP SCREEN COLORS
20$: LDA MISC,X
    STA TCOL,X
    DEX
    BPL 20$
99$: CLC;RETURN WITH CLEAR CARRY
    RTS

; *
; **
;********** ************************
;*********** * ASSORTED SUBROUTINES *
;********** ************************
; **
; *


;
; "RANDOM" NUMBER ROUTINE
;
; RETURNS A "RANDOM" NUMBER IN THE ACCUMULATOR. IF IT DOESN'T
; SEEM VERY RANDOM TRY PLAYING AROUND WITH THE BASE ADDRESS OF THE FIRST
; TWO EXCLUSIVE OR'S... FIND VERY VARIED PIECES OF YOUR PROGRAM TO USE,
; AND IT SHOULD RETURN VERY UNPREDICTABLE RESULTS. ANOTHER TRICK IS TO
; SOMEHOW DO AN EOR WITH YOUR GAME CONTROLLERS... THIS IS ABOUT
; AS RANDOM AS DATA CAN GET, AND USUALLY MAKES A DIFFERENCE.
RNDNO: LDA RAND;GET SEED (LAST NUMBER)
    LDX RNDIND;AND INDEX
    EOR OVERSC,X;"RANDOMIZE"
    EOR KERNEL,X
    ASL;ROTATE TO AVOID SINGLE-BIT
    ADC #0;STATE PREFERENCES
    INX
    STX RNDIND;SAVE NEW INDEX
    EOR HFRAM;AND USE FRAME COUNTER FOR
    EOR FRAME;LONG REPEAT TIME
    STA RAND;SAVE NEW SEED
    RTS;EXIT
;
; SCORE ADDITION ROUTINE
;
; ADDS VALUE FOUND IN ACCUMULATOR TO THE PLAYER WHOSE OFFSET IS IN
; Y-REG. KEEP IN MIND THAT PLAYER ZERO SHOULD BE Y-REG = 0 AND PLAYER
; ONE SHOULD BE Y-REG = 2. ALSO, REMEMBER THE AMOUNT TO ADD (IN THE ACC.)
; SHOULD BE A DECIMAL NUMBER. THIS ROUTINE ALLOWS FOUR DECIMAL DIGITS
; OF SCORE FOR EACH PLAYER.
ADSCR: SED;ADD TO SCORE OF A PLAYER
    CLC
    ADC TSCR+1,Y
    STA TSCR+1,Y
    TXA
    ADC TSCR,Y
    STA TSCR,Y
    CLD
    RTS

; *
; **
;********** **********************
;*********** * RELOCATABLE TABLES *
;********** **********************
; **
; *


MISC: .BYTE $7C,$46;MISC INFORMATION FOR INITIALIZATION
;
; FRCMOV IS A TABLE USED FOR SMOOTH MOVEMENT OF OBJECTS AT
; FRACTIONAL SPEEDS. TO USE IT, ASSUME SPEED BYTE IS XXXX.XXXX
; (IN PIXELS PER FRAME) AND DO THE FOLLOWING:
; LDA #0;INIT NUMBER OF PIXELS TO MOVE TO 0
; STA T0
; LDA FRAME;GET FRAME NUMBER
; AND #$0F;USE ONLY LOW NYBBLE
; TAY;INDEX INTO FRCMOV
; LDA FRCMOV,Y;GET TABLE VALUE
; AND SPEED;TIME TO LET FRACTIONAL SPEED OVERFLOW
;;INTO A PIXEL MOVEMENT?
; BEQ 10$;NO, SKIP IT
; INC T0;YES, T0 IS NOW 1
;10$: LDA SPEED;GET SPEED AGAIN
; LSR;SHIFT OUT FRACTIONAL PORTION
; LSR
; LSR
; LSR
; CLC;ADD TO OVERFLOW FROM FRACTIONAL PART
; ADC T0
;
; ACCUMULATOR NOW CONTAINS THE NUMBER OF PIXELS TO MOVE THIS FRAME.
FRCMOV: .BYTE 1,8,4,8,2,8,4,8,0,8,4,8,2,8,4,8
GF1RST: .BYTE $A0,$80;GFLG1 VALUES AFTER GAME RESET
GF1SEL: .BYTE $30,$10;GFLG1 VALUES AFTER GAME SELECT
;
; COPYRIGHT NOTICE GRAPHICS TABLES
COL1: .BYTE $79,$85,$B5,$A5,$B5,$85,$79
COL2: .BYTE $17,$15,$15,$77,$55,$55,$77
COL3: .BYTE $71,$41,$41,$71,$11,$11,$70
COL4: .BYTE $49,$49,$49,$C9,$49,$49,$BE
COL5: .BYTE $55,$55,$55,$D9,$55,$55,$99

; *
; **
;********** *******************************
;*********** * FIXED (PAGE-ALIGNED) TABLES *
;********** *******************************
; **
; *

    ALIGN 256

;
; HMVTAB CONTAINS RESET COUNTS AND HMOVE VALUES FOR OBJECTS ON THE
; SCREEN. TO USE IT, DO THE FOLLOWING (THIS EXAMPLE POSITIONS THE BALL):
;
; LDA POSN;GET HORIZONTAL POSITION OF BALL
; STA WSYNC;0 SYNC UP FOR RESET LINE
; TAX;2 INDEX INTO HMVTAB
; LDA HMVTAB,X;6 GET TABLE VALUE
; STA HMBL;9 SET HMOVE VALUE FROM HIGH NYBBLE
; AND #$0F;11 KEEP LOW NYBBLE FOR TIME LOOP
; TAY;13 TFR TO Y FOR LOOP
; NOP;15 WASTE 2 CYCLES
; DEY;17;22 ETC. TIMING LOOP
; BPL .-1;20;25 ETC.
; STA RESBL;SET THE BALL'S POSITION RIGHT HERE
; STA WSYNC;FINISH THE LINE
; STA HMOVE;EXECUTE THE FINE POSITIONING HMOVE
;
; REMEMBER, HMVTAB MUST NOT CROSS A PAGE BOUNDARY, BECAUSE IF IT DOES
; IT COULD CAUSE THE INSTRUCTION "LDA HMVTAB,X" TO TAKE 5 CYCLES INSTEAD OF
; 4, AND THAT WOULD THROW OFF THE TIMING OF THE RESET LINE.
HMVTAB:
    .BYTE $60,$50,$40,$30,$20,$10,$00,$F0,$E0,$D0,$C0,$B0,$A0,$90
    .BYTE $71,$61,$51,$41,$31,$21,$11,$01,$F1,$E1,$D1,$C1,$B1,$A1,91
    .BYTE $72,$62,$52,$42,$32,$22,$12,$02,$F2,$E2,$D2,$C2,$B2,$A2,92
    .BYTE $73,$63,$53,$43,$33,$23,$13,$03,$F3,$E3,$D3,$C3,$B3,$A3,93
    .BYTE $74,$64,$54,$44,$34,$24,$14,$04,$F4,$E4,$D4,$C4,$B4,$A4,94
    .BYTE $75,$65,$55,$45,$35,$25,$15,$05,$F5,$E5,$D5,$C5,$B5,$A5,95
    .BYTE $76,$66,$56,$46,$36,$26,$16,$06,$F6,$E6,$D6,$C6,$B6,$A6,96
    .BYTE $77,$67,$57,$47,$37,$27,$17,$07,$F7,$E7,$D7,$C7,$B7,$A7,97
    .BYTE $78,$68,$58,$48,$38,$28,$18,$08,$F8,$E8,$D8,$C8,$B8,$A8,98
    .BYTE $79,$69,$59,$49,$39,$29,$19,$09,$F9,$E9,$D9,$C9

;
; END OF MEMORY
;
    ORG $FFFC
    .WORD START
    .WORD START





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users