AppleIIAsm-Collection/documentation/AppleIIAsm Library Collecti.../0.6.1/38.0 Detailed_Reference_D9_...

112 KiB

Disk 9: HiRes


HiRes Components

The HiRes collection contains the following components:

  • A header file that includes hooks and vectors for plotting and displaying high resolution graphics.
  • Tables that are used for fast division by seven, memory mapping, and character bitmaps.
  • A macro library that includes all of the macros used for high resolution graphics.
  • Subroutines used by the macros.
  • A demonstration file that illustrates how each macro works.

HiRes Collection Header File

Condition Value
Name File: HEAD.HIRES.ASM
Type Header File
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin 8 Pro
OS Apple DOS 3.3
Purpose Provide appropriate hooks and routines for the HiRes Collection
Dependencies none
Bytes 16
Notes none
See Also none

DETAILS

The HiRes header file contains hooks and vectors for using high resolution graphics. In the future, this will also contain a dedicated and optimized plotting routine for use by the rest of the collection.

LISTING 9.00: HEAD.HIRES.ASM Source

*
*``````````````````````````````*
* HEAD.HIRES.ASM               *
*                              *
* THIS IS THE HEADER FILE FOR  *
* HIRES SUBROUTINES AND        *
* MACROS. THIS HEADER IS       *
* REQUIRED TO INCLUDE FOR ALL  *
* HIRES COLLECTION FUNCTIONS.  *
*                              *
* AUTHOR:     NATHAN RIGGS     *
* CONTACT:    NATHAN.RIGGS@    *
*             OUTLOOK.COM      *
*                              *
* DATE:       31-MAY-2021      *
* ASSEMBLER:  MERLIN 8 PRO     *
* OS:         DOS 3.3          *
*                              *
* SIZE: 16 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]ADDR    EQU   ADDR2
]HXHI    EQU   WPAR1+1
]HXLO    EQU   WPAR1
]HY      EQU   BPAR1
HGR      EQU   $F3E2      ; APPLESOFT HGR SUBROUTINE
AHCOLOR  EQU   $F6F0      ; APPLESOFT COLOR SET SUBROUTINE
AHPLOT   EQU   $F457      ; APPLESOFT PLOTTING SUBROUTINE
AHPOSN   EQU   $F411      ; APPLESOFT POSITION SUBROUTINE
AHLIN    EQU   $F53A      ; APPLESOFT LINE PLOT SUBROUTINE
AHGBAS   EQU   $26        ; APPLESOFT GET HIRES LOCATION
AHPAG    EQU   $E6        ; APPLESOFT SET PAGE
AHNDX    EQU   $E5
AHBIT    EQU   $30
AROT     EQU   $F9        ; APPLESOFT ROTATION VALUE
ASCALE   EQU   $E7        ; APPLESOFT SCALE VALUE
ASHNUM   EQU   $F730      ; APPLESOFT SHAPE NUMBER
ADRAW    EQU   $F605      ; APPLESOFT SHAPE DRAW SUBROUTINE
AXDRAW   EQU   $F661      ; APPLESOFT SHAPE XDRAW SUBROUTINE
*
GRAPHICS EQU   $C050      ; GRAPHICS SOFT SWITCH
HIRES    EQU   $C057      ; HIRES SOFT SWITCH
HPAGE1   EQU   $C054      ; PAGE 1 SOFT SWITCH
HMIXOFF  EQU   $C052      ; MIXED MODE OFF SOFT SWITCH
HPAGE2   EQU   $C055      ; PAGE 2 SOFT SWITCH
HMIXON   EQU   $C053      ; MIXED MODE ON SOFT SWITCH
HTEXTM   EQU   $C051      ; TEXT MODE SOFT SWITCH
IIESET   EQU   $A0        ; START OF CHARACTERS ON THE IIE
LOWSET   EQU   $80        ; OFFSET TO LOWERCASE FOR OLDER SYSTEMS
*
         JMP   _HRSKIP
*
** THESE ARE MASK VALUES FOR THE EVEN AND ODD
** BYTE LOCATIONS OF THE HIRES SCREEN
*
CT_EVEN  HEX   00         ; {0C1B} BLACK 1
         HEX   2A         ; {0C1B} GREEN
         HEX   55         ; {0C1B} VIOLET
         HEX   7F         ; {0C1B} WHITE 1
         HEX   80         ; {0C1B} BLACK 2
         HEX   AA         ; {0C1B} ORANGE
         HEX   D5         ; {OC1B} BLUE
         HEX   FF         ; {0C1B} WHITE 2
CT_ODD   HEX   00         ; {0C1B} BLACK 1
         HEX   55         ; {0C1B} GREEN
         HEX   2A         ; {0C1B} VIOLET
         HEX   7F         ; {0C1B} WHITE 1
         HEX   80         ; {0C1B} BLACK 2
         HEX   D5         ; {0C1B} ORANGE
         HEX   AA         ; {0C1B} BLUE
         HEX   FF         ; {0C1B} WHITE 2
*
** HIRES COLOR CODES
*
HBLACK1  EQU   $00
HGREEN   EQU   $01
HPURPLE  EQU   $02
HWHITE1  EQU   $03
HBLACK2  EQU   $04
HORANGE  EQU   $05
HBLUE    EQU   $06
HWHITE2  EQU   $07
*
HOFFSET  DS    1,0        ; WORKING PAGE OFFSET
*
*``````````````````````````````*
* _HPLOT                       *
*                              *
* THIS WILL BE ADDED IN THE    *
* FUTURE ONCE THE PLOTTING     *
* SUBROUTINE IS OPTIMIZED.     *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
*
_HRSKIP
*

HiRes Tables

The HiRes collection contains three primary tables that must be included in any program utilizing the collection in order for them to work properly (or at all). This includes the TBL.DB7.ASM table, for fast division by seven, the TBL.HIRES.ASM table for calculating HiRes page memory addresses and the TBL.HRCHAR.ASM table, which holds the bitmaps of the characters used in printing text on the HiRes screen. In use for complicated projects, it would be more useful to place these tables in unused non-contiguous areas of memory; for instance, as long as the text pages are going unused they can be utilized to hold these tables.

LISTING 9.01: The TBL.DB7.ASM Source

*
*``````````````````````````````*
* DIVIDE BY SEVEN RESULTS      *
*                              *
* THIS TABLE IS USED FOR FAST  *
* DIVISION BY 7 IN THE HIRES   *
* GRAPHICS COLLECTION.         *
*                              *
* SIZE: 588 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
*ORG $0800 ; HOLD IN TEXT PAGE 2 MEMORY
*
DB7RES   HEX   00000000000000
         HEX   01010101010101
         HEX   02020202020202
         HEX   03030303030303
         HEX   04040404040404
         HEX   05050505050505
         HEX   06060606060606
         HEX   07070707070707
         HEX   08080808080808
         HEX   09090909090909
         HEX   0A0A0A0A0A0A0A
         HEX   0B0B0B0B0B0B0B
         HEX   0C0C0C0C0C0C0C
         HEX   0D0D0D0D0D0D0D
         HEX   0E0E0E0E0E0E0E
         HEX   0F0F0F0F0F0F0F
         HEX   10101010101010
         HEX   11111111111111
         HEX   12121212121212
         HEX   13131313131313
         HEX   14141414141414
         HEX   15151515151515
         HEX   16161616161616
         HEX   17171717171717
         HEX   18181818181818
         HEX   19191919191919
         HEX   1A1A1A1A1A1A1A
         HEX   1B1B1B1B1B1B1B
         HEX   1C1C1C1C1C1C1C
         HEX   1D1D1D1D1D1D1D
         HEX   1E1E1E1E1E1E1E
         HEX   1F1F1F1F1F1F1F
         HEX   20202020202020
         HEX   21212121212121
         HEX   22222222222222
         HEX   23232323232323
         HEX   24242424242424
         HEX   25252525252525
         HEX   26262626262626
         HEX   27272727272727
         HEX   28282828282828
         HEX   29292929292929
*
*``````````````````````````````*
* DIVIDE BY SEVEN REMAINDER    *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
DB7REM   HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040
         HEX   01020408102040

LISTING 9.02: The TBL.HIRES.ASM Source

*
*``````````````````````````````*
* HIRES ADDRESS LOOKUP HIBYTE  *
*                              *
* THIS IS THE MEMORY LOCATION  *
* LOOKUP TABLE FOR HIRES       *
* PLOTTING.                    *
*                              *
* SIZE: 384 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
*ORG $0400 ; STORE ON TEXT PAGE 1
*
HGRHI    HEX   2024282C3034383C
         HEX   2024282C3034383C
         HEX   2125292D3135393D
         HEX   2125292D3135393D
         HEX   22262A2E32363A3E
         HEX   22262A2E32363A3E
         HEX   23272B2F33373B3F
         HEX   23272B2F33373B3F
         HEX   2024282C3034383C
         HEX   2024282C3034383C
         HEX   2125292D3135393D
         HEX   2125292D3135393D
         HEX   22262A2E32363A3E
         HEX   22262A2E32363A3E
         HEX   23272B2F33373B3F
         HEX   23272B2F33373B3F
         HEX   2024282C3034383C
         HEX   2024282C3034383C
         HEX   2125292D3135393D
         HEX   2125292D3135393D
         HEX   22262A2E32363A3E
         HEX   22262A2E32363A3E
         HEX   23272B2F33373B3F
         HEX   23272B2F33373B3F
*
*``````````````````````````````*
* HIRES ADDRESS LOOKUP LOBYTE  *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HGRLO    HEX   0000000000000000
         HEX   8080808080808080
         HEX   0000000000000000
         HEX   8080808080808080
         HEX   0000000000000000
         HEX   8080808080808080
         HEX   0000000000000000
         HEX   8080808080808080
         HEX   2828282828282828
         HEX   A8A8A8A8A8A8A8A8
         HEX   2828282828282828
         HEX   A8A8A8A8A8A8A8A8
         HEX   2828282828282828
         HEX   A8A8A8A8A8A8A8A8
         HEX   2828282828282828
         HEX   A8A8A8A8A8A8A8A8
         HEX   5050505050505050
         HEX   D0D0D0D0D0D0D0D0
         HEX   5050505050505050
         HEX   D0D0D0D0D0D0D0D0
         HEX   5050505050505050
         HEX   D0D0D0D0D0D0D0D0
         HEX   5050505050505050
         HEX   D0D0D0D0D0D0D0D0

LISTING 9.03: The TBL.HRCHAR.ASM Source

*
*``````````````````````````````*
* HIRES CHARACTER TABLE        *
*                              *
* THIS TABLE HOLDS THE BITMAPS *
* OF THE HIRES CHARACTERS FOR  *
* PLOTTING TO THE HIRES PAGES. *
*                              *
* SIZE: 760 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
*ORG $0800 ; ON TEXT PAGE 1
*
HRCTBL
*
HRT_SPC
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
HRT_EXC
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0000000
         DB    %0001100
         DB    %0000000
HRT_QUO
         DB    %0110011
         DB    %0110011
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
HRT_PND
         DB    %0010110
         DB    %0010110
         DB    %0111111
         DB    %0010110
         DB    %0111111
         DB    %0010110
         DB    %0010110
         DB    %0000000
HRT_DOL
         DB    %0001100
         DB    %0111110
         DB    %0001101
         DB    %0011110
         DB    %0101100
         DB    %0011111
         DB    %0001100
         DB    %0000000
HRT_PCT
         DB    %0110011
         DB    %0110011
         DB    %0011000
         DB    %0001100
         DB    %0000110
         DB    %0110011
         DB    %0110011   ; %
         DB    %0000000
HRT_AMP
         DB    %0000010   ; &
         DB    %0000101
         DB    %0000101
         DB    %0000010
         DB    %0010101
         DB    %0001001
         DB    %0010110
         DB    %0000000
HRT_APO
         DB    %0001100
         DB    %0001100
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
HRT_LPA
         DB    %0011000
         DB    %0001100
         DB    %0000110
         DB    %0000110
         DB    %0000110
         DB    %0001100
         DB    %0011000
         DB    %0000000
HRT_RPA
         DB    %0000110
         DB    %0001100
         DB    %0011000
         DB    %0011000
         DB    %0011000
         DB    %0001100
         DB    %0000110
         DB    %0000000
HRT_AST
         DB    %0101101
         DB    %0011110
         DB    %0001100
         DB    %0111111
         DB    %0001100
         DB    %0011110
         DB    %0101101
         DB    %0000000
HRT_ADD
         DB    %0000000
         DB    %0001100
         DB    %0001100
         DB    %0111111
         DB    %0001100
         DB    %0001100
         DB    %0000000
         DB    %0000000
HRT_COM
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0011110
         DB    %0011110
         DB    %0011000
         DB    %0000100
HRT_SUB
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0011110
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
HRT_PRD
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0011110
         DB    %0011110
         DB    %0000000
HRT_FSL
         DB    %0110000
         DB    %0110000
         DB    %0011000
         DB    %0001100
         DB    %0000110
         DB    %0000011
         DB    %0000011
         DB    %0000000
HRT_0
         DB    %0011110
         DB    %0110011
         DB    %0111011
         DB    %0111011
         DB    %0110111
         DB    %0110111
         DB    %0011110
         DB    %0000000
HRT_1
         DB    %0001100
         DB    %0001110
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0111111
         DB    %0000000
HRT_2
         DB    %0011110
         DB    %0110011
         DB    %0011000
         DB    %0001100
         DB    %0000110
         DB    %0000011
         DB    %0111111
         DB    %0000000
HRT_3
         DB    %0111111
         DB    %0110000
         DB    %0011000
         DB    %0001100
         DB    %0011000
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_4
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0111111
         DB    %0110000
         DB    %0110000
         DB    %0110000
         DB    %0000000
HRT_5
         DB    %0111111
         DB    %0000011
         DB    %0001111
         DB    %0011000
         DB    %0110000
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_6
         DB    %0011000
         DB    %0001100
         DB    %0000110
         DB    %0011011
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_7
         DB    %0111111
         DB    %0110000
         DB    %0011000
         DB    %0001100
         DB    %0000110
         DB    %0000011
         DB    %0000011
         DB    %0000000
HRT_8
         DB    %0011110
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_9
         DB    %0011110
         DB    %0110011
         DB    %0110011
         DB    %0111110
         DB    %0110000
         DB    %0011000
         DB    %0001110
         DB    %0000000
HRT_COL
         DB    %0000000
         DB    %0001100
         DB    %0001100
         DB    %0000000
         DB    %0001100
         DB    %0001100
         DB    %0000000
         DB    %0000000
HRT_SEM
         DB    %0000000
         DB    %0001100
         DB    %0001100
         DB    %0000000
         DB    %0001100
         DB    %0001100
         DB    %0000110
         DB    %0000000
HRT_LT
         DB    %0110000
         DB    %0011000
         DB    %0001100
         DB    %0000011
         DB    %0001100
         DB    %0011000
         DB    %0110000
         DB    %0000000
HRT_EQ
         DB    %0000000
         DB    %0000000
         DB    %0011110
         DB    %0000000
         DB    %0011110
         DB    %0000000
         DB    %0000000
         DB    %0000000
HRT_GT
         DB    %0000011
         DB    %0000110
         DB    %0001100
         DB    %0110000
         DB    %0001100
         DB    %0000110
         DB    %0000011
         DB    %0000000
HRT_QUE
         DB    %0011110
         DB    %0110011
         DB    %0110000
         DB    %0001100
         DB    %0001100
         DB    %0000000
         DB    %0001100
         DB    %0000000
HRT_AT
         DB    %0000000
         DB    %0111111
         DB    %0100001
         DB    %0111101
         DB    %0111101
         DB    %0000001
         DB    %0111111
         DB    %0000000
HRT_A
         DB    %0011110
         DB    %0110011
         DB    %0110011
         DB    %0111111
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0000000
HRT_B
         DB    %0011111
         DB    %0110011
         DB    %0110011
         DB    %0011111
         DB    %0110011
         DB    %0110011
         DB    %0011111
         DB    %0000000
HRT_C
         DB    %0011110
         DB    %0110011
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_D
         DB    %0011111
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0011111
         DB    %0000000
HRT_E
         DB    %0111111
         DB    %0000011
         DB    %0000011
         DB    %0011111
         DB    %0000011
         DB    %0000011
         DB    %0111111
         DB    %0000000
HRT_F
         DB    %0111111
         DB    %0000011
         DB    %0000011
         DB    %0011111
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0000000
HRT_G
         DB    %0111111
         DB    %0000011
         DB    %0000011
         DB    %0111011
         DB    %0110011
         DB    %0110011
         DB    %0111111
         DB    %0000000
HRT_H
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0111111
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0000000
HRT_I
         DB    %0111111
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0111111
         DB    %0000000
HRT_J
         DB    %0111100
         DB    %0110000
         DB    %0110000
         DB    %0110000
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_K
         DB    %0110011
         DB    %0011011
         DB    %0001111
         DB    %0000111
         DB    %0001111
         DB    %0011011
         DB    %0110011
         DB    %0000000
HRT_L
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0111111
         DB    %0000000
HRT_M
         DB    %0100001
         DB    %0110011
         DB    %0101101
         DB    %0100001
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0000000
HRT_N
         DB    %0110011
         DB    %0110111
         DB    %0110111
         DB    %0111011
         DB    %0111011
         DB    %0110011
         DB    %0110011
         DB    %0000000
HRT_O
         DB    %0011110
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_P
         DB    %0011111
         DB    %0110011
         DB    %0110011
         DB    %0011111
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0000000
HRT_Q
         DB    %0011110
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0111011
         DB    %0111011
         DB    %0011110
         DB    %0100000
HRT_R
         DB    %0011111
         DB    %0110011
         DB    %0110011
         DB    %0011111
         DB    %0001111
         DB    %0011011
         DB    %0110011
         DB    %0000000
HRT_S
         DB    %0011110
         DB    %0110011
         DB    %0000110
         DB    %0011100
         DB    %0110000
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_T
         DB    %0111111
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0000000
HRT_U
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_V
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0001100
         DB    %0000000
HRT_W
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0100001
         DB    %0101101
         DB    %0110011
         DB    %0100001
         DB    %0000000
HRT_X
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0001100
         DB    %0011110
         DB    %0110011
         DB    %0110011
         DB    %0000000
HRT_Y
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0000000
HRT_Z
         DB    %0111111
         DB    %0110000
         DB    %0011000
         DB    %0001100
         DB    %0000110
         DB    %0000011
         DB    %0111111
         DB    %0000000
HRT_LBR
         DB    %0001111
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0001111
         DB    %0000000
HRT_BSL
         DB    %0000011
         DB    %0000011
         DB    %0000110
         DB    %0001100
         DB    %0011000
         DB    %0110000
         DB    %0110000
         DB    %0000000
HRT_RBR
         DB    %0111100
         DB    %0110000
         DB    %0110000
         DB    %0110000
         DB    %0110000
         DB    %0110000
         DB    %0111100
         DB    %0000000
HRT_CRT
         DB    %0001100
         DB    %0011110
         DB    %0110011
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
HRT_UND
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0011111
         DB    %0000000
HRT_ACC
         DB    %0000110
         DB    %0001100
         DB    %0011000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
HRT_ALOW
         DB    %0000000
         DB    %0000000
         DB    %0110110
         DB    %0111011
         DB    %0110011
         DB    %0110011
         DB    %0101110
         DB    %0000000
HRT_BLOW
         DB    %0000011
         DB    %0000011
         DB    %0011111
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0011101
         DB    %0000000
HRT_CLOW
         DB    %0000000
         DB    %0000000
         DB    %0011110
         DB    %0110011
         DB    %0000011
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_DLOW
         DB    %0110000
         DB    %0110000
         DB    %0111110
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0101110
         DB    %0000000
HRT_ELOW
         DB    %0000000
         DB    %0000000
         DB    %0011110
         DB    %0110011
         DB    %0111111
         DB    %0000011
         DB    %0111110
         DB    %0000000
HRT_FLOW
         DB    %0011110
         DB    %0110011
         DB    %0000011
         DB    %0001111
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0000000
HRT_GLOW
         DB    %0000000
         DB    %0000000
         DB    %0101110
         DB    %0110011
         DB    %0110011
         DB    %0101110
         DB    %0110000
         DB    %0011111
HRT_HLOW
         DB    %0000011
         DB    %0000011
         DB    %0011111
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0000000
HRT_ILOW
         DB    %0000000
         DB    %0001100
         DB    %0000000
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0000000
HRT_JLOW
         DB    %0000000
         DB    %0110000
         DB    %0000000
         DB    %0110000
         DB    %0110000
         DB    %0110000
         DB    %0110110
         DB    %0011100
HRT_KLOW
         DB    %0000011
         DB    %0000011
         DB    %0110011
         DB    %0011011
         DB    %0001111
         DB    %0011011
         DB    %0110011
         DB    %0000000
HRT_LLOW
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0000000
HRT_MLOW
         DB    %0000000
         DB    %0000000
         DB    %0110011
         DB    %0101101
         DB    %0100001
         DB    %0110011
         DB    %0110011
         DB    %0000000
HRT_NLOW
         DB    %0000000
         DB    %0000000
         DB    %0011011
         DB    %0110111
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0000000
HRT_OLOW
         DB    %0000000
         DB    %0000000
         DB    %0011110
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0000000
HRT_PLOW
         DB    %0000000
         DB    %0000000
         DB    %0011011
         DB    %0110111
         DB    %0110011
         DB    %0011111
         DB    %0000011
         DB    %0000011
HRT_QLOW
         DB    %0000000
         DB    %0000000
         DB    %0110110
         DB    %0111011
         DB    %0110011
         DB    %0111110
         DB    %0110000
         DB    %0110000
HRT_RLOW
         DB    %0000000
         DB    %0000000
         DB    %0011011
         DB    %0110111
         DB    %0000011
         DB    %0000011
         DB    %0000011
         DB    %0000000
HRT_SLOW
         DB    %0000000
         DB    %0000000
         DB    %0111110
         DB    %0000011
         DB    %0011110
         DB    %0110000
         DB    %0011111
         DB    %0000000
HRT_TLOW
         DB    %0001100
         DB    %0001100
         DB    %0011110
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0000000
HRT_ULOW
         DB    %0000000
         DB    %0000000
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0101110
         DB    %0000000
HRT_VLOW
         DB    %0000000
         DB    %0000000
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0011110
         DB    %0001100
         DB    %0000000
HRT_WLOW
         DB    %0000000
         DB    %0000000
         DB    %0110011
         DB    %0110011
         DB    %0100001
         DB    %0101101
         DB    %0110011
         DB    %0000000
HRT_XLOW
         DB    %0000000
         DB    %0000000
         DB    %0110011
         DB    %0110011
         DB    %0001100
         DB    %0110011
         DB    %0110011
         DB    %0000000
HRT_YLOW
         DB    %0000000
         DB    %0000000
         DB    %0110011
         DB    %0110011
         DB    %0110011
         DB    %0111100
         DB    %0110000
         DB    %0011110
HRT_ZLOW
         DB    %0000000
         DB    %0000000
         DB    %0111111
         DB    %0011000
         DB    %0001100
         DB    %0000110
         DB    %0111111
         DB    %0000000
HRT_LCB
         DB    %0011100   ; {
         DB    %0000110
         DB    %0000110
         DB    %0000011
         DB    %0000110
         DB    %0000110
         DB    %0011100
         DB    %0000000
HRT_PIP
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0001100
         DB    %0000000
HRT_RCB
         DB    %0001110   ; }
         DB    %0011000
         DB    %0011000
         DB    %0110000
         DB    %0011000
         DB    %0011000
         DB    %0001110
         DB    %0000000
HRT_TLD
         DB    %0000000
         DB    %0011001   ;~
         DB    %0100110
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000
         DB    %0000000


HiRes Macros and Subroutines

The MAC.HIRES.ASM file contains all of the macros used for high resolution graphics. All subroutines are currently located in their own files.

LISTING 9.04: The MAC.HIRES.ASM Heading

*
*``````````````````````````````*
* MAC.HIRES.ASM                *
*                              *
* THIS IS A MACRO LIBRARY FOR  *
* HIGH RESOLUTION GRAPHICS.    *
* FOR THE TIME BEING, THIS IS  *
* REQUIRED FOR MOST OF THE     *
* SUBROUTINES INCLUDED IN THE  *
* HIGH RESOLUTION COLLECTION.  *
*                              *
* AUTHOR:     NATHAN RIGGS     *
* CONTACT:    NATHAN.RIGGS@    *
*             OUTLOOK.COM      *
*                              *
* DATE:       30-MAY-2001      *
* ASSEMBLER:  MERLIN 8 PRO     *
* OS:         DOS 3.3          *
*                              *
* SUBROUTINE FILES NEEDED      *
*                              *
*  SUB.HRPLOT.ASM              *
*  SUB.HRCLEAR.ASM             *
*  SUB.HRBLINE.ASM             *
*  SUB.HRHLINE.ASM             *
*  SUB.HRVLINE.ASM             *
*  SUB.HRSTR.ASM               *
*  TBL.DB7.ASM                 *
*  TBL.HIRES.ASM               *
*  TBL.HRCHAR.ASM              *
*                              *
* LIST OF MACROS               *
*                              *
*  HBSET: SET HIRES BYTE       *
*  HBGET: GET HIRES BYTE       *
*  HVIEWPG: SET VIEWING PAGE   *
*  HWORKPG: SET WORKING PAGE   *
*  HPLOT  : PLOT HIRES POINT   *
*  HCLR   : FILL SCREEN COLOR  *
*  HLINE  : HORIZONTAL LINE    *
*  VLIN   : VERTICAL LINE      *
*  LINE   : ARBITRARY LINE     *
*  HCHAR  : PLOT HIRES CHAR    *
*  HSTR   : PLOT HIRES STRING  *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*

THE HBSET MACRO

SUMMARY

Condition Value
Name HBSET
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Plot a byte to the HiRes page
Input ]1 = X position
]2 = Y position
]3 = Byte value
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 54
Bytes 37
Notes none
See Also HBGET

DETAILS

The HBSET macro takes a byte and plots it to the working high resolution page at the given X,Y coordinate, x being between 0 and 39 while Y is between 0 and 191. To help with speed, this macro does not call any subroutines; the full 37 bytes are posted in place of the call to the macro each time. Given that displaying a tile requires eight calls to HBSET, the size can get unwieldy quickly; care should be taken to call the macro as part of a larger plotting mechanism rather than use it on its own.

Thanks to the way high resolution graphics works on the Apple II, plotting an entire byte to the working page is much faster than plotting a single pixel; in fact, if the HPLOT subroutine is examined, one finds that the subroutine uses HBGET to read the byte already where a pixel is to be plotted, alters the byte to add the new pixel (after masking for color), then replots the byte using the HBSET macro. As such, most complicated uses of high resolution graphics will use plotting entire bytes rather than single pixels.

It should be noted that since the color of a pixel is determined by its placement on the high resolution screen, there is no need to pass color information to HBSET. However, this does make using color with tiles rather difficult, especially since every other column (seven pixels) reverses the order of coloring. Much care and forethought needs to be put into how tiles will display on the screen unless the tiles are to be all white, in which case two pixels side-by-side will suffice.

Exactly how high resolution works on the Apple II is beyond the scope of this documentation, though reading the source code in this collection will go a long way towards understanding it. For a more thorough understanding, see Leonard Malkin's Hi-Res Graphics and Animation Using Assembly Language and Jeffrey Stanton's Apple Graphics & Arcade Design.

LISTING 9.05: The HBSET Macro Source

*
*``````````````````````````````*
* HBSET                        *
*                              *
* SET A BYTE ON THE HIRES PAGE *
* AT THE GIVEN X AND Y COORDS. *
* SINCE THIS IS IN BYTES AND   *
* NOT PIXELS, X IS BETWEEN 0   *
* AND 39 WHILE Y IS BETWEEN 0  *
* AND 191. THIS IS MOST USEFUL *
* FOR PLOTTING TILES IN GAMES, *
* ETC., AS IT IS MUCH FASTER   *
* THAN THE STANDARD PLOT       *
* THANKS TO HOW THE HIRES      *
* SCREEN FUNCTIONS.            *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = X POSITION             *
*  ]2 = Y POSITION             *
*  ]3 = BYTE VALUE             *
*                              *
* CYCLES: 54                   *
* SIZE: 37 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HBSET    MAC
         LDY   ]1         ; {4C3B} HORIZONTAL BYTE NUMBER
         LDX   ]2         ; {4C3B} VERTICAL LINE NUMBER
         LDA   HGRHI,X    ; {5C3B} GET LINE ADDRESS
         STA   WPAR1+1    ; {4C3B}
         LDA   HGRLO,X    ; {5C3B}
         STA   WPAR1      ; {3C2B}
         LDA   HOFFSET    ; {4C3B} IS THERE A PAGE OFFSET?
         CMP   #0         ; {3C2B} NO, SO SKIP TO PLOT
         BEQ   ]BLOT      ; {3C2B}
         CLC              ; {2C1B} ELSE ADD PAGE OFFSET
         ADC   WPAR1+1    ; {4C3B}
         STA   WPAR1+1    ; {4C3B}
]BLOT
         LDA   ]3         ; {4C3B}
         STA   (WPAR1),Y  ; {5C3B} PLOT TO MEMORY
         <<<
*

THE HBGET MACRO

SUMMARY

Condition Value
Name HBGET
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose Plot a byte to the HiRes page
Input ]1 = X position
]2 = Y position
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 49
Bytes 30
Notes none
See Also HBSET

DETAILS

The HBGET macro retrieves a byte value from the HiRes working page at a given X,Y coordinate, returning the byte in the Accumulator.

LISTING 9.06: The HBGET Macro Source

*
*``````````````````````````````*
* HBGET                        *
*                              *
* GET A BYTE FROM THE HIRES    *
* WORKING PAGE.                *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = X POSITION             *
*  ]2 = Y POSITION             *
*                              *
* CYCLES: 49                   *
* SIZE: 30 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HBGET    MAC
         LDY   ]1         ; {4C3B} HORIZONTAL BYTE NUMBER
         LDX   ]2         ; {4C3B} VERTICAL LINE NUMBER
         LDA   HGRHI,X    ; {5C3B} GET LINE ADDRESS
         STA   WPAR1+1    ; {4C3B}
         LDA   HGRLO,X    ; {5C3B}
         STA   WPAR1      ; {4C3B}
         LDA   HOFFSET    ; {4C3B} IS THERE A PAGE OFFSET?
         CMP   #0         ; {3C2B} NO, SO SKIP TO GET BYTE
         BEQ   ]BGET      ; {3C2B} ELSE ADD OFFSET FIRST
         CLC              ; {2C1B}
         ADC   WPAR1+1    ; {3C2B}
         STA   WPAR1+1    ; {3C2B}
]BGET
         LDA   (WPAR1),Y  ; {5C3B} RETURN BYTE IN .A
         <<<
*

THE HVIEWPG MACRO

SUMMARY

Condition Value
Name HVIEWPG
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose set the current viewingpage
Input ]1 = page number (#1 or #2)
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 19
Bytes 14
Notes none
See Also HWORKPG

DETAILS

The HVIEWPG macro sets the current high resolution viewing page (either page #1 or page #2). This is mostly useful for smoothing out animations, or holding a frequently used interface in memory that can be quickly switched to. Note that when the Merlin Assembler is loaded into memory, the second page is disabled (this goes for the text/LoRes page #2 as well); a clean copy of DOS must first be loaded from another disk in order to see the page flipping in action.

LISTING 9.07: The HVIEWPG Macro Source

*
*``````````````````````````````*
* HVIEWPG                      *
*                              *
* SET THE VIEWING HIRES PAGE.  *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = PAGE NUMBER (1 OR 2)   *
*                              *
* CYCLES: 19                   *
* SIZE: 14 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HVIEWPG  MAC
         LDA   ]1         ; {4C3B} GET PAGE NUMBER
         CMP   #1         ; {3C2B} IF IT'S ONE, THEN SET
         BNE   ]TWO       ; {3C2B} VIEWING PAGE TO PAGE ONE
]ONE
         BIT   HPAGE1     ; {3C2B}
         JMP   ]HVEXIT    ; {3C3B}
]TWO                      ;        ELSE, SET TO PAGE 2
         BIT   HPAGE2     ; {3C2B}
]HVEXIT
         <<<
*

THE HWORKPG MACRO

SUMMARY

Condition Value
Name HWORKPG
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose set the current plotting page
Input ]1 = page number (#1 or #2)
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 27+
Bytes 20
Notes none
See Also HVIEWPG

DETAILS

The HWORKPG macro sets the current high resolution page that will be plotted to, independent of the current page being viewed. Note that this only works with this library, and does not translate to simply hitting a soft switch (unlike switching the viewing page). The macro works by changing the offset for the plotting subroutines and macros; this should be kept in mind when porting any subroutines or macros for your own uses.

LISTING 9.08: The HWORKPG Macro Source

*
*``````````````````````````````*
* HWORKPG                      *
*                              *
* SET THE WORKING HIRES PAGE.  *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = PAGE NUMBER (1 OR 2)   *
*                              *
* CYCLES: 27                   *
* SIZE: 20 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HWORKPG  MAC
         LDA   ]1         ; {4C3B} GET PAGE NUMBER
         CMP   #1         ; {3C2B} IF IT'S ONE, THEN SET
         BNE   ]WTWO      ; {3C2B} WORKING PAGE TO PAGE ONE
]WONE    LDA   #0         ; {3C2B}
         STA   HOFFSET    ; {4C3B}
         JMP   ]HWEXIT    ; {3C3B}
]WTWO    LDA   #$20       ; {3C2B} ELSE, SET TO PAGE 2
         STA   HOFFSET    ; {4C3B}
]HWEXIT
         <<<
*

THE HPLOT MACRO

SUMMARY

Condition Value
Name HPLOT
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose plot a single high resolution pixel
Input ]1 = X position
]2 = Y position
]3 = Color
Output none
Dependencies HRPLOT
Flags Destroyed NZCV
Cycles 348+
Bytes 14
Notes none
See Also none

DETAILS

The HPLOT macro plots a single pixel to the current high resolution page. Given that pixel color is dependent on the pixel's position, a pixel will only plot to the screen if the color matches the position, except in the case of black or white (both black1/white1 and black2/white2), which will plot at any location. In the case of plotting a white pixel, it may appear green, purple, blue or orange depending on its position; for white to truly register as white on the NTSC screen, two pixels must be placed adjacent to one another. Even then, the limitations of this system often will be still visible: usually there is an underlying green or purple tint that is noticeable, and this is mostly unavoidable in high resolution graphics.

Currently, the subroutine that this macro uses, HRPLOT, is not fully optimized. As such, the macro is slightly slower than the built-in Applesoft plotting subroutine. This will be addressed in the next update.

LISTING 9.09: The HPLOT Macro Source

*
*``````````````````````````````*
* HPLOT                        *
*                              *
* PLOT A POINT TO THE GIVEN    *
* HIRES WORKING PAGE.          *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = X POSITION (2)         *
*  ]2 = Y POSITION (1)         *
*  ]3 = COLOR (1)              *
*                              *
* CYCLES: 348+                 *
* SIZE: 14 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HPLOT    MAC
         LDY   ]2         ; {4C3B}
         LDA   ]3         ; {4C3B} COLOR CODE
         STA   BPAR1      ; {3C2B}
         _AXLIT ]1        ; {8C6B}
         JSR   HRPLOT     ; {329C214B}
         <<<
*

THE HRPLOT SUBROUTINE

SUMMARY

Condition Value
Name HRPLOT
Type Subroutine
File SUB.HRPLOT.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose plot a single pixel to the high resolution screen
Input ADDR3 = X Position
BPAR2 = Y Position
BPAR1 = Color
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 323+
Bytes 211
Notes none
See Also HPLOT

DETAILS

The HRPLOT subroutine plots a single pixel to the working high resolution page at the give X,Y coordinate in the specified color. See the HPLOT macro entry for some caveats and limitations of the subroutine.

This subroutine is currently not optimized, and is therefore a great deal slower than it could be. This is partially due to the nature of the library as a whole, which is meant to be easier to understand by a newcomer to 6502 Assembly and the Apple II, but a number of changes can be made that will, at the very least, make this faster than the built-in Applesoft plotting routine. In the next iteration of development, some of these optimizations will be implemented.

LISTING 9.10: The HRPLOT Subroutine Source

*
*``````````````````````````````*
* HRPLOT        (NATHAN RIGGS) *
*                              *
* PLOT A POINT ONT THE HIGH    *
* RESOLUTION SCREEN. THIS WILL *
* PLOT TO THE CURRENT WORKING  *
* PAGE.                        *
*                              *
* INPUT:                       *
*                              *
*  ADDR3 = X POSITION (2)      *
*  BPAR2 = Y POSITION          *
*  BPAR1 = COLOR               *
*                              *
*  DESTROY: NZCIDV             *
*           ^^^  ^             *
*                              *
* CYCLES: 323+                 *
* SIZE: 211 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]COLOR   EQU   BPAR1      ; HIRES COLOR CODE
]X       EQU   ADDR3      ; ORIGINAL X POSITION
]Y       EQU   BPAR2      ; ORIGINAL Y POSITION
]RESOFF  EQU   ADDR1      ; DIVISION RESULT OFFSET
]REMOFF  EQU   ADDR2      ; DIVISION REMAINDER OFFSET
]PIXEL   EQU   WPAR2      ; BYTE CONTAINING SINGLE PIXEL TO PLOT
]BYTE    EQU   WPAR2+1    ; BYTE LOCATION TO PLOT AT
]NEWB    EQU   BPAR3      ; NEW BYTE
*
HRPLOT
*
         STY   ]Y         ; {3C2B} Y POSITION HELD IN .Y
         STA   ]X         ; {3C2B} X POSITION LOW BYTE
         STX   ]X+1       ; {3C2B} X POSITION HIGH BYTE
         CLC              ; {2C1B}
         ADC   #<DB7RES   ; {4C3B} ADD DIVIDE BY 7 TABLE ADDRESS
         STA   ]RESOFF    ; {3C2B} STORE IN RESULT OFFSET
         LDA   ]X+1       ; {3C2B} LODA X POSITION HIGH BYTE
         ADC   #>DB7RES   ; {4C3B} ADD DIVIDE BY 7 TABLE ADDRESS
         STA   ]RESOFF+1  ; {3C2B} STORE IN RESULT OFFSET HIGH
*
         LDA   ]X         ; {3C2B} LOAD X POSITION
         CLC              ; {2C1B}
         ADC   #<DB7REM   ; {4C3B} ADD DIV BY 7 REM TABLE ADDR
         STA   ]REMOFF    ; {3C2B} STORE IN REMAINDER OFFSET LOW
         LDA   ]X+1       ; {3C2B} LOAD X POSITION HIGH BYTE
         ADC   #>DB7REM   ; {4C3B} ADD DIV BY 7 REM TABLE ADDR
         STA   ]REMOFF+1  ; {3C2B} STORE IN REMAINDER OFFSET HIGH
*
         LDY   #$00       ; {3C2B} RESET .Y INDEX TO ZERO
         LDA   (]RESOFF),Y ; {5C2B} LOAD DIV BY 7 RESULT
         STA   ]BYTE      ; {3C2B} STORE THE RESULT HERE
         LDA   (]REMOFF),Y ; {5C3B} NOW LOAD DIV BY 7 REMAINDER
         STA   ]PIXEL     ; {3C2B} AND STORE AS PIXEL POSITION
         LDA   ]COLOR     ; {3C2B} GET THE COLOR CODE
         CMP   #0         ; {3C2B} IS IT BLACK 1?
         BEQ   :BLACK     ; {3C2B} IF YES, THEN GOTO :BLACK
         CMP   #4         ; {3C2B} IS IT BLACK 2?
         BEQ   :BLACK     ; {3C2B} IF YES, THEN GOTO :BLACK
         JMP   :MASK      ; {3C3B} ELSE, JUMP TO :MASK
:BLACK
         LDA   ]PIXEL     ; {3C2B} LOAD PIXEL POSITION
         EOR   #$FF       ; {2C2B} INVERT BITS (0 = 1, 1 = 0)
         STA   ]PIXEL     ; {3C2B} STORE BACK INTO PIXEL POS
         HBGET ]BYTE;]Y   ; {49C30B} GET BYTE ALREADY AT DESTINATION
         AND   ]PIXEL     ; {3C2B} LOG AND BY PIXEL POSITION
         STA   ]NEWB      ; {3C2B} STORE IN NEW BYTE
         JMP   :TESTHI    ; {3C3B} JUMP TO TESTING HIGH BIT
*
:MASK    LDY   ]COLOR     ; {3C2B} LOAD COLOR CODE
         LDA   ]BYTE      ; {3C2B} LOAD BYTE TO CHECK EVEN OR ODD
         CLC              ; {2C1B}
         ROR              ; {2C2B} ROTATE LEFTMOST BIT INTO CARRY
         BCC   :EVEN      ; {3C2B} IF CARRY CLEAR, GOTO :EVEN
:ODD     LDA   CT_ODD,Y   ; {5C2B} IF NO,IT'S ODD--GET MASK FROM TABLE
         AND   ]PIXEL     ; {3C2B} LOGICAL AND IT WITH THE PIXEL POS
         STA   ]PIXEL     ; {3C2B} STORE BACK INTO PIXEL POS
         JMP   :PLOT      ; {3C3B} JUMP TO PLOTTING
:EVEN
         LDA   CT_EVEN,Y  ; {5C3B} READ COLOR MASK FROM TABLE
         AND   ]PIXEL     ; {3C2B} LOGICAL AND IT WITH PIXEL POS
         STA   ]PIXEL     ; {3C2B} STORE NEW PIXEL POS VALUE
:PLOT
         HBGET ]BYTE;]Y   ; {49C30B} GET THE BYTE CURRENTLY THERE
         ORA   ]PIXEL     ; {3C2B} LOGICAL OR IT WITH THE PIXEL
         STA   ]NEWB      ; {3C2B} STORE AS A NEW BYTE
:TESTHI  LDA   ]COLOR     ; {3C2B} LOAD COLOR TO TEST FOR HI BIT SET
         CMP   #4         ; {3C2B} IF COLOR < 4 THEN
         BCC   :PLOT2     ; {4C3B} SKIP TO ACTUAL PLOTTING
         LDA   ]NEWB      ; {3C2B} ELSE LOAD THE NEW BYTE
         ORA   #$80       ; {3C2B} AND TURN ON MOST SIGNIFICANT BIT
         STA   ]NEWB      ; {3C2B} AND STORE THE NEW BYTE AGAIN
:PLOT2
         HBSET ]BYTE;]Y;]NEWB ; {54C37B} NOW PLOT NEW BYTE TO MEMORY
         RTS              ; {6C1B}

THE HCLR MACRO

SUMMARY

Condition Value
Name HCLR
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose plot a single high resolution pixel
Input ]1 = Color
Output none
Dependencies HCLEAR
Flags Destroyed NZCV
Cycles 96+
Bytes 5
Notes none
See Also HCLEAR

DETAILS

The HCLR macro fills the current high resolution working page with a given color. This does not use the plotting subroutine, but rather fills the screen memory appropriately, switching from even to odd pixels when necessary (this is needed due to the architecture of the Apple II).

LISTING 9.11: The HRCLR Macro Source

*
*``````````````````````````````*
* HCLR                         *
*                              *
* FILL THE WORKING HIRES PAGE  *
* WITH THE SPECIFIED COLOR.    *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = COLOR                  *
*                              *
* CYCLES: 96+                  *
* SIZE: 5 BYTES                *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HCLR     MAC
         LDA   ]1         ; {4C3B}
         STA   BPAR1      ; {3C2B}
         JSR   HCLEAR     ; {89C0B}
         <<<
*

THE HCLEAR SUBROUTINE

SUMMARY

Condition Value
Name HCLEAR
Type Subroutine
File SUB.HCLEAR.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose fill high resolution page with single color
Input BPAR1 = Color
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 83+
Bytes 49
Notes none
See Also HCLR

DETAILS

The HCLEAR subroutine fills the working page of the high resolution screen with the provided color code. This subroutine is independent from any plotting mechanism, and instead fills the high resolution page based on pixel color positions.

LISTING 9.12: The HCLEAR Subroutine Source

*
*``````````````````````````````*
* HCLEAR                       *
*                              *
* FILLS THE HIRES WORKING PAGE *
* WITH THE SPECIFIED COLOR.    *
*                              *
* INPUT:                       *
*                              *
*  BPAR1 = COLOR               *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 83                   *
* SIZE: 49+                    *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]HRLO    EQU   ADDR1      ; LOW BYTE OF WORKING SCREEN
]HRHI    EQU   ADDR1+1    ; HIGH BYTE OF WORKING SCREEN
]MAX     EQU   ADDR2      ; MAX LENGTH OF WORKING SCREEN
]COLOR   EQU   BPAR1      ; COLOR CODE
*
HCLEAR
         LDA   #$00       ; {3C2B} CLEAR OUT THE ACCUMULATOR
         STA   ]HRLO      ; {3C2B} CLEAR SCREEN MEM LOW BYTE
         LDA   #$20       ; {3C2B} LOAD #$20 AS HIGH BYTE
         CLC              ; {2C1B}
         ADC   HOFFSET    ; {4C3B} AND ADD HI BYTE OFFSET FOR PAGE
         STA   ]HRHI      ; {3C2B} AND STORE NEW HIGH BYTE
         LDA   HOFFSET    ; {4C3B} LOAD OFFSET AGAIN
         CLC              ; {2C1B}
         ADC   #$40       ; {3C2B} AND ADD 8K SCREEN LENGTH
         STA   ]MAX       ; {3C2B} TO STORE IN MAX
         LDX   ]COLOR     ; {3C2B} COLOR HELD IN .X
:CLR1    LDY   #$00       ; {3C2B} CLEAR THE .Y INDEX
:CLR2    LDA   CT_EVEN,X  ; {5C3B} GET COLOR MASK FOR EVEN BYTES
         STA   (]HRLO),Y  ; {5C3B} STORE IN SCREEN MEMORY
         INY              ; {2C1B} INCREASE .Y INDEX
         LDA   CT_ODD,X   ; {5C3B} GET COLOR MASK FOR ODD BYTES
         STA   (]HRLO),Y  ; {5C3B} STORE IN SCREEN MEMORY
         INY              ; {2C1B} INCREASE .Y INDEX
         BNE   :CLR2      ; {3C2B} IF .Y HASN'T FLIPPED YET
         INC   ]HRHI      ; {5C2B} THEN LOOP CLR2, ELSE INC HIGH
         LDA   ]HRHI      ; {3C2B}
         CMP   ]MAX       ; {3C2B} IS HIGH BYTE EQUAL TO MAX?
         BCC   :CLR1      ; {3C2B} IF NOT, LOOP CLR1
         RTS              ; {6C1B}

THE HLIN MACRO

SUMMARY

Condition Value
Name HLIN
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose plot a horizontal line to the high resolution page
Input ]1 = X origin
]2 = X destination
]3 = Y position
]4 = Color
Output none
Dependencies HRHLINE
Flags Destroyed NZCV
Cycles 494+
Bytes 34
Notes none
See Also HRHLINE

DETAILS

The HLIN macro draws a horizontal line on the working page of the high resolution screen, from an X origin to an X destination at a static Y position.

LISTING 9.13: The HLIN Macro Source

*
*``````````````````````````````*
* HLIN                         *
*                              *
* DRAW A HORIZONTAL LINE ON    *
* THE HIRES WORKING PAGE.      *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = X ORIGIN (2)           *
*  ]2 = X DESTINATION (2)      *
*  ]3 = Y POSITION (1)         *
*  ]4 = COLOR                  *
*                              *
* CYCLES: 494+                 *
* SIZE: 34 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HLIN     MAC
         _MLIT ]1;WPAR1   ; {16C12B}
         _MLIT ]2;WPAR2   ; {16C12B}
         LDA   ]3         ; {4C3B}
         STA   BPAR1      ; {3C2B}
         LDA   ]4         ; {4C3B}
         STA   BPAR2      ; {3C2B}
         JSR   HRHLINE    ; {448C0B}
         <<<
*

THE HRHLINE SUBROUTINE

SUMMARY

Condition Value
Name HRHLINE
Type Subroutine
File SUB.HRHLINE.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose draw a horizontal line on a high resolution page
Input WPAR1 = X origin
WPAR2 = X destination
BPAR1 = Y position
BPAR2 = Color
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 442+
Bytes 78
Notes none
See Also HLIN

DETAILS

The HRHLINE subroutine accepts an X origin and X destination and plots a horizontal line from one to the other at the static Y position given and in the color provided. This will only plot pixels that match the color passed.

LISTING 9.14: The HRHLINE Subroutine Source

*
*``````````````````````````````*
* HRHLINE                      *
*                              *
* CREATE A HORIZONTAL LINE ON  *
* THE HIRES WORKING PAGE AT    *
* THE GIVEN COORDINATES AND    *
* COLOR.                       *
*                              *
* INPUT:                       *
*                              *
*  WPAR1 = X ORIGIN            *
*  WPAR2 = X DESTINATION (2)   *
*  BPAR1 = Y POSITION (1)      *
*  BPAR2 = COLOR (1)           *
*                              *
* DESTROY: NZCIDV              *
*          ^^^  ^              *
*                              *
* CYCLES: 442+                 *
* SIZE: 78 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]X1      HEX   0000       ; X ORIGIN
]X2      HEX   0000       ; X DESTINATION
]Y       HEX   00         ; Y POSITION (COLUMN)
]COLOR   HEX   00         ; COLOR CODE
*
HRHLINE
         LDA   WPAR1      ; {3C2B} SAVE X ORIGIN LOW BYTE
         STA   ]X1        ; {4C3B}
         LDA   WPAR1+1    ; {3C2B} SAVE X DESTINATION HIGH BYTE
         STA   ]X1+1      ; {4C3B}
         LDA   WPAR2      ; {3C2B} SAVE X DESTINATION LOW BYTE
         STA   ]X2        ; {4C3B}
         LDA   WPAR2+1    ; {3C2B} SAVE X DESTINATION HIGH BYTE
         STA   ]X2+1      ; {4C3B}
         LDA   BPAR1      ; {3C2B} SAVE Y POSITION
         STA   ]Y         ; {4C3B}
         LDA   BPAR2      ; {3C2B} SAVE COLOR
         STA   ]COLOR     ; {4C3B}
*
:LOOP
         HPLOT ]X1;]Y;]COLOR ; {348C14B} PLOT POINT ON LINE
         LDA   ]X1        ;    {4C3B} LOAD X ORIGIN
         CLC              ;    {2C1B}
         ADC   #1         ;    {3C2B} ADD 1 TO LOW BYTE
         STA   ]X1        ;    {4C3B} STORE BACK INTO LOW BYTE
         LDA   ]X1+1      ;    {4C3B} LOAD THE HIGH BYTE
         ADC   #0         ;    {3C2B} ADJUST FOR CARRY
         STA   ]X1+1      ;    {4C3B} STORE BACK INTO HIGH BYTE
         LDY   ]X1        ;    {4C3B} LOAD CURRENT POSITION
         CPY   ]X2        ;    {4C3B} COMPARE IT TO DESTINATION
         BNE   :LOOP      ;    {3C2B} IF !=, THEN LOOP AGAIN
         LDY   ]X1+1      ;    {4C3B} ELSE LOAD HIGH BYTE
         CPY   ]X2+1      ;    {4C3B} AND COMPARE TO DESTINATION
         BNE   :LOOP      ;    {3C2B} IF !=, KEEP LOOPING
:EXIT
         RTS              ; {6C1B}

THE VLIN MACRO

SUMMARY

Condition Value
Name VLIN
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose plot a vertical line to the high resolution page
Input ]1 = Y origin
]2 = Y destination
]3 = X position
]4 = Color
Output none
Dependencies HRVLINE
Flags Destroyed NZCV
Cycles 449+
Bytes 30
Notes none
See Also HRVLINE

DETAILS

The VLIN macro plots a vertical line to the high resolution working page.

LISTING 9.15: The VLIN Macro Source

*
*``````````````````````````````*
* VLIN                         *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = Y ORIGIN (1)           *
*  ]2 = Y DESTINATION (1)      *
*  ]3 = X POSITION (2)         *
*  ]4 = COLOR (1)              *
*                              *
* CYCLES: 449+                 *
* SIZE: 30 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
VLIN     MAC
         LDA   ]1         ; {4C3B}
         STA   WPAR1      ; {3C2B}
         LDA   ]2         ; {4C3B}
         STA   WPAR1+1    ; {3C2B}
         _MLIT ]3;WPAR2   ; {16C12B}
         LDA   ]4         ; {4C3B}
         STA   BPAR2      ; {3C2B}
         JSR   HRVLINE    ; {412C3B}
         <<<
*

THE HRVLINE SUBROUTINE

SUMMARY

Condition Value
Name HRVLINE
Type Subroutine
File SUB.HRVLINE.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose draw a vertical line on a high resolution page
Input WPAR1 = Y origin
WPAR1+1 = Y destination
WPAR2 = X position
BPAR2 = Color
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 406+
Bytes 51
Notes none
See Also VLIN

DETAILS

The HRVLINE subroutine plots a vertical line to the high resolution working page. This uses a standard plotting mechanism, so pixels are only plotted to the appropriately color-matched positions.

LISTING 9.16: The HRVLINE Subroutine Source

*
*``````````````````````````````*
* HRVLINE                      *
*                              *
* CREATE A VERTICAL LINE ON    *
* THE WORKING HIRES PAGE AT    *
* THE GIVEN COORDINATES AND    *
* COLOR.                       *
*                              *
* INPUT:                       *
*                              *
*  WPAR1 = Y ORIGIN (1)        *
*  WPAR1+1 = Y DESTINATION (1) *
*  WPAR2 = X POSITION (2)      *
*  BPAR2 = COLOR               *
*                              *
* CYCLES: 406+                 *
* SIZE: 51 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]Y1      HEX   00         ; Y ORIGIN
]Y2      HEX   00         ; Y DESTINATION
]X       HEX   0000       ; X POSITION (ROW)
]COLOR   HEX   00         ; COLOR CODE
*
HRVLINE
         LDA   WPAR1      ; {3C2B} STORE Y ORIGIN
         STA   ]Y1        ; {4C3B}
         LDA   WPAR1+1    ; {3C2B} STORE Y DESTINATION
         STA   ]Y2        ; {4C3B}
         LDA   WPAR2      ; {3C2B} STORE X POSITION
         STA   ]X         ; {4C3B}
         LDA   WPAR2+1    ; {3C2B} STORE X POS HIGH BYTE
         STA   ]X+1       ; {4C3B}
         LDA   BPAR2      ; {3C2B} STORE COLOR
         STA   ]COLOR     ; {4C3B}
:LOOP
         HPLOT ]X;]Y1;]COLOR ; {348C14B} PLOT CURRENT POINT
         INC   ]Y1        ;    {5C3B} INCREASE Y POSITION
         LDY   ]Y1        ;    {4C3B}
         CPY   ]Y2        ;    {4C3B} IF Y ORIGIN != DESTINATION
         BNE   :LOOP      ;    {3C2B} CONTINUE LOOPING
:EXIT
         RTS              ; {6C1B}

THE LINE MACRO

SUMMARY

Condition Value
Name LINE
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose plot an arbitrary line to the high resolution page
Input ]1 = X origin
]2 = Y origin
]3 = X destination
]4 = Y destination
]5 = Color
Output none
Dependencies HRBLINE
Flags Destroyed NZCV
Cycles 825+
Bytes 42
Notes none
See Also HRBLINE

DETAILS

The LINE macro plots an arbitrary line from X0,Y0 to X1,Y1 on the current working high resolution page in the specified color.

This implementation currently uses the most limited version of Bresenham's line algorithm, and thus is only able to plot a line from lower values to higher values, on both the X and Y axis. This is obviously a severe limitation, and will be fixed in the next dedicated update to the high resolution collection.

LISTING 9.17: The LINE Macro Source

*
*``````````````````````````````*
* LINE                         *
* DRAW A LINE ON THE WORKING   *
* HIRES PAGE FROM X0,Y0 TO     *
* X1,Y1 IN THE GIVEN COLOR.    *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = X ORIGIN (2)           *
*  ]2 = Y ORIGIN (1)           *
*  ]3 = X DESTINATION (2)      *
*  ]4 = Y DESTINATION (1)      *
*  ]5 = COLOR                  *
*                              *
* CYCLES: 825+                 *
* SIZE: 42 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
LINE     MAC
         _MLIT ]1;WPAR1   ; {16C12B}
         LDA   ]2         ; {4C3B}
         STA   ADDR1      ; {3C2B}
         _MLIT ]3;WPAR3   ; {16C12B}
         LDA   ]4         ; {4C3B}
         STA   ADDR1+1    ; {3C2B}
         LDA   ]5         ; {4C3B}
         STA   BPAR1      ; {3C2B}
         JSR   HRBLINE    ; {788C3B}
         <<<
*

THE HRBLINE SUBROUTINE

SUMMARY

Condition Value
Name HRBLINE
Type Subroutine
File SUB.HRBLINE.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose draw an arbitrary line on a high resolution page
Input WPAR1 = X origin
ADDR1 = Y origin
WPAR3 = X destination
ADDR1+1 = Y destination
BPAR1 = Color
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 782+
Bytes 489
Notes none
See Also LINE

DETAILS

The HRBLINE subroutine uses a barebones implementation of Bresenham's line algorithm to plot a line from an X,Y origin to an X1,Y1 destination in the given color. It should be noted that due to uses such a limited version of Bresenham's line algorithm, this implementation can only plot from lower to higher values on either axis. This will be updated and expanded in the next dedicated revision of the high resolution collection.

LISTING 9.18: The HRBLINE Subroutine Source

*
*``````````````````````````````*
* HRBLINE       (NATHAN RIGGS) *
*                              *
* PLOT A LINE FROM X0,Y0 TO    *
* X1,Y1 ON THE HIRES SCREEN IN *
* THE SPECIFIED COLOR. THIS    *
* USES BRESENHAM'S LINE        *
* ALGORITHM FOR SPEED.         *
*                              *
* BE ADVISED THAT THIS IS A    *
* BAREBONES VERSION OF         *
* BRESENHAM'S LINE ALGORITHM,  *
* AND THUS ONLY PLOTS FROM LOW *
* VALUES TO HIGHER VALUES.     *
* IN THE NEXT REVISION, A FULL *
* IMPLEMENTATION THAT TRULY    *
* DEALS WITH ALL DIAGONAL      *
* LINES WILL BE PROVIDED.      *
*                              *
* NOTE THAT USING THE ZERO     *
* PAGE FOR VARIABLE SPACE WILL *
* BE USED IN THE FUTURE. IT IS *
* NOT CURRENTLY IN USE DUE TO  *
* CONFLICTS WITH OTHER         *
* SUBROUTINES.                 *
*                              *
* INPUT:                       *
*                              *
*  WPAR1 = X ORIGIN (2)        *
*  ADDR1 = Y ORIGIN (1)        *
*  WPAR3 = X DESTINATION (2)   *
*  ADDR1+1 = Y DESTINATION (1) *
*  BPAR1 = COLOR (1)           *
*                              *
* DESTROYS: NZCIDV             *
*           ^^^  ^             *
*                              *
* CYCLES: 782+                 *
* SIZE: 489 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]X0      HEX   0000       ; {0C2B} X ORIGIN
]X1      HEX   0000       ; {0C2B} X DESTINATION
]Y0      HEX   0000       ; {0C2B} Y ORIGIN
]Y1      HEX   0000       ; {0C2B} Y DESTINATION
]DX      HEX   0000       ; {0C2B} CHANGE IN X
]DY      HEX   0000       ; {0C2B} CHANGE IN Y
]ERR     HEX   0000       ; {0C2B} LINE ERROR
]ERRX2   HEX   0000       ; {0C2B} ERROR * 2
]TEMP    HEX   0000       ; {0C2B} TEMP STORAGE
]SX      HEX   00         ; {0C1B} SLOPE X
]SY      HEX   00         ; {0C1B} SLOPE Y
]COLOR   EQU   BPAR1      ; COLOR PASSED TO HPLOT IN BPAR1
*
HRBLINE
*
** GET PARAMETERS
*
:GETPARM
         LDA   WPAR1      ; {3C2B} GET ]X0
         STA   ]X0        ; {4C3B}
         LDA   WPAR1+1    ; {3C2B}
         STA   ]X0+1      ; {4C3B}
         LDA   ADDR1      ; {3C2B} GET ]Y0
         STA   ]Y0        ; {4C3B}
         LDA   WPAR3      ; {3C2B} GET ]X1
         STA   ]X1        ; {4C3B}
         LDA   WPAR3+1    ; {3C2B}
         STA   ]X1+1      ; {4C3B}
         LDA   ADDR1+1    ; {3C2B} GET ]Y1
         STA   ]Y1        ; {4C3B}
         LDA   #0         ; {3C2B}
         STA   ]Y0+1      ; {4C3B}
         STA   ]Y1+1      ; {4C3B}
*
** GET DX: ABS(X1-X0)
*
:GETDX
         LDA   ]X1        ; {4C3B} ]X1 - ]X0
         SEC              ; {2C1B}
         SBC   ]X0        ; {4C3B}
         TAY              ; {2C1B} HOLD LO BYTE VALUE IN .Y
         LDA   ]X1+1      ; {4C3B} ]X1+1 - ]X0+1
         SBC   ]X0+1      ; {4C3B}
         BPL   :DXFOUND   ; {3C2B} IF HI BYTE IS POS, SKIP ABS
         TAX              ; {2C1B} HOLD HI BYTE IN .X
         TYA              ; {2C1B} TRANSFER LO BYTE INTO .A
         SEC              ; {2C1B}
         SBC   #1         ; {3C2B} SUBTRACT 1 AND
         EOR   #$FF       ; {3C2B} EOR TO RETURN TO POSITIVE
         STA   ]DX        ; {4C3B} STORE LO BYTE
         TXA              ; {2C1B} TRANSFER HI BYTE INTO .A
         SBC   #0         ; {4C3B} ADJUST FOR CARRY
         EOR   #$FF       ; {3C2B} AND EOR TO MAKE POSITIVE
         STA   ]DX+1      ; {4C3B} AND STORE THE HIGH BYTE
         JMP   :GETDY     ; {3C3B}
:DXFOUND STA   ]DX+1      ; {4C3B} NO CHANGE, STORE THE HI BYTE
         STY   ]DX        ; {4C3B} AND STORE LOW BYTE
*
** GETDY: ABS(Y1-Y0)
*
:GETDY
         LDA   ]Y1        ; {4C3B} ]Y1 - ]Y0
         SEC              ; {2C1B}
         SBC   ]Y0        ; {4C3B}
         TAY              ; {2C1B} HOLD LO BYTE VALUE IN .Y
         LDA   ]Y1+1      ; {4C3B} ]Y1+1 - ]Y0+1
         SBC   ]Y0+1      ; {4C3B}
         BPL   :DYFOUND   ; {3C2B} IF HI BYTE IS POS, SKIP ABS
         TAX              ; {2C1B} HOLD HI BYTE IN .X
         TYA              ; {2C1B} TRANSFER LO BYTE INTO .A
         SEC              ; {2C1B}
         SBC   #1         ; {3C2B} SUBTRACT 1 AND
         EOR   #$FF       ; {3C2B} EOR TO RETURN TO POSITIVE
         STA   ]DY        ; {4C3B} STORE LO BYTE
         TXA              ; {2C1B} TRANSFER HI BYTE INTO .A
         SBC   #0         ; {4C3B} ADJUST FOR CARRY
         EOR   #$FF       ; {3C2B} AND EOR TO MAKE POSITIVE
         STA   ]DY+1      ; {4C3B} AND STORE THE HIGH BYTE
         JMP   :GETERR    ; {3C3B}
:DYFOUND STA   ]DY+1      ; {4C3B} NO CHANGE, STORE THE HI BYTE
         STY   ]DY        ; {4C3B} AND STORE LOW BYTE
*
** GETERR: ]ERR = ]DX - ]DY
*
:GETERR
         LDA   ]DX        ; {4C3B} LO BYTE ]DX - ]DY
         SEC              ; {2C1B}
         SBC   ]DY        ; {4C3B}
         STA   ]ERR       ; {4C3B}
         LDA   ]DX+1      ; {4C3B} HI BYTE ]DX - ]DY
         SBC   ]DY+1      ; {4C3B}
         STA   ]ERR+1     ; {4C3B}
*
** SETSX: IF X0 < X1, THEN SX = 1--ELSE, SX = -1
*
:SETSX
         LDX   #$FF       ; {3C2B} HOLD -1 AUTOMATICALLY IN .X
         SEC              ; {2C1B}
         LDA   ]X0        ; {4C3B} IF X0 < X1, GOTO :SXLT--ELSE,
         CMP   ]X1        ; {3C2B} GOTO :SXGTE (16-BIT COMPARISON)
         LDA   ]X0+1      ; {4C3B}
         SBC   ]X1+1      ; {4C3B}
         BVC   :SXLBL     ; {3C2B}
         EOR   #$80       ; {3C2B}
:SXLBL   BMI   :SXLT      ; {3C2B}
         BPL   :SXGTE     ; {3C2B}
:SXLT    LDX   #$01       ; {3C2B} X0 < X1, SO ]SX = 1
:SXGTE   STX   ]SX        ; {4C3B} ELSE ]SX = -1--STORE ]SX
*
** SETSY: IF Y0 < Y1, THEN SY = 1--ELSE, SY = -1
*
         LDX   #$FF       ; {3C2B} HOLD -1 IN .X
         SEC              ; {2C1B}
         LDA   ]Y0        ; {4C3B} IF Y0 < Y1, GOTO :SYLT--ELSE,
         CMP   ]Y1        ; {4C3B} GOTO :SYGTE (16-BIT COMPARISON)
         LDA   ]Y0+1      ; {4C3B}
         SBC   ]Y1+1      ; {4C3B}
         BVC   :SYLBL     ; {3C2B}
         EOR   #$80       ; {3C2B}
:SYLBL   BMI   :SYLT      ; {3C2B}
         BPL   :SYGTE     ; {3C2B}
:SYLT    LDX   #$01       ; {4C3B} Y0 < Y1, SO ]SY = 1
:SYGTE   STX   ]SY        ; {4C3B} ELSE ]SY = -1--STORE ]SY
*
********************************
*
* MAIN LOOP
*
********************************
*
:LOOP
*
** FIRST, PLOT THE CURRENT POINT
*
:PLOT
         LDA   ]X0        ; {4C3B}
         LDX   ]X0+1      ; {4C3B}
         LDY   ]Y0        ; {4C3B}
         JSR   HRPLOT     ; {323C0B}
*
** NOW CHECK FOR END OF LOOP: X1 = X0, Y1 = Y0
*
         LDA   ]X0+1      ; {4C3B} IF X0 HI != X1 HI, SKIP REST
         CMP   ]X1+1      ; {3C2B} OF COMPARISON
         BNE   :CLOOP     ; {3C2B}
         LDA   ]X0        ; {4C3B} IF X0 LO != X0 LO, SKIP REST
         CMP   ]X1        ; {4C3B} OF COMPARISON
         BNE   :CLOOP     ; {3C2B}
         LDA   ]Y0+1      ; {4C3B} IF Y0 HI != Y1 HI, SKIP REST
         CMP   ]Y1+1      ; {3C2B} OF COMPARISON
         BNE   :CLOOP     ; {3C2B}
         LDA   ]Y0        ; {4C3B} IF Y0 LO != Y1 LO, SKIP
         CMP   ]Y1        ; {3C2B} THE JUMP TO EXIT THE SUBROUTINE
         JMP   :HRBLEXIT  ; {3C3B}
:CLOOP                    ; CONTINUE LOOPING
*
** SET ]ERROR * 2
*
:GETE2X
         LDA   ]ERR+1     ; {4C3B} IF HI BYTE OF ]ERR IS NEG,
         BMI   :ENEG      ; {3C2B} THEN GOTO :ENEG TO MAKE POSITIVE
         LDA   ]ERR       ; {4C3B} ELSE MULTIPLY BY TWO
         ASL              ; {2C1B}
         STA   ]ERRX2     ; {4C3B}
         LDA   ]ERR+1     ; {4C3B}
         ROL              ; {2C1B}
         STA   ]ERRX2+1   ; {4C3B}
         JMP   :STEPX     ; {3C3B}
:ENEG
         LDA   ]ERR       ; {4C3B} CONVERT NEGATIVE ]ERR TO
         EOR   #$FF       ; {3C2B} A POSITIVE VALUE FOR
         CLC              ; {2C1B} MULTIPLICATION
         ADC   #1         ; {3C2B}
         TAY              ; {2C1B} HOLD LO BYTE IN .Y
         LDA   ]ERR+1     ; {4C3B}
         EOR   #$FF       ; {3C2B}
         ADC   #0         ; {3C2B}
         TAX              ; {2C1B} HOLD HI BYTE IN .X
         TYA              ; {2C1B} TRANSFER LO BYTE BACK INTO .A
         ASL              ; {2C1B} MUL BY 2
         STA   ]ERRX2     ; {4C3B} STORE NEW ERR2X
         TXA              ; {2C1B} TRANSFER HI BYTE BACK INTO .A
         ROL              ; {2C1B} MUL BY 2
         STA   ]ERRX2+1   ; {4C3B} STORE NEW HI BYTE ERR2X
         LDA   ]ERRX2     ; {4C3B} NOW RECONVERT TO NEGATIVE
         EOR   #$FF       ; {3C2B}
         CLC              ; {2C1B}
         ADC   #1         ; {3C2B}
         STA   ]ERRX2     ; {4C3B}
         LDA   ]ERRX2+1   ; {4C3B}
         EOR   #$FF       ; {3C2B}
         ADC   #0         ; {3C2B}
         STA   ]ERRX2+1   ; {4C3B}
*
** STEPX: IF (-DY < ERRX2),
**        THEN ERR -= DY,
**             X0  += SX
*
:STEPX
         LDA   ]DY        ; {4C3B} FIRST, MAKE ]DY NEGATIVE
         SEC              ; {2C1B}
         SBC   #$01       ; {3C2B}
         EOR   #$FF       ; {3C2B}
         TAY              ; {2C1B} HOLD LO BYTE IN .Y
         STA   ]TEMP      ; {4C3B} AND IN TEMP FOR LATER USE
         LDA   ]DY+1      ; {4C3B}
         SBC   #$00       ; {3C2B}
         EOR   #$FF       ; {3C2B}
         STA   ]TEMP+1    ; {4C3B} HOLD HI BYTE IN TEMP AND
         TAX              ; {2C1B} HOLD HIGH BYTE IN .X
         SEC              ; {2C1B} BEGIN 16-BIT COMPARISON
         TYA              ; {2C1B} LOAD LOW BYTE INTO .A
         CMP   ]ERRX2     ; {4C3B}
         TXA              ; {2C1B} LOAD HIGH BYTE INTO .A
         SBC   ]ERRX2+1   ; {4C3B}
         BVC   :SXSLBL    ; {3C2B}
         EOR   #$80       ; {3C2B}
:SXSLBL  BMI   :SXSLT     ; {3C2B}
         BPL   :SXSGTE    ; {3C2B}
:SXSLT   LDA   ]ERR       ; {4C3B} -DY < ERR*2, SO
         SEC              ; {2C1B}
         SBC   ]DY        ; {4C3B} ]ERR = ]ERR - ]DY
         STA   ]ERR       ; {4C3B}
         LDA   ]ERR+1     ; {4C3B}
         SBC   ]DY+1      ; {4C3B}
         STA   ]ERR+1     ; {4C3B}
         LDA   ]X0        ; {4C3B} AND X0 = X0 + SX (1 OR -1)
         CLC              ; {2C1B}
         ADC   ]SX        ; {4C3B}
         STA   ]X0        ; {4C3B}
         LDA   ]X0+1      ; {4C3B}
         ADC   #$00       ; {3C2B} HI BYTE OF SX IS ALWAYS 0
         STA   ]X0+1      ; {4C3B}
         JMP   :STEPY     ; {3C3B}
:SXSGTE  LDA   ]ERRX2+1   ; {4C3B} IF ERR*2 = -DY, GOTO :SXSLT
         CMP   ]TEMP+1    ; {4C3B}
         BNE   :STEPY     ; {3C2B}
         LDA   ]ERRX2     ; {4C3B}
         CMP   ]TEMP      ; {4C3B}
         BEQ   :SXSLT     ; {3C2B}
*
** STEPY: IF ERR*2 < DX, THEN
**        ERR += DX,
**        Y0  += SY
*
:STEPY
         SEC              ; {2C1B} BEGIN 16-BIT COMPARISON (SIGNED)
         LDA   ]ERRX2     ; {4C3B} IF ERR*2 < DX, GOTO :SYSLT--
         CMP   ]DX        ; {4C3B} ELSE, GOTO :SYSGTE
         LDA   ]ERRX2+1   ; {4C3B}
         SBC   ]DX+1      ; {4C3B}
         BVC   :SYSLBL    ; {3C2B}
         EOR   #$80       ; {3C2B}
:SYSLBL  BMI   :SYSLT     ; {3C2B}
         BPL   :SYSGTE    ; {3C2B}
:SYSLT   LDA   ]ERR       ; {4C3B} ERR = ERR + DX
         CLC              ; {2C1B}
         ADC   ]DX        ; {4C3B}
         STA   ]ERR       ; {4C3B}
         LDA   ]ERR+1     ; {4C3B}
         ADC   ]DX+1      ; {4C3B}
         STA   ]ERR+1     ; {4C3B}
         LDA   ]Y0        ; {4C3B} Y0 = Y0 + SY
         CLC              ; {2C1B}
         ADC   ]SY        ; {4C3B}
         STA   ]Y0        ; {4C3B}
         LDA   ]Y0+1      ; {4C3B}
         ADC   #0         ; {3C2B} ]SY HIGH BYTE IS ALWAYS 0
         STA   ]Y0+1      ; {4C3B}
:SYSGTE
         JMP   :LOOP      ; {3C3B}
:HRBLEXIT
         RTS              ; {6C1B}

THE HCHAR MACRO

SUMMARY

Condition Value
Name HCHAR
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose plot a text character to the high resolution page
Input ]1 = X position
]2 = Y position
]3 = Byte series address to plot
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 432+
Bytes 296
Notes none
See Also HSTR HRSTR

DETAILS

The HCHAR macro simply plots a text character at the given X,Y coordinate to the high resolution working page in the specified color. Note that this macro does not call a subroutine, but directly plots bytes to the working page. While this allows for faster text character plotting, it also uses an inordinate number of bytes in the process. When possible, even when plotting a single character, the HSTR macro should be used in place of this macro unless only one or two characters need to be plotted to the screen throughout the entire program.

Note that this macro requires the user to include (PUT) the TBL.HRCHAR.ASM file in the main source code listing in order to function properly.

LISTING 9.19: The HCHAR Macro Source

*
*``````````````````````````````*
* HCHAR                        *
*                              *
* PLACE A CHARACTER AT THE     *
* GIVEN COORDINATES ON THE     *
* HIRES WORKING PAGE.          *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = X POSITION (2)         *
*  ]2 = Y POSITION (1)         *
*  ]3 = BYTE TO PRINT (1)      *
*                              *
* CYCLES: 432+                 *
* SIZE: 296 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HCHAR    MAC
         HBSET ]1;]2+0;]3+0 ; {54C37B}
         HBSET ]1;]2+1;]3+1 ; {54C37B}
         HBSET ]1;]2+2;]3+2 ; {54C37B}
         HBSET ]1;]2+3;]3+3 ; {54C37B}
         HBSET ]1;]2+4;]3+4 ; {54C37B}
         HBSET ]1;]2+5;]3+5 ; {54C37B}
         HBSET ]1;]2+6;]3+6 ; {54C37B}
         HBSET ]1;]2+7;]3+7 ; {54C37B}
         <<<
*

THE HSTR MACRO

SUMMARY

Condition Value
Name HSTR
Type Macro
File MAC.HIRES.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose plot a string of text characters to the high resolution page
Input ]1 = X position
]2 = Y position
]3 = String address
]4 = ASCII Offset value
Output none
Dependencies HRSTR
Flags Destroyed NZCV
Cycles 767+
Bytes 37
Notes none
See Also HCHAR HRSTR

DETAILS

The HSTR macro plots a string of text characters to the high resolution working page at the given X,Y coordinate and in the given color. The X position is numbered by character, 0..39, whereas the Y position is numbered by pixel placement, 0..191.

The fourth parameter of the macro, the ASCII offset value, can be used to either target specific machines that use slightly different characters or to force using lowercase characters when no equivalent exists on the machine. Generally, the #IIESET value defined in the collection header is most often used here, but the #LOWSET value is also defined for forcing lowercase letters on most Apple II machines.

LISTING 9.20: The HSTR Macro Source

*
*``````````````````````````````*
* HSTR                         *
*                              *
* PLOT A STRING OF CHARACTERS  *
* TO THE HIRES WORKING PAGE.   *
*                              *
* PARAMETERS:                  *
*                              *
*  ]1 = X POSITION (2)         *
*  ]2 = Y POSITION (1)         *
*  ]3 = STRING ADDRESS (2)     *
*  ]4 = OFFSET VALUE (1)       *
*                              *
* CYCLES: 767+                 *
* SIZE: 37 BYTES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
HSTR     MAC
         _MLIT ]1;ADDR3   ; {16C12B}
         LDA   ]2         ; {4C3B}
         STA   BPAR4      ; {3C2B}
         _MSTR ]3;WPAR3   ; {16C12B}
         LDA   ]4         ; {4C3B}
         STA   BPAR3      ; {3C2B}
         JSR   HRSTR      ; {721C3B}
         <<<

THE HRSTR SUBROUTINE

SUMMARY

Condition Value
Name HRSTR
Type Subroutine
File SUB.HRSTR.ASM
Author Nathan Riggs
Last Revision 31-MAY-2021
Assembler Merlin Pro 8
OS Apple DOS 3.3
Purpose plot a string of characters to the high resolution page
Input ADDR3 = X position
BPAR4 = Y position
WPAR3 = String address
BPAR3 = Charset offset
Output none
Dependencies none
Flags Destroyed NZCV
Cycles 715+
Bytes 639
Notes none
See Also HRCHAR HSTR

DETAILS

The HRSTR subroutine plots a string of text characters to the high resolution working page at the given X,Y position. The X position is numbered by characters on the horizontal space (0..39) while the Y position is numbered by single pixel (0..191).

The charset offset value is used to either target specific machines that use slightly different characters or to force using lowercase characters when no equivalent exists on the machine. Generally, the #IIESET value defined in the collection header is most often used here, but the #LOWSET value is also defined for forcing lowercase letters on most Apple II machines.

Note that this subroutine requires the TBL.HRCHAR.ASM table to be included (PUT) in the main program in order to function properly.

LISTING 9.21: The HRSTR Subroutine Source

*
*``````````````````````````````*
* HRSTR                        *
*                              *
* PRINT A STRING OF CHARACTERS *
* TO THE CURRENT WORKING PAGE  *
* OF THE HIRES SCREEN.         *
*                              *
* INPUT:                       *
*                              *
*  ADDR3 = X POSITION (2)      *
*  BPAR4 = Y POSITION (1)      *
*  WPAR3 = STRING ADDRESS (2)  *
*  BPAR3 = CHARSET OFFSET (1)  *
*                              *
* DESTROYS: NZCIDV             *
*           ^^^  ^             *
*                              *
* CYCLES: 715+                 *
* SIZE: 639 BYTES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
]STRX    HEX   0000       ; {0C2B} X POSITION (0..39)
]STRY    HEX   0000       ; {0C2B} Y POSITION (0..191)
]STR     HEX   0000       ; {0C2B} STRING ADDRESS
]TBL     HEX   0000       ; {0C2B} CHAR TABLE ADDRESS
]ADDR    HEX   0000       ; {0C2B} CHARACTER ADDRESS
]CHAR    HEX   0000       ; {0C2B} CHARACTGER OFFSET
]PRNBYTE HEX   0000       ; {0C2B} BYTE TO PLOT TO SCREEN
]STROFF  HEX   00         ; {0C1B} STRING OFFSET
]LEN     HEX   00         ; {0C1B} STRING LENGTH
]XCOUNT  HEX   00         ; {0C1B} STRING COUNTER
]BCOUNT  HEX   00         ; {0C1B} BYTE COUNTER
]YSUM    HEX   00         ; {0C1B} Y POSITION SUM
*
HRSTR
*
         LDA   ADDR3      ; {3C2B} X POSITION LOW BYTE
         STA   ]STRX      ; {4C3B}
         LDA   ADDR3+1    ; {3C2B} X POSITION HIGH BYTE
         STA   ]STRX+1    ; {4C3B}
         LDA   BPAR4      ; {3C2B} Y POSITION
         STA   ]STRY      ; {4C3B}
         LDA   #0         ; {3C2B} Y POS HIGH BYTE
         STA   ]STRY+1    ; {4C3B}
         LDA   WPAR3      ; {3C2B} STRING ADDRESS LOW
         STA   ]STR       ; {4C3B}
         LDA   WPAR3+1    ; {3C2B} STRING ADDRESS HIGH
         STA   ]STR+1     ; {4C3B}
         LDA   BPAR3      ; {3C2B} STRING OFFSET
         STA   ]STROFF    ; {4C3B}
*
         LDA   #0         ; {3C2B}
         STA   ]LEN       ; {4C3B}
         STA   ]XCOUNT    ; {4C3B}
         STA   ]BCOUNT    ; {4C3B}
*
         LDA   ]STR       ; {4C3B} ; GETE STRING LENGTH
         STA   ADDR3      ; {3C2B}
         LDA   ]STR+1     ; {4C3B}
         STA   ADDR3+1    ; {3C2B}
         LDY   #0         ; {3C2B}
         LDA   (ADDR3),Y  ; {5C3B}
         STA   ]LEN       ; {4C3B}
*
:LOOP
         LDA   ]LEN       ; {4C3B} IF LEN = XCOUNT, EXIT
         CMP   ]XCOUNT    ; {4C3B}
         BEQ   :EXIT      ; {3C2B}
         JMP   :CONT      ; {3C3B}
:EXIT    JMP   :HRSTREXIT ; {3C3B}
:CONT
         INC   ]XCOUNT    ; {5C3B} INCREMENT STRING CHAR POS
         LDY   ]XCOUNT    ; {4C3B}
         LDA   ]STR       ; {4C3B}
         STA   ADDR3      ; {3C2B}
         LDA   ]STR+1     ; {4C3B}
         STA   ADDR3+1    ; {3C2B}
         LDA   (ADDR3),Y  ; {5C3B} GET NEXT CHAR IN STRING
         SEC              ; {2C1B}
         SBC   ]STROFF    ; {4C3B} SUBTRACT OFFSET, NORMALLY #$A0
         STA   ]CHAR      ; {4C3B} STORE CHARACTER OFFSET
         LDA   #0         ; {3C2B}
         STA   ]CHAR+1    ; {4C3B}
*
         ASL   ]CHAR      ; {6C3B} MULTIPLY CHAR OFFSET BY 8
         ROL   ]CHAR+1    ; {6C3B} TO GET OFFSET IN BYTES
         ASL   ]CHAR      ; {6C3B}
         ROL   ]CHAR+1    ; {6C3B}
         ASL   ]CHAR      ; {6C3B}
         ROL   ]CHAR+1    ; {6C3B}
*
         LDA   ]CHAR      ; {4C3B} ADD TABLE ADDRESS TO
         CLC              ; {2C1B} CHAR OFFSET AND STORE AS
         ADC   #<HRCTBL   ; {4C3B} NEW ADDRESS. THIS IS THE
         STA   ]ADDR      ; {4C3B} ADDRESS OF THE INDIVIDUAL
         LDA   ]CHAR+1    ; {4C3B} CHARACTER IN THE TABLE
         ADC   #>HRCTBL   ; {4C3B}
         STA   ]ADDR+1    ; {4C3B}
*
         LDA   ]ADDR      ; {4C3B}
         STA   ADDR3      ; {3C2B}
         LDA   ]ADDR+1    ; {4C3B}
         STA   ADDR3+1    ; {3C2B}
*
         LDY   #0         ; {3C2B} RESET BYTE COUNTER
         STY   ]BCOUNT    ; {4C3B}
         LDA   (ADDR3),Y  ; {5C3B} LOAD BYTE TO PLOT
         STA   ]PRNBYTE   ; {4C3B}
         LDA   ]BCOUNT    ; {4C3B}
         CLC              ; {2C1B} NOW GET Y POS OFFSET
         ADC   ]STRY      ; {4C3B}
         STA   ]YSUM      ; {4C3B}
         HBSET ]STRX;]YSUM;]PRNBYTE ; {54C37B} PLOT BYTE
*
         INC   ]BCOUNT    ; {5C3B} INCREMENT BYTE COUNTER
         LDY   ]BCOUNT    ; {4C3B}
         LDA   (ADDR3),Y  ; {5C3B} LOAD BYTE TO PRINT
         STA   ]PRNBYTE   ; {4C3B}
         TYA              ; {2C1B} NOW GET Y OFFSET
         CLC              ; {2C1B}
         ADC   ]STRY      ; {4C3B}
         STA   ]YSUM      ; {4C3B}
         HBSET ]STRX;]YSUM;]PRNBYTE ; {54C37B} PLOT CHARACTER
*
         INC   ]BCOUNT    ; {5C3B}
         LDY   ]BCOUNT    ; {4C3B}
         LDA   (ADDR3),Y  ; {5C3B}
         STA   ]PRNBYTE   ; {4C3B}
         TYA              ; {2C1B}
         CLC              ; {2C1B}
         ADC   ]STRY      ; {4C3B}
         STA   ]YSUM      ; {4C3B}
         HBSET ]STRX;]YSUM;]PRNBYTE ; {54C37B}
*
         INC   ]BCOUNT    ; {5C3B}
         LDY   ]BCOUNT    ; {4C3B}
         LDA   (ADDR3),Y  ; {5C3B}
         STA   ]PRNBYTE   ; {4C3B}
         TYA              ; {2C1B}
         CLC              ; {2C1B}
         ADC   ]STRY      ; {4C3B}
         STA   ]YSUM      ; {4C3B}
         HBSET ]STRX;]YSUM;]PRNBYTE ; {54C37B}
*
         INC   ]BCOUNT    ; {5C3B}
         LDY   ]BCOUNT    ; {4C3B}
         LDA   (ADDR3),Y  ; {5C3B}
         STA   ]PRNBYTE   ; {4C3B}
         TYA              ; {2C1B}
         CLC              ; {2C1B}
         ADC   ]STRY      ; {4C3B}
         STA   ]YSUM      ; {4C3B}
         HBSET ]STRX;]YSUM;]PRNBYTE ; {54C37B}
*
         INC   ]BCOUNT    ; {5C3B}
         LDY   ]BCOUNT    ; {4C3B}
         LDA   (ADDR3),Y  ; {5C3B}
         STA   ]PRNBYTE   ; {4C3B}
         TYA              ; {2C1B}
         CLC              ; {2C1B}
         ADC   ]STRY      ; {4C3B}
         STA   ]YSUM      ; {4C3B}
         HBSET ]STRX;]YSUM;]PRNBYTE ; {54C37B}
*
         INC   ]BCOUNT    ; {5C3B}
         LDY   ]BCOUNT    ; {4C3B}
         LDA   (ADDR3),Y  ; {5C3B}
         STA   ]PRNBYTE   ; {4C3B}
         TYA              ; {2C1B}
         CLC              ; {2C1B}
         ADC   ]STRY      ; {4C3B}
         STA   ]YSUM      ; {4C3B}
         HBSET ]STRX;]YSUM;]PRNBYTE ; {54C37B}
*
         INC   ]BCOUNT    ; {5C3B}
         LDY   ]BCOUNT    ; {4C3B}
         LDA   (ADDR3),Y  ; {5C3B}
         STA   ]PRNBYTE   ; {4C3B}
         TYA              ; {2C1B}
         CLC              ; {2C1B}
         ADC   ]STRY      ; {4C3B}
         STA   ]YSUM      ; {4C3B}
         HBSET ]STRX;]YSUM;]PRNBYTE ; {54C37B}
*
         INC   ]STRX      ; {5C3B}
         JMP   :LOOP      ; {3C3B}
*
:HRSTREXIT
         RTS              ; {6C1B}

Part II: The HiRes Collection Demo

Listing 9.22 contains demonstrations of how to use the macros in the high resolution collection.

LISTING 9.22: The DEMO.HIRES.ASM Source

*
*``````````````````````````````*
* DEMO.LORES                   *
*                              *
* A DEMO OF THE MACROS AND     *
* SUBROUTINES FOR USING LORES  *
* GRAPHICS.                    *
*                              *
* AUTHOR:    NATHAN RIGGS      *
* CONTACT:   NATHAN.RIGGS@     *
*            OUTLOOK.COM       *
*                              *
* DATE:      03-OCT-2019       *
* ASSEMBLER: MERLIN 8 PRO      *
* OS:        DOS 3.3           *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** ASSEMBLER DIRECTIVES
*
         CYC   AVE
         EXP   OFF
         TR    ON
         DSK   DEMO.HIRES
         OBJ   $BFE0
         ORG   $6000
*
*``````````````````````````````*
*  TOP INCLUDES (PUTS, MACROS) *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
         PUT   MIN.HEAD.REQUIRED.ASM
         PUT   MIN.HEAD.HIRES.ASM
         USE   MIN.MAC.REQUIRED.ASM
         USE   MIN.MAC.HIRES.ASM
*
*``````````````````````````````*
*      PROGRAM MAIN BODY       *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
         BIT   HPAGE1
         HCLR  #HBLACK1
         BIT   HMIXOFF
         BIT   HIRES
         BIT   GRAPHICS
*
*``````````````````````````````*
* HIRES CHARACTERS             *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE HIRES COLLECTION PROVIDES TWO WAYS TO PLOT
** CHARACTERS TO THE SCREEN: HCHAR AND HSTR. HCHAR
** PLOTS A SINGLE CHARACTER, WHILE HSTR PLOTS AN
** ENTIRE STRING TO THE WORKING HIRES PAGE.
*
** GENERALLY, HCHAR SHOULD BE AVOIDED AS IT WILL
** QUICKLY EAT UP AVAILABLE MEMORY IF USED EXTENSIVELY.
** EVEN WHEN PLOTTING A SINGLE CHARACTER, HRSTR IS
** USUALLY MORE APPROPRIATE UNLESS SPEED IS A CONCERN.
*
** HCHAR TAKES AN X-POSITION OF THE BYTE (0..39), A
** PIXEL Y-POSITION (0..191) AND THE BYTE TO PLOT TO
** THE SCREEN. NOTE THAT BECAUSE COLORS ARE DETERMINED
** BY SCREEN POSITION, THERE IS NO OPTION FOR CHANGING
** THE COLOR OF THE TEXT. THE CHARACTER TABLE IS BUILT
** WITH THE ASSUMPTION THAT THE TEXT WILL BE WHITE, AS
** EACH CHARACTER DOUBLES UP ON ADJACENT PIXELS AS MUCH
** AS POSSIBLE TO AVOID ACCIDENTAL TINTS (THIS IS UNAVOIDABLE
** IN THE LONG RUN, HOWEVER).
*
** THE HSTR MACRO SIMILARLY TAKES AN X AND Y POSITION WITH
** THE CHARACTER TO BE PLOTTED. ADDITIONALLY, THIS MACRO
** ACCEPTS A CHANGEABLE OFFSET FOR DIFFERENT ASCII TABLE
** CONFIGURATIONS ON DIFFERENT MACHINES. AS A BONUS, IT IS
** ALSO POSSIBLE TO SET THE OFFSET SO THAT EVEN IF A MACHINE
** DOES NOT HAVE LOWERCASE LETTERS, THEY CAN BE PLOTTED TO
** THE HIRES SCREEN.
*
         HCHAR #20;#160;HRT_T
         HCHAR #21;#160;HRT_E
         HCHAR #22;#160;HRT_S
         HCHAR #23;#160;HRT_T
*
         HSTR  #0;#0;#STR0;#IIESET
         HSTR  #0;#16;#STR1;#IIESET
         HSTR  #0;#24;#STR2;#IIESET
         HSTR  #0;#32;#STR3;#IIESET
         HSTR  #0;#40;#STR4;#IIESET
         HSTR  #0;#48;#STR5;#LOWSET
*
*``````````````````````````````*
* FILLING THE SCREEN           *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE HCLR MACRO FILLS THE SCREEN WITH THE COLOR
** SPECIFIED BY THE GIVEN COLOR CODE.
*
         _WAIT
         HCLR  #0
         _WAIT
         HCLR  #1
         _WAIT
         HCLR  #2
         _WAIT
         HCLR  #3
         _WAIT
         HCLR  #4
         _WAIT
         HCLR  #5
         _WAIT
         HCLR  #6
         _WAIT
         HCLR  #7
         _WAIT
         HCLR  #HBLACK1
*
*``````````````````````````````*
* HIRES PIXEL PLOTTING         *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE HPLOT MACRO PLOTS A PIXEL AT A GIVE X,Y COORDINATE
** IN THE SPECIFIED COLOR TO THE WORKING HIRES PAGE (SEE
** BELOW). NOTE THAT BECAUSE OF THE WAY THAT THE APPLE II
** ORGANIZES THE HIRES MEMORY PAGE, THIS IS ACTUALLY MUCH
** SLOWER THAN PLOTTING ENTIRE BYTES (SEE BELOW).
*
** CURRENTLY, THE PLOTTING SUBROUTINE IS NOT OPTIMIZED.
** THIS MAKES IT EASIER TO UNDERSTAND, BUT ALSO CAUSES
** THE PLOTTING SUBROUTINE TO BE SLIGHTLY SLOWER THAN THE
** EQUIVALENT APPLESOFT SUBROUTINE, EVEN USING TABLE LOOKUPS.
** THIS WILL BE ADDRESSED IN FUTURE UPDATES.
*
         HPLOT #160;#95;#HWHITE1
         HPLOT #161;#96;#HWHITE1
         HPLOT #162;#97;#HWHITE1
         HPLOT #162;#98;#HWHITE1
         _WAIT
*
*``````````````````````````````*
* HORIZONTAL LINES             *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE HLIN MACRO DRAWS A HORIZONTAL LINE TO THE
** WORKING HIRES PAGE STARTING AT AN X ORIGIN AND
** CONTINUING TO AN X DESTINATION AT THE GIVEN
** Y COORDINATE AND COLOR.
*
         LDY   #255
         STY   COUNTER
LP
         INC   COUNTER
         HLIN #10;#050;COUNTER;#HBLUE
         LDY   COUNTER
         CPY   #191
         BNE   LP
*
*``````````````````````````````*
* VERTICAL LINES               *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE VLIN MACRO CREATES A VERTICAL LINE AT THE
** GIVEN X AXIS STARTING AT A Y ORIGIN AND ENDING
** AT A Y DESTINATION (IN THE PROVIDED COLOR).
*
         VLIN  #10;#100;#20;#HGREEN
         VLIN  #10;#100;#21;#HGREEN
         VLIN  #10;#100;#100;#HGREEN
         VLIN  #10;#100;#101;#HGREEN
         VLIN  #10;#100;#102;#HGREEN
         VLIN  #10;#100;#103;#HGREEN
         VLIN  #10;#100;#104;#HGREEN
         VLIN  #10;#100;#105;#HGREEN
         VLIN  #10;#100;#106;#HGREEN
         VLIN  #10;#100;#107;#HGREEN
*
** NOTE TWO THINGS HERE: FIRST, WHEN GREEN IS
** PLOTTED NEXT TO PURPLE, THE RESULTING COLOR IS
** WHITE: THIS IS INEVITABLE, AND REQUIRES FORETHOUGHT
** WHEN USING HIRES GRAPHICS. SECOND, IF YOU LOOK
** CLOSELY YOU CAN SEE THAT SOME GREEN LINES ARE NOT
** PLOTTED TO THE SCREEN. THIS, TOO, IS DUE TO THE WAY
** THAT THE APPLE II DISPLAYS COLOR, AND IS UNAVOIDABLE.
*
*
*``````````````````````````````*
* ARBITRARY LINES              *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE LAST OF THE PIXEL-BY-PIXEL PLOTTING MACROS
** IS THE LINE MACRO, WHICH PLOTS A LINE FROM A
** GIVEN X0,Y0 STARTING POINT TO AN ENDING X1,Y1
** COORDINATE, IN THE COLOR SPECIFIED. NOTE THAT
** SINCE THIS USES THE PLOTTING ROUTINE, COLOR
** ISSUES ARE ALREADY TAKEN CARE OF; A BLUE LINE
** WILL ONLY PLOT TO BLUE PIXELS, GREEN TO GREEN,
** ETC. HOWEVER, THIS DOES HAVE THE POTENTIAL TO
** CHANGE THE HIGH BIT OF A BYTE IN SCREEN MEMORY
** THAT WILL RESULT IN CHANGING THE COLOR OF NEARBY
** PIXELS. THIS IS AGAIN UNAVOIDABLE, AND CARE HAS
** TO BE TAKEN BY THE USER TO ONLY PLOT LINES WHERE
** THE HIGH BYTES MATCH.
*
         LINE  #01;#01;#200;#048;#HBLUE
         LINE  #200;#1;#250;#100;#HPURPLE
         LINE  #10;#10;#200;#150;#HORANGE
         _WAIT
*
** NOTE THAT CURRENTLY, THE LINE ALGORITHM IS
** EQUIPPED ONLY TO GO FROM LOWER VALUES TO
** HIGHER VALUES, ON BOTH X AND Y AXES. THIS WILL
** BE FIXED IN A FUTURE UPDATE.
*
*``````````````````````````````*
* PLOTTING BYTES TO THE SCREEN *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THE HBSET MACRO PLOTS AN ENTIRE BYTE TO
** SCREEN MEMORY. THIS CAN BE USED FOR QUICKLY
** DISPLAYING TILES (LIKE THE HIRES CHARACTERS)
** ON THE SCREEN. NOTE THAT SINCE COLOR IS
** DETERMINED BY SCREEN POSITION, THE VALUE OF
** THE BYTE DETERMINES THE COLORS OF THE INDIVIDUAL
** PIXELS. THIS IS FURTHER CONFOUNDED BY THE FACT
** THAT EVEN AND ODD COLUMNS OF BYTES REVERSE WHICH
** COLOR IS PLOTTED BASED ON POSITION, SO CARE MUST
** BE TAKEN WELL AHEAD OF TIME TO GUARANTEE THE CORRECT
** COLORS WILL BE DISPLAYED.
*
         HBSET #10;#100+0;TILE+0
         HBSET #10;#100+1;TILE+1
         HBSET #10;#100+2;TILE+2
         HBSET #10;#100+3;TILE+3
         HBSET #10;#100+4;TILE+4
         HBSET #10;#100+5;TILE+5
         HBSET #10;#100+6;TILE+6
         HBSET #10;#100+7;TILE+7
*
** IF YOU LOOK AT THE TILE DEFINITION AT THE
** BOTTOM OF THIS LISTING, YOU'LL SEE THAT A
** TILE IS 7 * 8 BITS WIDE AND LONG (THE HIGH
** BIT OF EACH BYTE IS USED FOR COLOR, AND IS
** NOT INCLUDED HERE; HOWEVER, IT CAN BE INCLUDED
** IF COLOR IS A CONCERN). THIS MEANS THAT EACH
** TILE CONSISTS OF 8 BYTES, TO BE PLOTTED IN THE
** ORDER ABOVE.
*
*``````````````````````````````*
* PAGE FLIPPING                *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** THERE ARE TWO PAGES FOR THE HIRES SCREEN THAT
** CAN BE PLOTTED TO OR VIEWED SEPERATELY. THIS IS
** MOSTLY USED TO CREATE SMOOTHER ANIMATIONS. THE
** MACROS USED TO HANDLE THIS ARE HVIEWPG AND
** HWORKPG, FOR SETTING THE PAGE TO CURRENTLY DISPLAY
** AND FOR SETTING THE PAGE TO PLOT TO, RESPECTIVELY.
*
********************************
*
** NOTE: THIS DOES NOT WORK IF YOU CURRENTLY HAVE
** MERLIN 8 PRO LOADED. TO SEE THIS IN EFFECT, YOU
** WILL HAVE TO BOOT FROM A CLEAN DOS DISK, THEN LOAD
** THIS DISK.
*
********************************
*
         HWORKPG #2       ; SET THE PLOTTING PAGE TO 2
                          ; WHILE THE VIEWING PAGE IS STILL
                          ; SET TO PAGE 1
*
         HCLR  #HBLACK1
         HSTR  #10;#10;"PAGE 2!";#IIESET
         HVIEWPG #2       ; DISPLAY PAGE 2
         _WAIT
         HVIEWPG #1       ; SET TO VIEW PAGE 1 AGAIN
         HWORKPG #1       ; ALSO PLOT TO PAGE 1 AGAIN
         _WAIT
*
         BIT   HTEXTM     ; SET TEXT MODE
         _PRN  " ",8D8D
         _PRN  "FIN!",8D8D
*
         JMP   $3D0
*
*``````````````````````````````*
*        BOTTOM INCLUDES       *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
** BOTTOM INCLUDES
*
         PUT   MIN.LIB.REQUIRED.ASM
*
** INDIVIDUAL SUBROUTINE INCLUDES
*
         PUT   MIN.SUB.HRPLOT.ASM
         PUT   MIN.SUB.HCLEAR.ASM
         PUT   MIN.SUB.HRHLINE.ASM
         PUT   MIN.SUB.HRVLINE.ASM
         PUT   MIN.SUB.HRBLINE.ASM
         PUT   MIN.SUB.HRSTR.ASM
         PUT   TBL.HRCHAR.ASM
         PUT   TBL.HIRES.ASM
         PUT   TBL.DB7.ASM
*
COUNTER  DS    1
STR0     STR   "WELCOME TO HIGH RESOLUTION!"
STR1     STR   " !#$%&'()*+,-./0123456789:;<=>?@"
STR2     HEX   01A2       ; THIS IS A " CHARACTER
STR3     STR   "ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_`"
STR4     STR   "abcdefghijklmnopqrstuvwxyz{|}~"
STR5     STR   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
TILE     DB    %1111111
         DB    %1000001
         DB    %1010101
         DB    %1000001
         DB    %1010101
         DB    %1011101
         DB    %1000001
         DB    %1111111