transformer/GRAF.SRC/GRAF.S

539 lines
12 KiB
ArmAsm

REL
DSK GRAF.L
JMP INIT
LST OFF
USE 4/DOS.16.MACS
USE 4/EVENT.MACS
USE 4/INT.MACS
USE 4/LOCATOR.MACS
USE 4/MACROS
USE 4/MEM.MACS
USE 4/SANE.MACS
USE 4/UTIL.MACS
USE GRAF.MACROS
USE FIXED.MACROS
USE DP.TABLE
PUT VIDEO.EQUATES
**************************************************
EXT DrawRectangle
EXT PaletteTable
EXT Bresenham
EXT DrawShape
EXT DrawShape2
EXT RotateVertex
EXT ClearScreen
**************************************************
* Data...
mmID ds 2
old_DP ds 2 ;store the DP so we can restore it on exit
old_SP ds 2 ;store the SP so we can restore it on exit
DP_ptr ds 2 ;pointer to direct-page bank
DP_hndl ds 4
ScratchPtr ds 4 ;a scratch memory pointer
fixed_test_1 ds 4
fixed_test_2 ds 4
fixed_test_3 ds 4
fixed_HALF adrl $00008000 ; 0.5000
INT_scratch_1 ds 2
INT_scratch_2 ds 2
INT_scratch_3 ds 3
INT_65535 = $FFFF
degrees_to_rotate ds 2
**************************************************
* Tool Startup structures
StartStopRef ds 4 ; reference to StartStopRec
StartStopRec
dw 0 ; must be 0
dw $0 ; QD 320px
ds 2 ; resFileID
ds 4 ; dPageHandle
dw 4 ; Number of tools to start
ToolsList
dw 3,$0100 ; Misc Tools
dw 6,$0100 ; Event Manager
dw 10,$0100 ; SANE
dw 11,$0100 ; Integer Math
evtMouseDown = 1
evtKeyDown = 3
**************************************************
* Event Manager record
EventRecord
evtWhat ds 2
evtMsg ds 4
evtWhen ds 4
evtWhere ds 4
evtMods ds 2 ; Modifiers
**************************************************
* Strings *
str_Title ASC "THE VALUE OF 100 * COS(45) IS: ",00
str_lol ASC "PLUS A BUNCH OF FRACTIONAL JUNK",00
; Room for 16 characters
str_IntMath db 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
* Decimal and fractional strings for printing a FIXED value.
str_fx1 db 00,00,00,00,00,00,00,00,00
str_fx2 db 00,00,00,00,00,00,00,00,00
**************************************************
INIT MX %00 ;16-bit mode
PHK
PLB ;data bank = program bank
TDC
STA old_DP ;store the DP as of the start of program
TSC
STA old_SP ;store the SP as of the start of program
TOOLS _TLStartUp
~MMStartUp ; Memory Manager
* _IMStartUp ; Integer Tools
PLA
STA mmID ;get our Memory Manager ID
* Start up the remaining tools.
PushLong #0
PushWord mmID
PEA #0
PushLong #StartStopRec
_StartupTools
PullLong StartStopRef
* Allocate some direct page memory
PushLong #0
PushLong #$300 ;3 pages
PushWord mmID
PushWord #$C001 ;Locked, fixed, fixed bank
PushLong #0
_NewHandle
* Dereference the handle.
PLX ; X = low 16 bits of handle
PLA ; A = high 16 bits of handle
PHD ;save caller's direct page register
PHA ; push high word
PHX ;push low word
TSC ;get stack pointer in A
TCD ;and put it in D
LDA [1] ;get low word of master pointer
TAX ;and put it in X
LDY #$0002 ;offset to high word of master pointer
LDA [1],Y ;get high word
PLY ;remove low word of handle
PLY ;and high word
PLD ;restore caller's direct page register
* A,X is now nnHHMMLL. Since this is a direct page pointer,
* all we care about is MMLL.
STX DP_ptr
TXA
TCD ;and now we have our own direct page
CLC
ADC #$200
PHA ;push address of direct-page bank
_SANEStartUp ;start SANE
LDA #GS_PixelData
STA $00 ;$00 = ptr to current pixel
START LDA #0
JSR SetSCBs
LDA #0
JSR ClearToColor
JSR EnableSHR
LDA #$FFFF
STA penColor
LDA #0
M_FX_INIT #fixed_test_1
M_FX_INIT #fixed_test_2
M_FX_INIT #fixed_test_3
LDA #45
STA degrees_to_rotate
**************************************************
EventLoop
* Let's play with the Integer tools!
PushWord degrees_to_rotate
PushLong #shape_Square
JSR RotateShape2
PullLong
PullWord ;clean stack
JSR ClearScreen
M_DrawShape2 #shape_Square;#100;#100
* Are there any events waiting for us?
PushWord #0 ;result
PushWord #$000A ;event mask
PushLong #EventRecord
_EventAvail ; nulls out EventRecord if there's no event
:eventAvailable
* Look for keydown and mouse button 0 down
PushWord #0
PushWord #$000A
PushLong #EventRecord
_GetNextEvent
:isThisOurEvent
PLA ; A = 0 if not our event
CMP #0
BEQ :done
:checkEventDetails
LDA evtWhat
CMP #evtMouseDown ; is this a mouse button 0 event?
BEQ EXIT
CMP #evtKeyDown ; is this a key event?
BNE :done
* This is a key event.
* TODO: uh, something
* Finally...
:done
INC degrees_to_rotate
* Uncomment this line to loop
JMP EventLoop
Waiting
JSR WaitKey
JMP EXIT
**************************************************
* Stuff to do when we exit.
EXIT
PEA #0
PushLong #StartStopRef
_ShutdownTools ; orderly shutdown of our opened tools
_DisposeAll ; release all owned memory handles
_MMShutDown
_TLShutDown
JSL $E100A8 ; and exit the application
DW $2029
ADRL #QuitParms
QuitParms ADRL $00000000
DW $0000
**************************************************
CalculatePixelOffset
* Input coordinates in dp addrs dest_X and dest_Y
* Outputs to dest_Offset
LDY dest_Y
LDA dest_X
LSR
:loop
CPY #0 ;each Y = 160 bytes added to A
BEQ :done
CLC
ADC #BYTES_PER_LINE
DEY
BRA :loop
:done
STA dest_Offset ;store the destination
RTS
**************************************************
RotateShape2
* B,S = WORD number of degrees to rotate
* 7,S = LONG pointer to shape data structure
* 5,S = return address
* 3,S = WORD number of vertices in shape
* 1,S = vertex we're on
LDA #0
PHA
PHA
* How many vertices are there in this shape?
LDA #0
LDY #0
SHORT
LDA ($7,S),Y
LONG
STA $3,S
LDA $7,S
STA ptr_Long_Shape
LDA $9,S
STA ptr_Long_Shape+2
INC ptr_Long_Shape
* ptr_Long_Shape is the source.
* Calculate ptr_RotatedVertices with the following formula:
* ptr_RotatedVertices = ptr_Long_Shape + (8 * vertex_count)
LDA $3,S
ASL
ASL
ASL ; multiply vertex count by 8
CLC
ADC ptr_Long_Shape
STA ptr_RotatedVertices ; and construct the pointer with it
LDA ptr_Long_Shape+2
STA ptr_RotatedVertices+2
:nextVertex
* Vertex 1
PushWord $B,S
PushLong ptr_Long_Shape
JSR RotateVertex
* Store the X vertex
M_MoveLongToPtr fx_RotatedX;(ptr_RotatedVertices)
LDA ptr_Long_Shape
CLC
ADC #4
STA ptr_Long_Shape
LDA ptr_RotatedVertices
CLC
ADC #4
STA ptr_RotatedVertices
* And store the Y vertex
M_MoveLongToPtr fx_RotatedY;(ptr_RotatedVertices)
LDA ptr_Long_Shape
CLC
ADC #4
STA ptr_Long_Shape
LDA ptr_RotatedVertices
CLC
ADC #4
STA ptr_RotatedVertices
LDA $1,S
INC
STA $1,S
CMP $3,S
BNE :nextVertex
BRA :done
:done
PLA
PLA
RTS
**************************************************
ResetIntMathString
LDA #0
LDY #15
:loop STA str_IntMath,Y
CPY #0
BEQ :done
DEY
BRA :loop
:done
RTS
**************************************************
DrawString ;keep doing DrawGlyph until we hit a $00
PHA ;local variable
this_glyph = $1,S ;
ptr_String = $5,S ;input, the string pointer
:getNextCharLoop
LDY #0
LDA ($5,S),Y ;grab the character we need
AND #$007F ;strip the high bit
CMP #0 ;NUL?
BEQ :done
* Okay, now draw this character code.
STA this_glyph
M_DrawGlyph this_glyph;dest_X;dest_Y
LDA $5,S
INC
STA $5,S ;next character
LDA dest_X
CLC
ADC #8
STA dest_X ;advance a character cell
BRA :getNextCharLoop
:done
PLA ;destroy local variable
RTS
**************************************************
DrawGlyph ;Just draw the glyph_A for now
;at (X,Y)
:init
LDA #0
STA glyph_sl_drawn
JSR CalculatePixelOffset ;stores this in dest_Offset
JMP :makePtr
:makePtr
LDA $3,S ; Get the glyph from the stack
SEC
SBC #$20 ; subtract $20 to get the offset into the table
ASL ; multiply the char by 2 to get the offset
TAY
LDA ASCIIGlyphs,Y
STA ptr_Glyph
SHORT
PHB
PLA
LONG
AND #$00FF
STA ptr_Glyph+2 ;constructed a 24-bit pointer.
:draw
* A glyph is 8x6.
PHB
SetDBR #$E1
LDY #0
LDX dest_Offset
:drawScanline
LDA [ptr_Glyph],Y
STA $2000,X
INX
INX
INY
INY
LDA [ptr_Glyph],Y
STA $2000,X
DEX ;Back to byte 0
DEX
INY
INY
* Next scanline.
TXA
CLC
ADC #BYTES_PER_LINE ;move to next scanline
TAX
INC glyph_sl_drawn
LDA glyph_sl_drawn
CMP #6
BEQ :doneDrawing
BRA :drawScanline
:doneDrawing
PLB
RTS
**************************************************
* Load the palette
LoadPalette
LDX #0
:loop
LDA PaletteTable,X
STAL GS_Palettes,X ;set palette 0 color 0
INX
INX
CMP #32
BNE :loop
RTS
* Enable Super Hi-Res graphics
EnableSHR
SHORT
LDAL $00C029
ORA #$C0 ; Enable SHR and linear VRAM
STAL $00C029 ; New Video Register
LONG
RTS
* Clear screen to one solid color in A.
ClearToColor
LDX #$7D00 ; Pixel data is $E12000-$E19D00
:clearLoop
DEX
DEX
STAL $E12000,X ; pixel location
BNE :clearLoop ; loop until X == 0
RTS
* Sets all Scanline Control Bits to A.
SetSCBs
LDX #$0100
:scbLoop
DEX
DEX
STAL $E19D00,X
BNE :scbLoop
RTS
* Wait for a keypress.
WaitKey
SEP #$30 ; 8-bit mode
:wait LDAL $00C000 ; Apple II keyboard register
BPL :wait
STAL $00C010
REP #$30 ; 16-bit mode
RTS
**************************************************
shape_Square
db 4 ; how many vertices in the shape?
* Each M_FX_VERTEX specifies one vertex.
shape_Square_vertices
M_FX_VERTEX #-20;#-20
M_FX_VERTEX #20;#-20
M_FX_VERTEX #20;#20
M_FX_VERTEX #-20;#20
* And then leave room at the end for the transformed vertices.
shape_Square_transformed
ds 8
ds 8
ds 8
ds 8
**************************************************
glyph_data ; Marks the start of the glyphs.
PUT GLYPH