goapple2/source/progaid/hires.asm
2016-07-13 13:28:30 -06:00

625 lines
16 KiB
NASM

**************************
* *
* APPLE-II HI-RESOLUTION *
* GRAPHICS SUBROUTINES *
* *
* BY WOZ 9/13/77 *
* *
* ALL RIGHTS RESERVED *
* *
**************************
* HI-RES EQUATES
SHAPEL EQU $1A POINTER TO
SHAPEH EQU $1B SHAPE LIST
HCOLOR1 EQU $1C RUNNING COLOR MASK
COUNTH EQU $1D
HBASL EQU $26 BASE ADR FOR CURRENT
HBASH EQU $27 HI-RES PLOT LINE. A
HMASK EQU $30
A1L EQU $3C MONITOR A1.
A1H EQU $3D
A2L EQU $3E MONITOR A2.
A2H EQU $3F
LOMEML EQU $4A BASIC 'START OF VARS'.
MOMEMH EQU $4B
DXL EQU $50 DELTA-X FOR HLIN, SHAPE.
DXH EQU $51
SHAPEX EQU $51 SHAPE TEMP.
DY EQU $52 DELTA-Y FOR HLIN, SHAPE.
QDRNT EQU $53 ROT QUADRANT (SHAPE).
EL EQU $54 ERROR FOR HLIN.
EH EQU $55
PPL EQU $CA BASIC START OF PROG PTR.
PPH EQU $CB
PVL EQU $CC BASIC END OF VARS PTR.
PVH EQU $CD
ACL EQU $CE BASIC ACC.
ACH EQU $CF
X0L EQU $320 PRIOR X-COORD SAVE
X0H EQU $321 AFTER HLIN OR HPLOT.
Y0 EQU $322 HLIN, HPLOT Y-COORD SAVE.
BXSAV EQU $323 X-REG SAVE FOR BASIC.
HCOLOR EQU $324 COLOR FOR HPLOT, HPOSN
HNDX EQU $325 HORIZ OFFSET SAVE.
HPAG EQU $326 HI-RES PAGE ($20 NORMAL)
SCALE EQU $327 SCALE FOR SHAPE, MOVE.
SHAPXL EQU $328 START OF
SHAPXH EQU $329 SHAPE TABLE.
COLLSN EQU $32A COLLISION COUNT.
HIRES EQU $C057 SWITCH TO HI-RES VIDEO
MIXSET EQU $C053 SELECT TEXT/GRAPHICS MIX
TXTCLR EQU $C050 SELECT GRAPHICS MODE.
MEMFUL EQU $E36B BASIC MEM FULL ERROR.
RNGERR EQU $EE68 BASIC RANGE ERROR.
ACADR EQU $F11E 2-BYTE TAPE READ SETUP.
RD2BIT EQU $FCFA TWO-EDGE TAPE SENSE.
READ EQU $FEFD TAPE READ (A1.A2).
READX1 EQU $FF02 READ WITHOUT HEADER.
* HIGH RESOLUTION GRAPHICS INITS
*
* ROM VERSION $D000 TO $D3FF
*
ORG $D000
OBJ $A000
SETHRL LDA #$20 INIT FOR $2000-3FFF
STA HPAG HI-RES SCREEN MEMORY.
LDA HIRES SET HIRES DISPLAY MODE
LDA MIXSET WITH TEXT AT BOTTOM.
LDA TXTCLR SET GRAPHICS DISPLAY MODE
HCLR LDA #$0
BKGND0 STA HCOLOR1 SET FOR BLACK BKGND.
BKGND LDA HPAG
STA SHAPEH INIT HI-RES SCREEN MEM
LDY #$0 FOR CURRENT PAGE, NORMALLY
STY SHAPEL $2000-3FFF OR $4000-5FFF
BKGND1 LDA HCOLOR1
STA (SHAPEL),Y
JSR CSHFT2 (SHAPEL,H) WILL SPECIFY
INY 32 SEPARATE PAGES.
BNE BKGND1 THROUGHOUT THE INIT.
INC SHAPEH
LDA SHAPEH
AND #$1F TEST FOR DONE.
BNE BKGND1
RTS
* HI-RES GRAPHICS POSITION AND PLOT SUBRS
HPOSN STA Y0 ENTER WITH Y IN A-REG,
STX X0L XL IN X-REG,
STY X0H AND XH IN Y-REG.
PHA
AND #$C0
STA HBASL FOR Y-COORD = 00ABCDEF.
LSR ;CALCULATES BASE ADDRESS
LSR ;IN HBASL, HBASH FOR
ORA HBASL ACCESSING SCREEN MEM
STA HBASL VIA (HBASL),Y ADDRESSING MODE
PLA
STA HBASH
ASL ;CALCULATES
ASL ;HBASH = PPPFGHCD
ASL ;HBASL = EABAB000
ROL HBASH
ASL ;WHERE PPP=001 FOR $2000-3FFF
ROL HBASH SCREEN MEM RANGE AND
ASL ; PPP=010 FOR $4000-7FFF
ROR HBASL (GIVEN Y-COORD=ABCDEFGH)
LDA HBASH
AND #$1F
ORA HPAG
STA HBASH
TXA DIVIDE X0 BY 7 FOR
CPY #$0 INDEX FROM BASE ADR
BEQ HPOSN2 (QUOTIENT) AND BIT
LDY #$23 WITHIN SCREEN MEM BYTE
ADC #$4 (MASK SPEC'D BY REMAINDER)
HPOSN1 INY
HPOSN2 SBC #$7 SUBTRACT OUT SEVENS
BCS HPOSN1
STY HNDX WORKS FOR X0 FROM
TAX 0 TO 279, LOW-ORDER
LDA MSKTBL-249,X BYTE IN X-REG,
STA HMASK HIGH IN Y-REG ON ENTRY
TYA
LSR ; IF ON ODD BYTE (CARRY SET)
LDA HCOLOR THEN ROTATE HCOLOR ONE
HPOSN3 STA HCOLOR1 BIT FOR 180 DEGREE SHIFT
BCS CSHFT2 PRIOR TO COPYING TO HCOLOR1.
RTS
HPLOT JSR HPOSN
HPLOT1 LDA HCOLOR1 CALC BIT POSN IN HBASL,H
EOR (HBASL),Y HNDX, AND HMASK FROM
AND HMASK Y-COORD IN A-REG,
EOR (HBASL),Y X-COORD IN X,Y-REGS.
STA (HBASL),Y FOR ANY 'L' BITS OF HMASK
RTS SUBSTITUTE CORRESPONDING
* BIT OF HCOLOR1.
* HI-RES GRAPHICS L,R,U,D SUBRS
LFTRT BPL RIGHT USE SIGN FOR LFT/RT SELECT
LEFT LDA HMASK
LSR ; SHIFT LOW-ORDER
BCS LEFT1 7 BITS OF HMASK
EOR #$C0 ONE BIT TO LSB.
LR1 STA HMASK
RTS
LEFT1 DEY DECR HORIZ INDEX.
BPL LEFT2
LDY #$27 WRAP AROUND SCREEN.
LEFT2 LDA #$C0 NEW HMASK, RIGHTMOST
NEWNDX STA HMASK DOT OF BYTE.
STY HNDX UPDATE HORIZ INDEX.
CSHIFT LDA HCOLOR1
CSHFT2 ASL ; ROTATE LOW-ORDER
CMP #$C0 7 BITS OF HCOLOR1
BPL RTS1 ONE BIT POSN.
LDA HCOLOR1
EOR #$7F ZXYXYXYX -> ZYXYXYXY
STA HCOLOR1
RTS1 RTS
RIGHT LDA HMASK
ASL ; SHIFT LOW-ORDER
EOR #$80 7 BITS OF HMASK
BMI LR1 ONE BIT TO MSB.
LDA #$81
INY NEXT BYTE.
CPY #$28
BCC NEWNDX
LDY #$0 WRAP AROUND SCREEN IF >279
BCS NEWNDX ALWAYS TAKEN.
* L,R,U,D, SUBROUTINES.
LRUDX1 CLC NO 90 DEG ROT (X-OR).
LRUDX2 LDA SHAPEX
AND #$4 IF B2=0 THEN NO PLOT.
BEQ LRUD4
LDA #$7F FOR EX-OR INTO SCREEN MEM
AND HMASK
AND (HBASL),Y SCREEN BIT SET?
BNE LRUD3
INC COLLSN
LDA #$7F
AND HMASK
BPL LRUD3 ALWAYS TAKEN.
LRUD1 CLC NO 90 DEG ROT.
LRUD2 LDA SHAPEX
AND #$4 IF B2=0 THEN NO PLOT.
BEQ LRUD4
LDA (HBASL),Y
EOR HCOLOR1 SET HI-RES SCREEN BIT
AND HMASK TO CORRESPONDING HCOLOR1
BNE LRUD3 IF BIT OF SCREEN CHANGES
INC COLLSN THEN INCR COLLSN DETECT
LRUD3 EOR (HBASL),Y
STA (HBASL),Y
LRUD4 LDA SHAPEX ADD GDRNT TO
ADC QDRNT SPECIFIED VECTOR
AND #$3 AND MOVE LFT, RT,
EQ3 EQU *-1 UP, OR DWN BASED
CMP #$2 ON SIGN AND CARRY.
ROR
LRUD BCS LFTRT
UPDWN BMI DOWN4 SIGN FOR UP/DWN SELECT
UP CLC
LDA HBASH CALC BASE ADDRESS
BIT EQ1C (ADR OF LEFTMOST BYTE)
BNE UP4 FOR NEXT LINE UP
ASL HBASL IN (HBASL, HBASH)
BCS UP2 WITH 192-LINE WRAPAROUND
BIT EQ3
BEQ UP1
ADC #$1F **** BIT MAP ****
SEC
BCS UP3 FOR ROW = ABCDEFGH
UP1 ADC #$23
PHA
LDA HBASL HBASL = EABAB000
ADC #$B0 HBASH = PPPFGHCD
BCS UP5
ADC #$F0 WHERE PPP=001 FOR PRIMARY
UP5 STA HBASL HI-RES PAGE ($2000-$3FFF)
PLA
BCS UP3
UP2 ADC #$1F
UP3 ROR HBASL
UP4 ADC #$FC
UPDWN1 STA HBASH
RTS
DOWN CLC
DOWN4 LDA HBASH
ADC #$4 CALC BASE ADR FOR NEXT LINE
EQ4 EQU *-1 DOWN TO (HBASL,HBASH)
BIT EQ1C
BNE UPDWN1
ASL HBASL WITH 192-LINE WRAPAROUND
BCC DOWN1
ADC #$E0
CLC
BIT EQ4
BEQ DOWN2
LDA HBASL
ADC #$50
EOR #$F0
BEQ DOWN3
EOR #$F0
DOWN3 STA HBASL
LDA HPAG
BCC DOWN2
DOWN1 ADC #$E0
DOWN2 ROR HBASL
BCC UPDWN1
* HI-RES GRAPHICS LINE DRAW SUBRS
HLINRL PHA
LDA #$0 SET (X0L,X0H) AND
STA X0L Y0 TO ZERO FOR
STA X0H REL LINE DRAW
STA Y0 (DX, DY).
PLA
HLIN PHA ON ENTRY
SEC XL: A-REG
SBC X0L XH: X-REG
PHA Y: Y-REG
TXA
SBC X0H
STA QDRNT CALC ABS(X-X0)
BCS HLIN2 IN (DXL,DXH)
PLA
EOR #$FF X DIR TO SIGN BIT
ADC #$1 OF QDRNT.
PHA 0=RIGHT (DX POS)
LDA #$0 1=LEFT (DX NEG)
SBC QDRNT
HLIN2 STA SHAPEX
STA EH INIT (EL,EH) TO
PLA ABS(X-X0)
STA DXL
STA EL
PLA
STA X0L
STX X0H
TYA
CLC
SBC Y0 CALC -ABS(Y-0)-1
BCC HLIN3 IN DY.
EOR #$FF
ADC #$FE
HLIN3 STA DY ROTATE Y DIR INTO
STY Y0 QDRNT SIGN BIT
ROR QDRNT (0=UP, 1=DOWN)
SEC
SBC DXL INIT (COUNTL, COUNTH).
TAX TO -(DELTX+DELTY+1)
LDA #$FF
SBC DXH
STA COUNTH
LDY HNDX HORIZ INDEX
BCS MOVEX2 ALWAYS TAKEN.
MOVEX ASL ; MOVE IN X-DIR. USE
JSR LFTRT GDRNT B6 FOR LFT/RT SELECT
SEC
MOVEX2 LDA EL ASSUME CARRY SET.
ADC DY (EL,EH)-DELTY TO (EL,EH)
STA EL NOTE: DY IS (-DELTY)-1
LDA EH CARRY CLR IF (EL,EH)
SBC #$0 GOES NEG.
HCOUNT STA EH
LDA (HBASL),Y SCREEN BYTE.
EOR HCOLOR1 PLOT DOT OF HCOLOR1.
AND HMASK CURRENT BIT MASK.
EOR (HBASL),Y
STA (HBASL),Y
INX DONE (DELTX+DELTY)
BNE HLIN4 DOTS?
INC COUNTH
BEQ RTS2 YES, RETURN.
HLIN4 LDA QDRNT FOR DIRECTION TEST
BCS MOVEX IF CAR SET, (EL, EH) POS
JSR UPDWN IF CLR, NEG, MOVE YDIR
CLC
LDA EL (EL,EH)+DELTX
ADC DXL TO (EL,EH).
STA EL
LDA EH CAR SET IF (EL,EH) GOES POS
ADC DXH
BVC HCOUNT ALWAYS TAKEN
MSKTBL HEX 81 LEFTMOST BIT OF BYTE.
HEX 82,84,88
HEX 90,A0
HEX C0 RIGHTMOST BIT OF BYTE.
EQ1C HEX 1C
COS HEX FF,FE,FA,F4,EC,E1,D4,C5,B4
HEX A1,8D,78,61,49,31,18,FF
* HI-RES GRAPHICS COORDINATE RESTORE SUBR
HFIND LDA HBASL
ASL ; CONVERTS BASE ADR
LDA HBASH TO Y-COORD
AND #$3
ROL ; FOR HBASL = EABAB000
ORA HBASL HBASH = PPPFGHCD
ASL
ASL ; GENERATE
ASL ; Y-COORD = ABCDEFGH
STA Y0
LDA HBASH (PPP=SCREEN PAGE,
LSR ; NORMALLY 001 FOR
LSR ; $2000-$3FFF
AND #$7 HI-RES SCREEN)
ORA Y0
STA Y0 CONVERTS HNDX (INDEX
LDA HNDX FROM BASE ADR)
ASL ; AND HMASK (BIT
ADC HNDX MASK) TO X-COORD
ASL ; IN (X0L, X0H)
TAX (RANGE $0-$133)
DEX
LDA HMASK
AND #$7F
HFIND1 INX
LSR
BNE HFIND1
STA X0H
TXA
CLC CALC HNDX*7+
ADC HNDX LOG (BASE 2) HMASK.
BCC HFIND2
INC X0H
HFIND2 STA X0L
RTS2 RTS
* HI-RES GRAPHICS SHAPE DRAW SUBR
*
* SHAPE DRAW
* R = 0 TO 63
* SCALE FACTOR USED (1=NORMAL)
*
DRAW STX SHAPEL DRAW DEFINITION
STY SHAPEH POINTER
DRAW1 TAX
LSR ; ROT ($0=$3F)
LSR
LSR ; GRDNT 0=UP, 1=RT,
LSR ; 2=DWN, 3=LFT.
STA QDRNT
TXA
AND #$F
TAX
LDY COS,X SAVE COS AND SIN
STY DXL VALS IN DXL AND DY.
EOR #$F
TAX
LDY COS+1,X
INY
STY DY
DRAW2 LDY HNDX BYTE INDEX FROM
LDX #$0 HI-RES BASE ADR.
STX COLLSN CLEAR COLLISION COUNT.
LDA (SHAPEL,X) 1ST SHAPE DEF BYTE.
DRAW3 STA SHAPEX
LDX #$80
STX EL EL,EH FOR FRACTIONAL
STX EH L,R,U,D VECTORS.
LDX SCALE SCALE FACTOR.
DRAW4 LDA EL
SEC IF FRAC COS OVFL
ADC DXL THEN MOVE IN
STA EL SPECIFIED VECTOR
BCC DRAW5 DIRECTION.
JSR LRUD1
CLC
DRAW5 LDA EH IF FRAC SIN OVFL
ADC DY THEN MOVE IN
STA EH SPECIFIED VECTOR
BCC DRAW6 DIRECTION
JSR LRUD2
DRAW6 DEX LOOP ON SCALE
BNE DRAW4 FACTOR.
LDA SHAPEX
LSR ; NEXT 3-BIT VECTOR
LSR ; OF SHAPE DEF.
LSR
BNE DRAW3 NOT DONE THIS BYTE.
INC SHAPEL
BNE DRAW7 NEXT BYTE OF
INC SHAPEH SHAPE DEFINITION.
DRAW7 LDA (SHAPEL,X)
BNE DRAW3 DONE IF ZERO.
RTS
* HI-RES GRAPHICS SHAPE EX-OR SUBR
*
* EX-OR SHAPE INTO SCREEN.
*
* ROT = 0 TO 3 (QUADRANT ONLY)
* SCALE IS USED
*
XDRAW STX SHAPEL SHAPE DEFINITION
STY SHAPEH POINTER.
XDRAW1 TAX
LSR ; ROT ($0-$3F)
LSR
LSR ; GDRNT 0=UP, 1=RT,
LSR ; 2=DWN, 3=LFT.
STA QDRNT
TXA
AND #$F
TAX
LDY COS,X SAVE COS AND SIN
STY DXL VALS IN DXL AND DY,
EOR #$F
TAX
LDY COS+1,X
INY
STY DY
XDRAW2 LDY HNDX INDEX FROM HI-RES
LDX #$0 BASE ADR.
STX COLLSN CLEAR COLLISION DETECT
LDA (SHAPEL,X) 1ST SHAPE DEF BYTE.
XDRAW3 STA SHAPEX
LDX #$80
STX EL EL,EH FOR FRACTIONAL
STX EH L,R,U,D, VECTORS.
LDX SCALE SCALE FACTOR.
XDRAW4 LDA EL
SEC IF FRAC COS OVFL
ADC DXL THEN MOVE IN
STA EL SPECIFIED VECTOR
BCC XDRAW5 DIRECTION
JSR LRUDX1
CLC
XDRAW5 LDA EH IF FRAC SIN OVFL
ADC DY THEN MOVE IN
STA EH SPECIFIED VECTOR
BCC XDRAW6 DIRECTION +90 DEG.
JSR LRUD2
XDRAW6 DEX LOOP ON SCALE
BNE XDRAW4 FACTOR.
LDA SHAPEX
LSR ; NEXT 3-BIT VECTOR
LSR ; OF SHAPE DEF.
LSR
BNE XDRAW3
INC SHAPEL
BNE XDRAW7 NEXT BYTE OF
INC SHAPEH SHAPE DEF.
XDRAW7 LDA (SHAPEL,X)
BNE XDRAW3 DONE IF ZERO.
RTS
* ENTRY POINTS FROM APPLE-II BASIC
BPOSN JSR PCOLR POSN CALL, COLR FROM BASIC
STA HCOLOR
JSR GETY0 Y0 FROM BASIC.
PHA
JSR GETX0 X0 FROM BASIC.
PLA
JSR HPOSN
LDX BXSAV
RTS
BPLOT JSR BPOSN PLOT CALL (BASIC).
JMP HPLOT1
BLIN1 LDA HNDX
LSR ; SET HCOLOR1 FROM
JSR PCOLR BASIC VAR COLR.
JSR HPOSN3
BLINE JSR GETX0 LINE CALL, GET X0 FROM BASIC
TXA
PHA
TYA
TAX
JSR GETY0 Y0 FROM BASIC
TAY
PLA
JSR HLIN
LDX BXSAV
RTS
BGND JSR PCOLR BACKGROUND CALL
JMP BKGND0
* DRAW ROUTINES
BDRAW1 JSR BPOSN
BDRAW JSR BDRAWX DRAW CALL FROM BASIC.
JSR DRAW
LDX BXSAV
RTS
BXDRW1 JSR BPOSN
BXDRAW JSR BDRAWX EX-OR DRAW
JSR XDRAW FROM BASIC.
LDX BXSAV
RTS
BDRAWX STX BXSAV SAVE FOR BASIC.
LDY #$32
JSR PBYTE SCALE FROM BASIC.
STA SCALE
LDY #$28
JSR PBYTE ROT FROM BASIC.
PHA SAVE ON STACK.
LDA SHAPXL
STA SHAPEL START OF
LDA SHAPXH SHAPE TABLE.
STA SHAPEH
LDY #$20
JSR PBYTE SHAPE FROM BASIC.
BEQ RERR1
LDX #$0
CMP (SHAPEL,X) > NUM OF SHAPES?
BEQ BDRWX1
BCS RERR1 YES, RANGE ERR.
BDRWX1 ASL
BCC BDRWX2
INC SHAPEH
CLC
BDRWX2 TAY SHAPE NO. * 2.
LDA (SHAPEL),Y
ADC SHAPEL
TAX ADD 2-BYTE INDEX
INY TO SHAPE TABLE
LDA (SHAPEL),Y START ADR
ADC SHAPXH (X LOW, Y HI).
TAY
PLA ROT FROM STACK.
RTS
* BASIC PARAM FETCH SUBR'S
PCOLR LDY #$16
PBYTE LDA (LOMEML),Y
BNE RERR1 GET BASIC PARAM.
DEY (ERR IF >255)
LDA (LOMEML),Y
RTSB RTS
GETX0 STX BXSAV SAVE FOR BASIC.
LDY #$5
LDA (LOMEML),Y X0 LOW-ORDER BYTE.
TAX
INY
LDA (LOMEML),Y HI-ORDER BYTE.
TAY
CPX #$18
SBC #$1 RANGE ERR IF >279
BCC RTSB
RERR1 JMP RNGERR
GETY0 LDY #$D OFFSET TO Y0 FROM LOMEM
JSR PBYTE GET BASIC PARAM Y0.
CMP #$C0 (ERR IF >191)
BCS RERR1
RTS
* SHAPE TAPE LOAD SUBROUTINE
SHLOAD STX BXSAV SAVE FOR BASIC.
JSR ACADR READ 2-BYTE LENGTH INTO
JSR READ BASIC ACC
LDA #$00 ;START OF SHAPE TABLE IS $0800
STA A1L
STA SHAPXL
CLC
ADC ACL
TAY
LDA #$08 ;HIGH BYTE OF SHAPE TABLE POINTER.
STA A1H
STA SHAPXH
ADC ACH
BCS MFULL1 NOT ENOUGH MEMORY.
CPY PPL
PHA
SBC PPH
PLA
BCS MFULL1
STY A2L
STA A2H
INY
BNE SHLOD1
ADC #$1
SHLOD1 STY LOMEML
STA MOMEMH
STY PVL
STA PVH
JSR RD2BIT
LDA #$3 .5 SECOND HEADER.
JSR READX1
LDX BXSAV
RTS
MFULL1 JMP MEMFUL