mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-10-01 21:55:17 +00:00
1270 lines
26 KiB
ArmAsm
1270 lines
26 KiB
ArmAsm
|
;============================================================================
|
||
|
; Disassembly of a module generated by Bill Budge's 3-D Graphics System and
|
||
|
; Game Tool.
|
||
|
;
|
||
|
; The tool itself is copyright 1980 California Pacific Computer Co. Modules
|
||
|
; may be marketed and sold so long as they provide a credit notice.
|
||
|
;
|
||
|
; The HRCG (code and font) is credited to Christopher Espinosa.
|
||
|
;===========================================================================
|
||
|
; Disassembly by Andy McFadden, using 6502bench SourceGen v1.6.
|
||
|
; Last updated 2020/03/11
|
||
|
;
|
||
|
; The manual refers to "points" and "lines" rather than "vertices" and
|
||
|
; "edges". For consistency the same nomenclature is used here.
|
||
|
;
|
||
|
; Two shapes are defined: the space shuttle model from the manual, and a
|
||
|
; simple cube 11 units on a side. The module is configured for XOR drawing
|
||
|
|
||
|
; This makes extensive use of self-modifying code. Labels that begin with an
|
||
|
; underscore indicate self-modification targets.
|
||
|
|
||
|
; Note from Vince Weaver
|
||
|
; + I've taken the disassembly and am converting it to assembly language
|
||
|
; I guess it might make more sense to get an assembly language kernel
|
||
|
; from the program, but I'm going to modify the BASIC anyway
|
||
|
|
||
|
|
||
|
|
||
|
;===========================================================================
|
||
|
;
|
||
|
; You can define up to 16 shapes. Their parameters are stored in the various
|
||
|
; arrays:
|
||
|
;
|
||
|
; CODE_arr+N: 0 (do nothing), 1 (transform & draw), 2 (erase previous,
|
||
|
; transform, draw new), 3 (erase).
|
||
|
; X_arr+N: X coordinate of center (0-255).
|
||
|
; Y_arr+N: Y coordinate of center (0-191).
|
||
|
; SCALE_arr+N: scale factor, 0-15. 15 is full size, 0 is 1/16th.
|
||
|
; XROT_arr+N: rotation about X axis, 0-27. 0 is no rotation, 27 is just shy
|
||
|
; of 360 degrees.
|
||
|
; YROT_arr+N: rotation about Y axis.
|
||
|
; ZROT_arr+N: rotation about Z axis.
|
||
|
; SX_arr+N: (output) X coordinate of last point drawn.
|
||
|
; SY_arr+N: (output) Y coordinate of last point drawn.
|
||
|
;
|
||
|
; The code entry points are:
|
||
|
; RESET: initializes graphics module, clears the screen, switches display
|
||
|
; to primary hi-res page.
|
||
|
; CLR: clears both hi-res screens and switches to primary hi-res page.
|
||
|
; HIRES: turns on primary hi-res page.
|
||
|
; CRUNCH: primary animation function.
|
||
|
;
|
||
|
; The "CRUNCH" function:
|
||
|
; - erases objects whose CODE value is 2 or 3
|
||
|
; - computes new transformations for objects whose CODE value is 1 or 2
|
||
|
; - draws objects whose CODE value is 1 or 2
|
||
|
; - flips the display to the other page
|
||
|
;============================================================================
|
||
|
|
||
|
.include "zp.inc"
|
||
|
|
||
|
.include "hardware.inc"
|
||
|
|
||
|
; org $0300
|
||
|
|
||
|
entry:
|
||
|
jsr RESET
|
||
|
|
||
|
; CODE[0]=1 -> transform and draw
|
||
|
; CODE[1]=1 -> transform and draw
|
||
|
|
||
|
lda #1
|
||
|
sta CODE_arr
|
||
|
sta CODE_arr+1
|
||
|
|
||
|
; X[0]=127 Y[0]=96:X[1]=20:Y[1]=30 -> co-ord of center
|
||
|
|
||
|
lda #127
|
||
|
sta X_arr
|
||
|
lda #96
|
||
|
sta Y_arr
|
||
|
|
||
|
lda #20
|
||
|
sta X_arr+1
|
||
|
lda #30
|
||
|
sta Y_arr+1
|
||
|
|
||
|
; SCALE[0]=15:XROT[0]=2:YROT[0]=5:ZROT[0]=0
|
||
|
; SCALE[1]=15:XROT[1]=2:YROT[1]=5:ZROT[1]=0
|
||
|
|
||
|
lda #15
|
||
|
sta SCALE_arr
|
||
|
sta SCALE_arr+1
|
||
|
|
||
|
lda #2
|
||
|
sta XROT_arr
|
||
|
sta XROT_arr+1
|
||
|
|
||
|
lda #5
|
||
|
sta YROT_arr
|
||
|
sta YROT_arr+1
|
||
|
|
||
|
lda #0
|
||
|
sta ZROT_arr
|
||
|
sta ZROT_arr+1
|
||
|
|
||
|
jsr CRUNCH
|
||
|
jsr CRUNCH
|
||
|
|
||
|
; CODE[0]=2:CODE[1]=2 -> erase and draw new
|
||
|
|
||
|
lda #2
|
||
|
sta CODE_arr
|
||
|
sta CODE_arr+1
|
||
|
|
||
|
loop:
|
||
|
; ZROT[0]+=1: IF ZEROT[0]==28 THEN ZROT[0]=0
|
||
|
; YROT[1]=ZROT[0]
|
||
|
|
||
|
inc ZROT_arr
|
||
|
lda ZROT_arr
|
||
|
cmp #28
|
||
|
bne zrot_ok
|
||
|
lda #0
|
||
|
sta ZROT_arr
|
||
|
zrot_ok:
|
||
|
sta YROT_arr+1
|
||
|
|
||
|
jsr CRUNCH
|
||
|
|
||
|
jmp loop
|
||
|
|
||
|
nop
|
||
|
.align $100 ; 400
|
||
|
nop
|
||
|
.align $100 ; 500
|
||
|
nop
|
||
|
.align $100 ; 600
|
||
|
nop
|
||
|
.align $100 ; 700
|
||
|
nop
|
||
|
.align $100 ; 700
|
||
|
|
||
|
|
||
|
;===========================================================
|
||
|
; If configured without the HRCG, the module starts here. *
|
||
|
;===========================================================
|
||
|
|
||
|
;===========================================================
|
||
|
; Note that all tables are page-aligned for performance. *
|
||
|
;===========================================================
|
||
|
|
||
|
.include "shapes.s"
|
||
|
|
||
|
;
|
||
|
; These four buffers hold transformed points in screen coordinates. The points
|
||
|
; are in the same order as they are in the mesh definition.
|
||
|
;
|
||
|
; One pair of tables holds the X/Y screen coordinates from the previous frame,
|
||
|
; the other pair of tables holds the coordinates being transformed for the
|
||
|
; current frame. We need two sets because we're display set 0 while generating
|
||
|
; set 1, and after we flip we need to use set 0 again to erase the display.
|
||
|
;
|
||
|
; ----------
|
||
|
;
|
||
|
; Computed X coordinate, set 0.
|
||
|
XCoord0_0E: ; 0e00
|
||
|
.byte $00
|
||
|
.align $100
|
||
|
|
||
|
; Computed Y coordinate, set 0.
|
||
|
YCoord0_0F: ; 0f00
|
||
|
.byte $00
|
||
|
.align $100
|
||
|
|
||
|
; Computed X coordinate, set 1.
|
||
|
XCoord1_10: ; 1000
|
||
|
.byte $00
|
||
|
.align $100
|
||
|
|
||
|
; Computed Y coordinate, set 1.
|
||
|
YCoord1_11: ; 1100
|
||
|
.byte $00
|
||
|
.align $100
|
||
|
|
||
|
.include "math_constants.s"
|
||
|
|
||
|
.include "hgr_tables.s"
|
||
|
|
||
|
.include "scale_constants.s"
|
||
|
|
||
|
;
|
||
|
; Draw a list of lines using exclusive-or, which inverts the pixels. Drawing
|
||
|
; the same thing twice erases it.
|
||
|
;
|
||
|
; On entry:
|
||
|
; $45 - index of first line
|
||
|
; $46 - index of last line
|
||
|
; XCoord_0E/YCoord_0F or XCoord_10/YCoord_11 have transformed points in screen
|
||
|
; coordinates
|
||
|
;
|
||
|
; When the module is configured for OR-mode drawing, this code is replaced with
|
||
|
; a dedicated erase function. The erase code is nearly identical to the draw
|
||
|
; code, but saves a little time by simply zeroing out whole bytes instead of
|
||
|
; doing a read-modify-write.
|
||
|
;
|
||
|
|
||
|
; Clear variables
|
||
|
|
||
|
DrawLineListEOR:
|
||
|
ldx FIRST_LINE ; 3 start with the first line in this object
|
||
|
DrawLoop:
|
||
|
lda LineStartPoint,X; 4+ get X0,Y0
|
||
|
tay ; 2
|
||
|
_0E_or_10_1:
|
||
|
lda XCoord0_0E,Y ; 4+ the instructions here are modified to load from
|
||
|
sta XSTART ; 3 the appropriate set of X/Y coordinate tables
|
||
|
_0F_or_11_1:
|
||
|
lda YCoord0_0F,Y ; 4+
|
||
|
sta YSTART ; 3
|
||
|
lda LineEndPoint,X ; 4+ get X1,Y1
|
||
|
tay ; 2
|
||
|
_0E_or_10_2:
|
||
|
lda XCoord0_0E,Y ; 4+
|
||
|
sta XEND ; 3
|
||
|
_0F_or_11_2:
|
||
|
lda YCoord0_0F,Y ; 4+
|
||
|
sta YEND ; 3
|
||
|
stx LINE_INDEX ; 3 save this off
|
||
|
|
||
|
; Prep the line draw code. We need to compute deltaX/deltaY, and set a register
|
||
|
; increment / decrement / no-op instruction depending on which way the line is
|
||
|
; going.
|
||
|
|
||
|
lda XSTART ; 3 compute delta X
|
||
|
sec ; 2
|
||
|
sbc XEND ; 3
|
||
|
bcs L1A2F ; 2+ left to right
|
||
|
eor #$ff ; 2 right to left; invert value
|
||
|
adc #$01 ; 2
|
||
|
ldy #OpINX ; 2
|
||
|
bne GotDeltaX ; 3
|
||
|
|
||
|
L1A2F:
|
||
|
beq IsVertical ; 2+ branch if deltaX=0
|
||
|
ldy #OpDEX ; 2
|
||
|
bne GotDeltaX ; 3
|
||
|
|
||
|
IsVertical:
|
||
|
ldy #OpNOP ; 2 fully vertical, use no-op
|
||
|
GotDeltaX:
|
||
|
sta DELTA_X ; 3
|
||
|
sty _InxDexNop1 ; 4
|
||
|
sty _InxDexNop2 ; 4
|
||
|
lda YSTART ; 3 compute delta Y
|
||
|
sec ; 2
|
||
|
sbc YEND ; 3
|
||
|
bcs L1A4E ; 2+ end < start, we're good
|
||
|
eor #$ff ; 2 invert value
|
||
|
adc #$01 ; 2
|
||
|
ldy #OpINY ; 2
|
||
|
bne GotDeltaY ; 3
|
||
|
|
||
|
L1A4E:
|
||
|
beq IsHorizontal ; 2+ branch if deltaY=0
|
||
|
ldy #OpDEY ; 2
|
||
|
bne GotDeltaY ; 3
|
||
|
|
||
|
IsHorizontal:
|
||
|
ldy #OpNOP ; 2 fully horizontal, use no-op
|
||
|
GotDeltaY:
|
||
|
sta DELTA_Y ; 3
|
||
|
sty _InyDeyNop1 ; 4
|
||
|
sty _InyDeyNop2 ; 4
|
||
|
ldx XSTART ; 3
|
||
|
ldy YSTART ; 3
|
||
|
lda #$00 ; 2
|
||
|
sta LINE_ADJ ; 3
|
||
|
lda DELTA_X ; 3
|
||
|
cmp DELTA_Y ; 3
|
||
|
bcs HorizDomLine ; 2+
|
||
|
|
||
|
; Line draw: vertically dominant (move vertically every step)
|
||
|
;
|
||
|
; On entry: X=xpos, Y=ypos
|
||
|
|
||
|
VertDomLine:
|
||
|
cpy YEND ; 3
|
||
|
beq LineDone ; 2+
|
||
|
_InyDeyNop1:
|
||
|
nop ; 2 self-mod INY/DEY/NOP
|
||
|
lda YTableLo,Y ; 4+ new line, update Y position
|
||
|
sta HPTR ; 3
|
||
|
lda YTableHi,Y ; 4+
|
||
|
ora HPAGE ; 3
|
||
|
sta HPTR+1 ; 3
|
||
|
lda LINE_ADJ ; 3 Bresenham update
|
||
|
clc ; 2
|
||
|
adc DELTA_X ; 3
|
||
|
cmp DELTA_Y ; 3
|
||
|
bcs NewColumn ; 2+
|
||
|
sta LINE_ADJ ; 3
|
||
|
bcc SameColumn ; 3
|
||
|
|
||
|
NewColumn:
|
||
|
sbc DELTA_Y ; 3
|
||
|
sta LINE_ADJ ; 3
|
||
|
_InxDexNop1:
|
||
|
nop ;2 self-mod INX/DEX/NOP
|
||
|
SameColumn:
|
||
|
sty YSAVE ; 3
|
||
|
ldy Div7Tab,X ; 4+ XOR-draw the point
|
||
|
lda (HPTR),Y ; 5+
|
||
|
eor HiResBitTab,X ; 4+
|
||
|
sta (HPTR),Y ; 6
|
||
|
ldy YSAVE ; 3
|
||
|
jmp VertDomLine ; 3
|
||
|
|
||
|
LineDone:
|
||
|
ldx LINE_INDEX ; 3
|
||
|
inx ; 2
|
||
|
cpx LAST_LINE ; 3 reached end?
|
||
|
beq DrawDone ; 2+
|
||
|
jmp DrawLoop ; 3
|
||
|
|
||
|
DrawDone:
|
||
|
rts ; 6
|
||
|
|
||
|
; Line draw: horizontally dominant (move horizontally every step)
|
||
|
;
|
||
|
; On entry: X=xpos, Y=ypos
|
||
|
|
||
|
HorizDomLine:
|
||
|
lda YTableLo,Y ; 4+ set up hi-res pointer
|
||
|
sta HPTR ; 3
|
||
|
lda YTableHi,Y ; 4+
|
||
|
ora HPAGE ; 3
|
||
|
sta HPTR+1 ; 3
|
||
|
HorzLoop:
|
||
|
cpx XEND ; 3 X at end?
|
||
|
beq LineDone ; 2+ yes, finish
|
||
|
_InxDexNop2:
|
||
|
nop ; 2
|
||
|
lda LINE_ADJ ; 3 Bresenham update
|
||
|
clc ; 2
|
||
|
adc DELTA_Y ; 3
|
||
|
cmp DELTA_X ; 3
|
||
|
bcs NewRow ; 2+
|
||
|
sta LINE_ADJ ; 3
|
||
|
bcc SameRow ; 3
|
||
|
|
||
|
NewRow:
|
||
|
sbc DELTA_X ; 3
|
||
|
sta LINE_ADJ ; 3
|
||
|
_InyDeyNop2:
|
||
|
nop ; 2
|
||
|
lda YTableLo,Y ; 4+ update Y position
|
||
|
sta HPTR ; 3
|
||
|
lda YTableHi,Y ; 4+
|
||
|
ora HPAGE ; 3
|
||
|
sta HPTR+1 ; 3
|
||
|
SameRow:
|
||
|
sty YSAVE ; 3
|
||
|
ldy Div7Tab,X ; 4+ XOR-draw the point
|
||
|
lda (HPTR),Y ; 5+
|
||
|
eor HiResBitTab,X ; 4+
|
||
|
sta (HPTR),Y ; 6
|
||
|
ldy YSAVE ; 3
|
||
|
jmp HorzLoop ; 3
|
||
|
|
||
|
; Draw code calls here. Since we're configured for XOR mode, this just jumps to
|
||
|
; the exclusive-or version. If we were configured for OR mode, this would be
|
||
|
; LDX $45 / LDA $0B00,X instead of a JMP.
|
||
|
DrawLineList:
|
||
|
jmp DrawLineListEOR ; 3
|
||
|
|
||
|
;
|
||
|
; Unused OR-mode implementation follows.
|
||
|
;
|
||
|
; The code is substantially similar to the exclusive-or version, so it has not
|
||
|
; been annotated.
|
||
|
;
|
||
|
.byte $00,$0b ; ?
|
||
|
|
||
|
tay ; 2
|
||
|
lda XCoord0_0E,Y ; 4+
|
||
|
sta XSTART ; 3
|
||
|
lda YCoord0_0F,Y ; 4+
|
||
|
sta YSTART ; 3
|
||
|
lda LineEndPoint,X ; 4+
|
||
|
tay ; 2
|
||
|
lda XCoord0_0E,Y ; 4+
|
||
|
sta XEND ; 3
|
||
|
lda YCoord0_0F,Y ; 4+
|
||
|
sta YEND ; 3
|
||
|
stx LINE_INDEX ; 3
|
||
|
lda XSTART ; 3
|
||
|
sec ; 2
|
||
|
sbc XEND ; 3
|
||
|
bcs L1B1A ; 2+
|
||
|
eor #$ff ; 2
|
||
|
adc #$01 ; 2
|
||
|
ldy #$e8 ; 2
|
||
|
bne L1B22 ; 3
|
||
|
|
||
|
L1B1A:
|
||
|
beq L1B20 ; 2+
|
||
|
ldy #$ca ; 2
|
||
|
bne L1B22 ; 3
|
||
|
|
||
|
L1B20:
|
||
|
ldy #$ea ; 2
|
||
|
L1B22:
|
||
|
sta DELTA_X ; 3
|
||
|
sty L1B79 ; 4
|
||
|
sty L1BA6 ; 4
|
||
|
lda YSTART ; 3
|
||
|
sec ; 2
|
||
|
sbc YEND ; 3
|
||
|
bcs L1B39 ; 2+
|
||
|
eor #$ff ; 2
|
||
|
adc #$01 ; 2
|
||
|
ldy #$c8 ; 2
|
||
|
bne L1B41 ; 3
|
||
|
|
||
|
L1B39:
|
||
|
beq L1B3F ; 2+
|
||
|
ldy #$88 ; 2
|
||
|
bne L1B41 ; 3
|
||
|
|
||
|
L1B3F:
|
||
|
ldy #$ea ; 2
|
||
|
L1B41:
|
||
|
sta DELTA_Y ; 3
|
||
|
sty L1B5B ; 4
|
||
|
sty L1BB8 ; 4
|
||
|
ldx XSTART ; 3
|
||
|
ldy YSTART ; 3
|
||
|
lda #$00 ; 2
|
||
|
sta LINE_ADJ ; 3
|
||
|
lda DELTA_X ; 3
|
||
|
cmp DELTA_Y ; 3
|
||
|
bcs L1B96 ; 2+
|
||
|
L1B57:
|
||
|
cpy YEND ; 3
|
||
|
beq L1B8B ; 2+
|
||
|
L1B5B:
|
||
|
nop ; 2
|
||
|
lda YTableLo,Y ; 4+
|
||
|
sta HPTR ; 3
|
||
|
lda YTableHi,Y ; 4+
|
||
|
ora HPAGE ; 3
|
||
|
sta HPTR+1 ; 3
|
||
|
lda LINE_ADJ ; 3
|
||
|
clc ; 2
|
||
|
adc DELTA_X ; 3
|
||
|
cmp DELTA_Y ; 3
|
||
|
bcs L1B75 ; 2+
|
||
|
sta LINE_ADJ ; 3
|
||
|
bcc L1B7A ; 3
|
||
|
|
||
|
L1B75:
|
||
|
sbc DELTA_Y ; 3
|
||
|
sta LINE_ADJ ; 3
|
||
|
L1B79:
|
||
|
nop ; 2
|
||
|
L1B7A:
|
||
|
sty YSAVE ; 3
|
||
|
ldy Div7Tab,X ; 4+
|
||
|
lda (HPTR),Y ; 5+
|
||
|
ora HiResBitTab,X ; 4+
|
||
|
sta (HPTR),Y ; 6
|
||
|
ldy YSAVE ; 3
|
||
|
jmp L1B57 ; 3
|
||
|
|
||
|
L1B8B:
|
||
|
ldx LINE_INDEX ; 3
|
||
|
inx ; 2
|
||
|
cpx LAST_LINE ; 3
|
||
|
beq L1B95 ; 2+
|
||
|
jmp DrawLineList+2 ; 3
|
||
|
|
||
|
L1B95:
|
||
|
rts ; 6
|
||
|
|
||
|
L1B96:
|
||
|
lda YTableLo,Y ; 4+
|
||
|
sta HPTR ; 3
|
||
|
lda YTableHi,Y ; 4+
|
||
|
ora HPAGE ; 3
|
||
|
sta HPTR+1 ; 3
|
||
|
L1BA2:
|
||
|
cpx XEND ; 3
|
||
|
beq L1B8B ; 2+
|
||
|
L1BA6:
|
||
|
nop ; 2
|
||
|
lda LINE_ADJ ; 3
|
||
|
clc ; 2
|
||
|
adc DELTA_Y ; 3
|
||
|
cmp DELTA_X ; 3
|
||
|
bcs L1BB4 ; 2+
|
||
|
sta LINE_ADJ ; 3
|
||
|
bcc L1BC5 ; 3
|
||
|
|
||
|
L1BB4:
|
||
|
sbc DELTA_X ; 3
|
||
|
sta LINE_ADJ ; 3
|
||
|
L1BB8:
|
||
|
nop ; 2
|
||
|
lda YTableLo,Y ; 4+
|
||
|
sta HPTR ; 3
|
||
|
lda YTableHi,Y ; 4+
|
||
|
ora HPAGE ; 3
|
||
|
sta HPTR+1 ; 3
|
||
|
L1BC5:
|
||
|
sty YSAVE ; 3
|
||
|
ldy Div7Tab,X ; 4+
|
||
|
lda (HPTR),Y ; 5+
|
||
|
ora HiResBitTab,X ; 4+
|
||
|
sta (HPTR),Y ; 6
|
||
|
ldy YSAVE ; 3
|
||
|
jmp L1BA2 ; 3
|
||
|
|
||
|
;
|
||
|
; Unreferenced function that copies untransformed mesh X/Y values into the
|
||
|
; screen-coordinate buffers. Could be used for a static 2D effect, like a
|
||
|
; background that doesn't move.
|
||
|
;
|
||
|
ldx FIRST_LINE ; 3
|
||
|
UnusedCopyLoop:
|
||
|
lda ShapeXCoords,X ; 4+
|
||
|
clc ; 2
|
||
|
adc YSTART ; 3
|
||
|
_unused_mod0:
|
||
|
sta XCoord0_0E,X ; 5
|
||
|
lda XEND ; 3
|
||
|
sec ; 2
|
||
|
sbc ShapeYCoords,X ; 4+
|
||
|
_unused_mod1:
|
||
|
sta YCoord0_0F,X ; 5
|
||
|
inx ; 2
|
||
|
cpx LAST_LINE ; 3
|
||
|
bne UnusedCopyLoop ; 2+
|
||
|
rts ; 6
|
||
|
|
||
|
; Current hi-res page.
|
||
|
;
|
||
|
; $00 = draw page 1, show page 2
|
||
|
; $FF = draw page 2, show page 1
|
||
|
CurPage: .byte $ff
|
||
|
|
||
|
;
|
||
|
; Switch to the other hi-res page.
|
||
|
;
|
||
|
SwapPage:
|
||
|
lda CurPage ; 4
|
||
|
eor #$ff ; 2 flip to other page
|
||
|
sta CurPage ; 4
|
||
|
beq DrawOnPage1 ; 3+
|
||
|
sta TXTPAGE1 ; 4 draw on page 2, show page 1
|
||
|
lda #$40 ; 2
|
||
|
ldx #>XCoord1_10 ; 2
|
||
|
ldy #>YCoord1_11 ; 2
|
||
|
bne L1C0F ; 3
|
||
|
|
||
|
DrawOnPage1:
|
||
|
sta TXTPAGE2 ; 4 draw on page 1, show page 2
|
||
|
lda #$20 ; 2
|
||
|
ldx #>XCoord0_0E ; 2
|
||
|
ldy #>YCoord0_0F ; 2
|
||
|
|
||
|
; Save the hi-res page, and modify the instructions that read from or write data
|
||
|
; to the transformed point arrays.
|
||
|
L1C0F:
|
||
|
sta HPAGE ; 3
|
||
|
stx _0E_or_10_1+2 ; 4
|
||
|
stx _0E_or_10_2+2 ; 4
|
||
|
stx _0E_or_10_3+2 ; 4
|
||
|
stx _unused_mod0+2 ; 4
|
||
|
sty _0F_or_11_1+2 ; 4
|
||
|
sty _0F_or_11_2+2 ; 4
|
||
|
sty _0F_or_11_3+2 ; 4
|
||
|
sty _unused_mod1+2 ; 4
|
||
|
rts ; 6
|
||
|
|
||
|
; Unreferenced junk (12 bytes)
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00
|
||
|
.byte $00,$00,$00,$00
|
||
|
|
||
|
; Coordinate transformation function. Transforms all points in a single object.
|
||
|
;
|
||
|
; On entry:
|
||
|
; 1c = scale (00-0f)
|
||
|
; 1d = xc (00-ff)
|
||
|
; 1e = yc (00-bf)
|
||
|
; 1f = zrot (00-1b)
|
||
|
; 3c = yrot (00-1b)
|
||
|
; 3d = xrot (00-1b)
|
||
|
; 45 = index of first point to transform
|
||
|
; 46 = index of last point to transform
|
||
|
;
|
||
|
; Rotation values greater than $1B, and scale factors greater than $0F, disable
|
||
|
; the calculation. This has the same effect as a rotation value of 0 or a scale
|
||
|
; of 15, but is more efficient, because this uses self-modifying code to skip
|
||
|
; the computation entirely.
|
||
|
;
|
||
|
|
||
|
; Clear variables
|
||
|
xc = $19 ; transformed X coordinate
|
||
|
yc = $1a ; transformed Y coordinate
|
||
|
zc = $1b ; transformed Z coordinate
|
||
|
scale = $1c ; $00-0F, where $0F is full size
|
||
|
xposn = $1d ; X coordinate (0-255)
|
||
|
yposn = $1e ; Y coordinate (0-191)
|
||
|
zrot = $1f ; Z rotation ($00-1B)
|
||
|
yrot = $3c ; Y rotation ($00-1B)
|
||
|
xrot = $3d ; X rotation ($00-1B)
|
||
|
rot_tmp = $3f
|
||
|
out_index = $43
|
||
|
first_point = $45
|
||
|
last_point = $46
|
||
|
|
||
|
CompTransform:
|
||
|
ldx first_point ; 3 get first point index; this stays in X for a while
|
||
|
|
||
|
; Configure Z rotation.
|
||
|
|
||
|
ldy zrot ; 3
|
||
|
cpy #$1c ; 2 valid rotation value?
|
||
|
bcc ConfigZrot ; 2+ yes, configure
|
||
|
lda #<DoYrot ; 2 no, modify code to skip Z-rot
|
||
|
sta _BeforeZrot+1 ; 4
|
||
|
bne NoZrot ; 3
|
||
|
|
||
|
ConfigZrot:
|
||
|
lda #<DoZrot ; 2
|
||
|
sta _BeforeZrot+1 ; 4
|
||
|
lda RotIndexLo_sin,Y ; 4+
|
||
|
sta _zrotLS1+1 ; 4
|
||
|
sta _zrotLS2+1 ; 4
|
||
|
lda RotIndexHi_sin,Y ; 4+
|
||
|
sta _zrotHS1+1 ; 4
|
||
|
sta _zrotHS2+1 ; 4
|
||
|
lda RotIndexLo_cos,Y ; 4+
|
||
|
sta _zrotLC1+1 ; 4
|
||
|
sta _zrotLC2+1 ; 4
|
||
|
lda RotIndexHi_cos,Y ; 4+
|
||
|
sta _zrotHC1+1 ; 4
|
||
|
sta _zrotHC2+1 ; 4
|
||
|
|
||
|
; Configure Y rotation.
|
||
|
|
||
|
NoZrot:
|
||
|
ldy yrot ; 3
|
||
|
cpy #$1c ; 2 valid rotation value?
|
||
|
bcc ConfigYrot ; 2+ yes, configure
|
||
|
lda #<DoXrot ; 2 no, modify code to skip Y-rot
|
||
|
sta _BeforeYrot+1 ; 4
|
||
|
bne NoYrot ; 3
|
||
|
|
||
|
ConfigYrot:
|
||
|
lda #<DoYrot ; 2
|
||
|
sta _BeforeYrot+1 ; 4
|
||
|
lda RotIndexLo_sin,Y ; 4+
|
||
|
sta _yrotLS1+1 ; 4
|
||
|
sta _yrotLS2+1 ; 4
|
||
|
lda RotIndexHi_sin,Y ; 4+
|
||
|
sta _yrotHS1+1 ; 4
|
||
|
sta _yrotHS2+1 ; 4
|
||
|
lda RotIndexLo_cos,Y ; 4+
|
||
|
sta _yrotLC1+1 ; 4
|
||
|
sta _yrotLC2+1 ; 4
|
||
|
lda RotIndexHi_cos,Y ; 4+
|
||
|
sta _yrotHC1+1 ; 4
|
||
|
sta _yrotHC2+1 ; 4
|
||
|
|
||
|
; Configure X rotation.
|
||
|
|
||
|
NoYrot:
|
||
|
ldy xrot ; 3
|
||
|
cpy #$1c ; 2 valid rotation value?
|
||
|
bcc ConfigXrot ; 2+ yes, configure
|
||
|
lda #<DoScale ; 2 no, modify code to skip X-rot
|
||
|
sta _BeforeXrot+1 ; 4
|
||
|
bne ConfigScale ; 3
|
||
|
|
||
|
ConfigXrot:
|
||
|
lda #<DoXrot ; 2
|
||
|
sta _BeforeXrot+1 ; 4
|
||
|
lda RotIndexLo_sin,Y ; 4+
|
||
|
sta _xrotLS1+1 ; 4
|
||
|
sta _xrotLS2+1 ; 4
|
||
|
lda RotIndexHi_sin,Y ; 4+
|
||
|
sta _xrotHS1+1 ; 4
|
||
|
sta _xrotHS2+1 ; 4
|
||
|
lda RotIndexLo_cos,Y ; 4+
|
||
|
sta _xrotLC1+1 ; 4
|
||
|
sta _xrotLC2+1 ; 4
|
||
|
lda RotIndexHi_cos,Y ; 4+
|
||
|
sta _xrotHC1+1 ; 4
|
||
|
sta _xrotHC2+1 ; 4
|
||
|
|
||
|
; Configure scaling.
|
||
|
|
||
|
ConfigScale:
|
||
|
ldy scale ; 3
|
||
|
cpy #$10 ; 2 valid scale value?
|
||
|
bcc SetScale ; 2+ yes, configure it
|
||
|
lda #<DoTranslate ; 2 no, skip it
|
||
|
sta _BeforeScale+1 ; 4
|
||
|
lda #>DoTranslate ; 2
|
||
|
sta _BeforeScale+2 ; 4
|
||
|
bne TransformLoop ; 4
|
||
|
|
||
|
SetScale:
|
||
|
lda #<DoScale ; 2
|
||
|
sta _BeforeScale+1 ; 4
|
||
|
lda #>DoScale ; 2
|
||
|
sta _BeforeScale+2 ; 4
|
||
|
lda ScaleIndexLo,Y ; 4+ $00, $10, $20, ... $F0
|
||
|
sta _scaleLX+1 ; 4
|
||
|
sta _scaleLY+1 ; 4
|
||
|
lda ScaleIndexHi,Y ; 4+ $00, $01, $02, ... $0F
|
||
|
sta _scaleHX+1 ; 4
|
||
|
sta _scaleHY+1 ; 4
|
||
|
|
||
|
|
||
|
;
|
||
|
; Now that we've got the code modified, perform the computation for all points
|
||
|
; in the object.
|
||
|
;
|
||
|
TransformLoop:
|
||
|
lda ShapeXCoords,X ; 4+
|
||
|
sta xc ; 3
|
||
|
lda ShapeYCoords,X ; 4+
|
||
|
sta yc ; 3
|
||
|
lda ShapeZCoords,X ; 4+
|
||
|
sta zc ; 3
|
||
|
stx out_index ; 3 save for later
|
||
|
_BeforeZrot:
|
||
|
jmp DoZrot ; 3
|
||
|
|
||
|
DoZrot:
|
||
|
lda xc ; 3 rotating about Z, so we need to update X/Y coords
|
||
|
and #$0f ; 2 split X/Y into nibbles
|
||
|
sta rot_tmp ; 3
|
||
|
lda xc ; 3
|
||
|
and #$f0 ; 2
|
||
|
sta rot_tmp+1 ; 3
|
||
|
lda yc ; 3
|
||
|
and #$0f ; 2
|
||
|
sta rot_tmp+2 ; 3
|
||
|
lda yc ; 3
|
||
|
and #$f0 ; 2
|
||
|
sta rot_tmp+3 ; 3
|
||
|
ldy rot_tmp ; 3 transform X coord
|
||
|
ldx rot_tmp+1 ; 3 XC = X * cos(theta) - Y * sin(theta)
|
||
|
_zrotLC1:
|
||
|
lda RotTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_zrotHC1:
|
||
|
adc RotTabHi,X ; 4+
|
||
|
ldy rot_tmp+2 ; 3
|
||
|
ldx rot_tmp+3 ; 3
|
||
|
sec ; 2
|
||
|
_zrotLS1:
|
||
|
sbc RotTabLo,Y ; 4+
|
||
|
sec ; 2
|
||
|
_zrotHS1:
|
||
|
sbc RotTabHi,X ; 4+
|
||
|
sta xc ; 3 save updated coord
|
||
|
_zrotLC2:
|
||
|
lda RotTabLo,Y ; 4+ transform Y coord
|
||
|
clc ; 2 YC = Y * cos(theta) + X * sin(theta)
|
||
|
_zrotHC2:
|
||
|
adc RotTabHi,X ; 4+
|
||
|
ldy rot_tmp ; 3
|
||
|
ldx rot_tmp+1 ; 3
|
||
|
clc ; 2
|
||
|
_zrotLS2:
|
||
|
adc RotTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_zrotHS2:
|
||
|
adc RotTabHi,X ; 4+
|
||
|
sta yc ; 3 save updated coord
|
||
|
_BeforeYrot:
|
||
|
jmp DoYrot ; 3
|
||
|
|
||
|
DoYrot:
|
||
|
lda xc ; 3 rotating about Y, so update X/Z
|
||
|
and #$0f ; 2
|
||
|
sta rot_tmp ; 3
|
||
|
lda xc ; 3
|
||
|
and #$f0 ; 2
|
||
|
sta rot_tmp+1 ; 3
|
||
|
lda zc ; 3
|
||
|
and #$0f ; 2
|
||
|
sta rot_tmp+2 ; 3
|
||
|
lda zc ; 3
|
||
|
and #$f0 ; 2
|
||
|
sta rot_tmp+3 ; 3
|
||
|
ldy rot_tmp ; 3
|
||
|
ldx rot_tmp+1 ; 3
|
||
|
_yrotLC1:
|
||
|
lda RotTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_yrotHC1:
|
||
|
adc RotTabHi,X ; 4+
|
||
|
ldy rot_tmp+2 ; 3
|
||
|
ldx rot_tmp+3 ; 3
|
||
|
sec ; 2
|
||
|
_yrotLS1:
|
||
|
sbc RotTabLo,Y ; 4+
|
||
|
sec ; 2
|
||
|
_yrotHS1:
|
||
|
sbc RotTabHi,X ; 4+
|
||
|
sta xc ; 3
|
||
|
_yrotLC2:
|
||
|
lda RotTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_yrotHC2:
|
||
|
adc RotTabHi,X ; 4+
|
||
|
ldy rot_tmp ; 3
|
||
|
ldx rot_tmp+1 ; 3
|
||
|
clc ; 2
|
||
|
_yrotLS2:
|
||
|
adc RotTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_yrotHS2:
|
||
|
adc RotTabHi,X ; 4+
|
||
|
sta zc ; 3
|
||
|
_BeforeXrot:
|
||
|
jmp DoXrot ; 3
|
||
|
|
||
|
DoXrot:
|
||
|
lda zc ; 3 rotating about X, so update Z/Y
|
||
|
and #$0f ; 2
|
||
|
sta rot_tmp ; 3
|
||
|
lda zc ; 3
|
||
|
and #$f0 ; 2
|
||
|
sta rot_tmp+1 ; 3
|
||
|
lda yc ; 3
|
||
|
and #$0f ; 2
|
||
|
sta rot_tmp+2 ; 3
|
||
|
lda yc ; 3
|
||
|
and #$f0 ; 2
|
||
|
sta rot_tmp+3 ; 3
|
||
|
ldy rot_tmp ; 3
|
||
|
ldx rot_tmp+1 ; 3
|
||
|
_xrotLC1:
|
||
|
lda RotTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_xrotHC1:
|
||
|
adc RotTabHi,X ; 4+
|
||
|
ldy rot_tmp+2 ; 3
|
||
|
ldx rot_tmp+3 ; 3
|
||
|
sec ; 2
|
||
|
_xrotLS1:
|
||
|
sbc RotTabLo,Y ; 4+
|
||
|
sec ; 2
|
||
|
_xrotHS1:
|
||
|
sbc RotTabHi,X ; 4+
|
||
|
sta zc ; 3
|
||
|
_xrotLC2:
|
||
|
lda RotTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_xrotHC2:
|
||
|
adc RotTabHi,X ; 4+
|
||
|
ldy rot_tmp ; 3
|
||
|
ldx rot_tmp+1 ; 3
|
||
|
clc ; 2
|
||
|
_xrotLS2:
|
||
|
adc RotTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_xrotHS2:
|
||
|
adc RotTabHi,X ; 4+
|
||
|
sta yc ; 3
|
||
|
_BeforeScale:
|
||
|
jmp DoScale ; 3
|
||
|
|
||
|
|
||
|
; Apply scaling. Traditionally this is applied before rotation.
|
||
|
DoScale:
|
||
|
lda xc ; 3 scale the X coordinate
|
||
|
and #$f0 ; 2
|
||
|
tax ; 2
|
||
|
lda xc ; 3
|
||
|
and #$0f ; 2
|
||
|
tay ; 2
|
||
|
_scaleLX:
|
||
|
lda ScaleTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_scaleHX:
|
||
|
adc ScaleTabHi,X ; 4+
|
||
|
sta xc ; 3
|
||
|
lda yc ; 3 scale the Y coordinate
|
||
|
and #$f0 ; 2
|
||
|
tax ; 2
|
||
|
lda yc ; 3
|
||
|
and #$0f ; 2
|
||
|
tay ; 2
|
||
|
_scaleLY:
|
||
|
lda ScaleTabLo,Y ; 4+
|
||
|
clc ; 2
|
||
|
_scaleHY:
|
||
|
adc ScaleTabHi,X ; 4+
|
||
|
sta yc ; 3
|
||
|
|
||
|
;
|
||
|
; Apply translation.
|
||
|
;
|
||
|
; This is the final step, so the result is written to the transformed-point
|
||
|
; arrays.
|
||
|
;
|
||
|
DoTranslate:
|
||
|
ldx out_index ; 3
|
||
|
lda xc ; 3
|
||
|
clc ; 2
|
||
|
adc xposn ; 3 object center in screen coordinates
|
||
|
_0E_or_10_3:
|
||
|
sta XCoord0_0E,X ; 5
|
||
|
lda yposn ; 3
|
||
|
sec ; 2
|
||
|
sbc yc ; 3
|
||
|
_0F_or_11_3:
|
||
|
sta YCoord0_0F,X ; 5
|
||
|
inx ; 2
|
||
|
cpx last_point ; 3 done?
|
||
|
beq TransformDone ; 2+ yes, bail
|
||
|
jmp TransformLoop ; 3
|
||
|
|
||
|
TransformDone:
|
||
|
rts ; 6
|
||
|
|
||
|
SavedShapeIndex:
|
||
|
.byte $ad ;holds shape index while we work
|
||
|
|
||
|
;*******************************************************************************
|
||
|
; CRUNCH/CRNCH% entry point *
|
||
|
; *
|
||
|
; For each object, do what CODE%(n) tells us to: *
|
||
|
; *
|
||
|
; 0 - do nothing *
|
||
|
; 1 - transform and draw *
|
||
|
; 2 - erase, transform, draw *
|
||
|
; 3 - erase *
|
||
|
;*******************************************************************************
|
||
|
|
||
|
;FIRST_LINE = $45
|
||
|
;LAST_LINE = $46
|
||
|
|
||
|
CRUNCH:
|
||
|
; jsr Setup ; 6 find Applesoft arrays
|
||
|
|
||
|
;==============================
|
||
|
; First pass: erase old shapes
|
||
|
;==============================
|
||
|
|
||
|
lda NumObjects ; 4 number of defined objects
|
||
|
; asl ; 2 * 2
|
||
|
tax ; 2 use as index
|
||
|
ShapeLoop:
|
||
|
; dex ; 2
|
||
|
dex ; 2
|
||
|
bmi Transform ; 2+ done
|
||
|
_codeAR1:
|
||
|
lda CODE_arr,X ; 4+
|
||
|
cmp #$02 ; 2 2 or 3?
|
||
|
bcc ShapeLoop ; 2+ no, move on
|
||
|
stx SavedShapeIndex ; 4
|
||
|
; txa ; 2
|
||
|
; lsr ; 2
|
||
|
; tax ; 2
|
||
|
lda FirstLineIndex,X; 4+
|
||
|
sta FIRST_LINE ; 3
|
||
|
lda LastLineIndex,X ; 4+
|
||
|
sta LAST_LINE ; 3
|
||
|
cmp FIRST_LINE ; 3 is number of lines <= 0?
|
||
|
bcc NoLines1 ; 2+
|
||
|
beq NoLines1 ; 2+ yes, skip draw
|
||
|
jsr DrawLineListEOR ; 6 erase with EOR version, regardless of config
|
||
|
NoLines1:
|
||
|
ldx SavedShapeIndex ; 4
|
||
|
bpl ShapeLoop ; 3 ...always
|
||
|
|
||
|
;===============================
|
||
|
; Second pass: transform shapes
|
||
|
;===============================
|
||
|
Transform:
|
||
|
lda NumObjects ; 4
|
||
|
; asl ; 2
|
||
|
tax ; 2
|
||
|
TransLoop:
|
||
|
; dex ; 2
|
||
|
dex ; 2
|
||
|
bmi DrawNew ; 2+
|
||
|
_codeAR2:
|
||
|
lda CODE_arr,X ; 4+
|
||
|
beq TransLoop ; 2+ is it zero or three?
|
||
|
cmp #$03 ; 2
|
||
|
beq TransLoop ; 2+ yes, we only draw on 1 or 2
|
||
|
|
||
|
; Extract the scale, X/Y, and rotation values out of the arrays and copy them to
|
||
|
; zero-page locations.
|
||
|
|
||
|
_scaleAR:
|
||
|
lda SCALE_arr,X ; 4+
|
||
|
sta scale ; 3
|
||
|
_xAR:
|
||
|
lda X_arr,X ; 4+
|
||
|
sta xposn ; 3
|
||
|
_yAR:
|
||
|
lda Y_arr,X ; 4+
|
||
|
sta yposn ; 3
|
||
|
_zrotAR:
|
||
|
lda ZROT_arr,X ; 4+
|
||
|
sta zrot ; 3
|
||
|
_yrotAR:
|
||
|
lda YROT_arr,X ; 4+
|
||
|
sta yrot ; 3
|
||
|
_xrotAR:
|
||
|
lda XROT_arr,X ; 4+
|
||
|
sta xrot ; 3
|
||
|
stx SavedShapeIndex ; 4 save this off
|
||
|
; txa ; 2
|
||
|
; lsr ; 2 convert to 1x index
|
||
|
; tax ; 2
|
||
|
lda FirstPointIndex,X; 4+
|
||
|
sta FIRST_LINE ; 3 (actually first_point)
|
||
|
lda LastPointIndex,X; 4+
|
||
|
sta LAST_LINE ; 3
|
||
|
cmp FIRST_LINE ; 3 is number of points <= 0?
|
||
|
bcc NoPoints ; 2+
|
||
|
beq NoPoints ; 2+ yes, skip transform
|
||
|
jsr CompTransform ; 6 transform all points
|
||
|
NoPoints:
|
||
|
ldx SavedShapeIndex ; 4
|
||
|
lda xc ; 3
|
||
|
clc ; 2
|
||
|
adc xposn ; 3
|
||
|
_sxAR:
|
||
|
sta SX_arr,X ; 5
|
||
|
lda yposn ; 3
|
||
|
sec ; 2
|
||
|
sbc yc ; 3
|
||
|
_syAR:
|
||
|
sta SY_arr,X ; 5
|
||
|
jmp TransLoop ; 3
|
||
|
|
||
|
;=============================
|
||
|
; Third pass: draw shapes
|
||
|
;=============================
|
||
|
|
||
|
DrawNew:
|
||
|
lda NumObjects ; 4
|
||
|
; asl ; 2
|
||
|
tax ; 2
|
||
|
L1ECE:
|
||
|
; dex ; 2
|
||
|
dex ; 2
|
||
|
bmi L1EF9 ; 2+
|
||
|
_codeAR3:
|
||
|
lda CODE_arr,X ; 4+ is it 0 or 3?
|
||
|
beq L1ECE ; 2+
|
||
|
cmp #$03 ; 2
|
||
|
beq L1ECE ; 2+ yup, no draw
|
||
|
stx SavedShapeIndex ; 4 save index
|
||
|
; txa ; 2
|
||
|
; lsr ; 2 convert it back to 1x index
|
||
|
; tax ; 2
|
||
|
lda FirstLineIndex,X; 4+ draw all the lines in the shape
|
||
|
sta FIRST_LINE ; 3
|
||
|
lda LastLineIndex,X ; 4+
|
||
|
sta LAST_LINE ; 3
|
||
|
cmp FIRST_LINE ; 3 is number of lines <= 0?
|
||
|
bcc NoLines2 ; 2+
|
||
|
beq NoLines2 ; 2+ yes, skip draw
|
||
|
jsr DrawLineList ; 6 draw all lines
|
||
|
NoLines2:
|
||
|
ldx SavedShapeIndex ; 4
|
||
|
bpl L1ECE ; 3 ...always
|
||
|
|
||
|
L1EF9:
|
||
|
jmp SwapPage ; 3
|
||
|
|
||
|
|
||
|
;*******************************************************************************
|
||
|
; RESET entry point *
|
||
|
; *
|
||
|
; Zeroes out the CODE% array, erases both hi-res screens, and enables display *
|
||
|
; of the primary hi-res page. *
|
||
|
;*******************************************************************************
|
||
|
|
||
|
RESET:
|
||
|
; jsr Setup ; 6 sets A=0, Y=$1E
|
||
|
lda #$0
|
||
|
ldy #$F
|
||
|
_codeAR4:
|
||
|
sta CODE_arr,y ; 5 zero out CODE%
|
||
|
dey ; 2
|
||
|
bpl _codeAR4 ; 3+
|
||
|
jsr CLEAR ; 6
|
||
|
jsr SwapPage ; 6
|
||
|
jsr SwapPage ; 6
|
||
|
rts ; 6
|
||
|
|
||
|
;*******************************************************************************
|
||
|
; CLEAR/CLR% entry point *
|
||
|
; *
|
||
|
; Clears both hi-res pages. *
|
||
|
;*******************************************************************************
|
||
|
; Clear variables
|
||
|
|
||
|
ptr1 = $1a
|
||
|
ptr2 = $1c
|
||
|
|
||
|
CLEAR:
|
||
|
lda #$20 ; 2 hi-res page 1
|
||
|
sta ptr1+1 ; 3
|
||
|
lda #$40 ; 2 hi-res page 2
|
||
|
sta ptr2+1 ; 3
|
||
|
ldy #$00 ; 2
|
||
|
sty ptr1 ; 3
|
||
|
sty ptr2 ; 3
|
||
|
L1F1D:
|
||
|
tya ; 2
|
||
|
L1F1E:
|
||
|
sta (ptr1),Y ; 6 erase both pages
|
||
|
sta (ptr2),Y ; 6
|
||
|
iny ; 2
|
||
|
bne L1F1E ; 2+
|
||
|
inc ptr1+1 ; 5
|
||
|
inc ptr2+1 ; 5
|
||
|
lda ptr1+1 ; 3 (could hold counter in X-reg)
|
||
|
and #$3f ; 2
|
||
|
bne L1F1D ; 2+
|
||
|
|
||
|
;*******************************************************************************
|
||
|
; HIRES entry point *
|
||
|
; *
|
||
|
; Displays primary hi-res page. *
|
||
|
;*******************************************************************************
|
||
|
HI_RES:
|
||
|
sta HIRES ; 4
|
||
|
sta MIXCLR ; 4
|
||
|
sta TXTCLR ; 4
|
||
|
rts ; 6
|
||
|
|
||
|
; Locate Applesoft arrays. This assumes the arrays are declared first, and in
|
||
|
; the correct order, so that the start can be found at a fixed offset from the
|
||
|
; BASIC array table pointer.
|
||
|
;
|
||
|
; 1 DIM CODE%(15), X%(15), Y%(15), SCALE%(15), XROT%(15), YROT%(15), ZROT%(15),
|
||
|
; SX%(15), SY%(15)
|
||
|
;
|
||
|
; If you generate the module for Integer BASIC, this is the entry point for
|
||
|
; MISSILE (7993).
|
||
|
|
||
|
|
||
|
CODE_arr:
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||
|
X_arr:
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||
|
Y_arr:
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||
|
XROT_arr:
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||
|
YROT_arr:
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||
|
ZROT_arr:
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||
|
SCALE_arr:
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||
|
SX_arr:
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||
|
SY_arr:
|
||
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
||
|
|
||
|
|
||
|
|
||
|
.if 0
|
||
|
|
||
|
Setup:
|
||
|
lda BAS_ARYTAB ; 3 CODE% is at +$0008
|
||
|
clc ; 2
|
||
|
adc #$08 ; 2
|
||
|
tax ; 2
|
||
|
lda BAS_ARYTAB+1 ; 3
|
||
|
adc #$00 ; 2
|
||
|
stx _codeAR1+1 ; 4
|
||
|
sta _codeAR1+2 ; 4
|
||
|
stx _codeAR2+1 ; 4
|
||
|
sta _codeAR2+2 ; 4
|
||
|
stx _codeAR3+1 ; 4
|
||
|
sta _codeAR3+2 ; 4
|
||
|
stx _codeAR4+1 ; 4
|
||
|
sta _codeAR4+2 ; 4
|
||
|
lda BAS_ARYTAB ; 3 X% is at +$002F
|
||
|
clc ; 2
|
||
|
adc #$2f ; 2
|
||
|
tax ; 2
|
||
|
lda BAS_ARYTAB+1 ; 3
|
||
|
adc #$00 ; 2
|
||
|
stx _xAR+1 ; 4
|
||
|
sta _xAR+2 ; 4
|
||
|
lda BAS_ARYTAB ; 3 Y% is at +$0056
|
||
|
clc ; 2
|
||
|
adc #$56 ; 2
|
||
|
tax ; 2
|
||
|
lda BAS_ARYTAB+1 ; 3
|
||
|
adc #$00 ; 2
|
||
|
stx _yAR+1 ; 4
|
||
|
sta _yAR+2 ; 4
|
||
|
lda BAS_ARYTAB ; 3 SCALE% is at + $007D
|
||
|
clc ; 2
|
||
|
adc #$7d ; 2
|
||
|
tax ; 2
|
||
|
lda BAS_ARYTAB+1 ; 3
|
||
|
adc #$00 ; 2
|
||
|
stx _scaleAR+1 ; 4
|
||
|
sta _scaleAR+2 ; 4
|
||
|
lda BAS_ARYTAB ; 3 XROT% is at +$00A4
|
||
|
clc ; 2
|
||
|
adc #$a4 ; 2
|
||
|
tax ; 2
|
||
|
lda BAS_ARYTAB+1 ; 3
|
||
|
adc #$00 ; 2
|
||
|
stx _xrotAR+1 ; 4
|
||
|
sta _xrotAR+2 ; 4
|
||
|
lda BAS_ARYTAB ; 3 YROT% is at +$00CB
|
||
|
clc ; 2
|
||
|
adc #$cb ; 2
|
||
|
tax ; 2
|
||
|
lda BAS_ARYTAB+1 ; 3
|
||
|
adc #$00 ; 2
|
||
|
stx _yrotAR+1 ; 4
|
||
|
sta _yrotAR+2 ; 4
|
||
|
lda BAS_ARYTAB ; 3 ZROT% is at +$00F2
|
||
|
clc ; 2
|
||
|
adc #$f2 ; 2
|
||
|
tax ; 2
|
||
|
lda BAS_ARYTAB+1 ; 3
|
||
|
adc #$00 ; 2
|
||
|
stx _zrotAR+1 ; 4
|
||
|
sta _zrotAR+2 ; 4
|
||
|
lda BAS_ARYTAB ; 3 SX% is at +$0119
|
||
|
clc ; 2
|
||
|
adc #$19 ; 2
|
||
|
tax ; 2
|
||
|
lda BAS_ARYTAB+1 ; 3
|
||
|
adc #$01 ; 2
|
||
|
stx _sxAR+1 ; 4
|
||
|
sta _sxAR+2 ; 4
|
||
|
lda BAS_ARYTAB ; 3 SY% is at +$0140
|
||
|
clc ; 2
|
||
|
adc #$40 ; 2
|
||
|
tax ; 2
|
||
|
lda BAS_ARYTAB+1 ; 3
|
||
|
adc #$01 ; 2
|
||
|
stx _syAR+1 ; 4
|
||
|
sta _syAR+2 ; 4
|
||
|
ldy #$1e ; 2 Set A and Y for RESET
|
||
|
lda #$00 ; 2
|
||
|
rts ; 6
|
||
|
.endif
|
||
|
|
||
|
; Junk; pads binary to end of page.
|
||
|
.align $0100
|
||
|
|