************************** * * * 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