;------------------------------------------------------------------------------
; C callable functions
+ .global _joy_load_driver
.global _joy_unload
.global _joy_install
.global _joy_uninstall
TGI_MODE_160_200_4 ; 160x200, 4 colors
TGI_MODE_640_200_2 ; 640x200, 2 colors (b/w)
TGI_MODE_640_480_2 ; 640x480, 2 colors (b/w)
- TGI_MODE_280_192_6 ; 280x192, 6 colors
- TGI_MODE_560_192_2 ; 560x192, 2 colors
- TGI_MODE_40_40_16 ; 40x40, 16 colors
+ TGI_MODE_280_192_8 ; 280x192, 8 colors
+ TGI_MODE_40_48_16 ; 40x48, 16 colors
.endenum
The standard binary output format generated by the linker for the
Apple ][ target is a machine language program with a 4 byte DOS
-3.3 header. The standard load address is $800.
+3.3 header. The standard load address is $803.
The DOS header is in its own segment named <tt/EXEHDR/. If you don't want the
header for some reason, you can change
<verb>
- HEADER: start = $0000, size = $4, file = %O;
+ HEADER: start = $0000, size = $0004, file = %O;
</verb>
to
<verb>
- HEADER: start = $0000, size = $4, file = "";
+ HEADER: start = $0000, size = $0004, file = "";
</verb>
in the linker configuration to have the linker remove it.
-Please note that there is a "Apple ][ ProDOS 8 system program
-for loading binary programs" available in the cc65 User Contributions section.
+Please note that there is an 'Apple ][ ProDOS 8 system program
+for loading binary programs' available in the cc65 User Contributions section.
It adds all benefits of a ProDOS 8 system program to the standard binary
program generated by the linker for the Apple ][ target.
<sect>Memory layout<p>
In the standard setup, cc65 generated programs use the memory from
-$800 to $95FF, so 35.5K of memory are available. ROM calls are
-possible without further precautions.
+$803 to $95FF, so 35.5KB of RAM are available. While running
+<tt/main()/ the Language Card bank 2 is enabled for read access. However while
+running module constructors/destructors the Language Card is disabled.
Special locations:
runtime stack.
</descrip><p>
+Enabling the Language Card allows to use it as additional memory for executable
+code. Actually doing so requires either to compile code with the option
+<tt/--code-name HIGHCODE/ or to use <tt/#pragma codeseg ("HIGHCODE")/.
+
+The amount of memory available in the Language Card for executable code depends
+on the chosen program environment. A plain vanilla ProDOS 8 doesn't actually
+use the Language Card bank 2 memory from $D400 to $DFFF.
+Therefore the builtin linker configuration defines these 3KB as <tt/LC/ memory
+area for executable code.
+
+A plain vanilla DOS 3.3 doesn't make use of the Language Card at all. So you
+can change
+
+<verb>
+ LC: start = $D400, size = $0C00, define = yes;
+</verb>
+
+to
+
+<verb>
+ LC: start = $D000, size = $3000, define = yes;
+</verb>
+
+in the linker configuration to define the whole 12KB Language Card address
+space as memory area for executable code.
+
<sect>Platform specific header files<p>
<descrip>
<tag><tt/a2.lo.tgi/</tag>
- This driver was written by Stefan Haubenthal. It features a resolution of
- 40×40 with 16 colors. At the bottom of the screen, 4 additional text
- lines are available.
+ This driver features a resolution of 40×48 with 16 colors.
<tag><tt/a2.hi.tgi/</tag>
- This driver was written by Stefan Haubenthal. It features a resolution of
- 280×192 with 6 colors. Note that programs using this driver will have
- to be linked with <tt/--start-addr $4000/ to reserve the first hires page.
+ This driver features a resolution of 280×192 with 8 colors and two
+ hires pages. Note that programs using this driver will have to be linked
+ with <tt/--start-addr $4000/ to reserve the first hires page or with
+ <tt/--start-addr $6000/ to reserve both hires pages.
+
+ In memory constrained situations the memory from $803 to $1FFF
+ can be made available to a program by executing <tt/_heapadd ((void *) 0x0803, 0x17FD);/
+ at the beginning of <tt/main()/. Doing so is beneficial even if the program
+ doesn't use the the heap explicitly because loading the driver (and in fact
+ already opening the driver file) uses the heap implicitly.
</descrip><p>
<descrip>
- <tag><tt/a2.lc.emd/</tag>
- Gives access to 12KB RAM (48 pages of 256 bytes each) on the
- Apple II Language Card. The driver was contributed by Stefan Haubenthal.
- Note that this driver is incompatible with any DOS using the Language
- Card memory!
+ <tag><tt/a2.auxmem.emd/</tag>
+ Gives access to 47,5 KB RAM (190 pages of 256 bytes each) on an Extended
+ 80-Column Text Card.
+
+ Note that this driver doesn't check for the actual existence of the memory
+ and that it doesn't check for ProDOS 8 RAM disk content!
</descrip><p>
<tag><tt/a2.stdmou.mou/</tag>
Driver for the AppleMouse II Card. Searches all Apple II slots
for an AppleMouse II Card compatible firmware. The default bounding
- box is [0..279,0..191]. Programs using this driver will have
- to be linked with <tt/--start-addr $4000/ to reserve the first hires page
- if they are intended to run on an Apple ][ (in contrast to
- an Apple //e).
+ box is [0..279,0..191].
+
+ Programs using this driver will have to be linked with <tt/--start-addr $4000/
+ to reserve the first hires page if they are intended to run on an
+ Apple ][ (in contrast to an Apple //e) because the
+ AppleMouse II Card firmware writes to the hires page when initializing
+ on that machine.
Note that the Apple ][ default mouse callbacks support text
mode only.
flow control because of a full buffer.
The driver defaults to slot 2. Call <tt/ser_ioctl(0, <slot>)/ prior to
- <tt/ser_open/ in order to select a different slot. <tt/ser_ioctl/ succeeds
- for all Apple II slots, but <tt/ser_open/ fails with
+ <tt/ser_open()/ in order to select a different slot. <tt/ser_ioctl()/
+ succeeds for all Apple II slots, but <tt/ser_open()/ fails with
<tt/SER_ERR_NO_DEVICE/ if there's no SSC firmware found in the selected slot.
</descrip><p>
supported by BASIC, the following syntax was chosen:
<tscreen><verb>
-]CALL2048:REM ARG1 " ARG2 IS QUOTED" ARG3 "" ARG5
+]CALL2051:REM ARG1 " ARG2 IS QUOTED" ARG3 "" ARG5
</verb></tscreen>
<enum>
<sect1>Interrupts<p>
The runtime for the Apple ][ uses routines marked as <tt/.CONDES/
-type 2 for ProDOS interrupt handlers. Such routines must be written as simple
-machine language subroutines and will be called automatically by the interrupt
-handler code when they are linked into a program. See the discussion of the
-<tt/.CONDES/ feature in the <htmlurl url="ca65.html" name="assembler manual">.
+type <tt/interruptor/ for ProDOS 8 interrupt handlers. Such routines must be
+written as simple machine language subroutines and will be called automatically
+by the interrupt handler code when they are linked into a program. See the
+discussion of the <tt/.CONDES/ feature in the <htmlurl url="ca65.html"
+name="assembler manual">.
<sect>License<p>
This software is provided 'as-is', without any expressed or implied
-warranty. In no event will the authors be held liable for any damages
+warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
The standard binary output format generated by the linker for the
enhanced Apple //e target is a machine language program with a 4 byte DOS
-3.3 header. The standard load address is $800.
+3.3 header. The standard load address is $803.
The DOS header is in its own segment named <tt/EXEHDR/. If you don't want the
header for some reason, you can change
<verb>
- HEADER: start = $0000, size = $4, file = %O;
+ HEADER: start = $0000, size = $0004, file = %O;
</verb>
to
<verb>
- HEADER: start = $0000, size = $4, file = "";
+ HEADER: start = $0000, size = $0004, file = "";
</verb>
in the linker configuration to have the linker remove it.
-Please note that there is a "Apple ][ ProDOS 8 system program
-for loading binary programs" available in the cc65 User Contributions section.
+Please note that there is an 'Apple ][ ProDOS 8 system program
+for loading binary programs' available in the cc65 User Contributions section.
It adds all benefits of a ProDOS 8 system program to the standard binary
program generated by the linker for the enhanced Apple //e target.
<sect>Memory layout<p>
In the standard setup, cc65 generated programs use the memory from
-$800 to $95FF, so 35.5K of memory are available. ROM calls are
-possible without further precautions.
+$803 to $95FF, so 35.5KB of RAM are available. While running
+<tt/main()/ the Language Card bank 2 is enabled for read access. However while
+running module constructors/destructors the Language Card is disabled.
Special locations:
runtime stack.
</descrip><p>
+Enabling the Language Card allows to use it as additional memory for executable
+code. Actually doing so requires either to compile code with the option
+<tt/--code-name HIGHCODE/ or to use <tt/#pragma codeseg ("HIGHCODE")/.
+
+The amount of memory available in the Language Card for executable code depends
+on the chosen program environment. A plain vanilla ProDOS 8 doesn't actually
+use the Language Card bank 2 memory from $D400 to $DFFF.
+Therefore the builtin linker configuration defines these 3KB as <tt/LC/ memory
+area for executable code.
+
+A plain vanilla DOS 3.3 doesn't make use of the Language Card at all. So you
+can change
+
+<verb>
+ LC: start = $D400, size = $0C00, define = yes;
+</verb>
+
+to
+
+<verb>
+ LC: start = $D000, size = $3000, define = yes;
+</verb>
+
+in the linker configuration to define the whole 12KB Language Card address
+space as memory area for executable code.
+
<sect>Platform specific header files<p>
<descrip>
<tag><tt/a2e.lo.tgi/</tag>
- This driver was written by Stefan Haubenthal. It features a resolution of
- 40×40 with 16 colors. At the bottom of the screen, 4 additional text
- lines are available.
+ This driver features a resolution of 40×48 with 16 colors.
<tag><tt/a2e.hi.tgi/</tag>
- This driver was written by Stefan Haubenthal. It features a resolution of
- 280×192 with 6 colors. Note that programs using this driver will have
- to be linked with <tt/--start-addr $4000/ to reserve the first hires page.
+ This driver features a resolution of 280×192 with 8 colors and two
+ hires pages. Note that programs using this driver will have to be linked
+ with <tt/--start-addr $4000/ to reserve the first hires page or with
+ <tt/--start-addr $6000/ to reserve both hires pages.
+
+ In memory constrained situations the memory from $803 to $1FFF
+ can be made available to a program by executing <tt/_heapadd ((void *) 0x0803, 0x17FD);/
+ at the beginning of <tt/main()/. Doing so is beneficial even if the program
+ doesn't use the the heap explicitly because loading the driver (and in fact
+ already opening the driver file) uses the heap implicitly.
</descrip><p>
<descrip>
- <tag><tt/a2e.lc.emd/</tag>
- Gives access to 12KB RAM (48 pages of 256 bytes each) on the
- Apple II Language Card. The driver was contributed by Stefan Haubenthal.
- Note that this driver is incompatible with any DOS using the Language
- Card memory!
+ <tag><tt/a2e.auxmem.emd/</tag>
+ Gives access to 47,5 KB RAM (190 pages of 256 bytes each) on an Extended
+ 80-Column Text Card.
+
+ Note that this driver doesn't check for the actual existence of the memory
+ and that it doesn't check for ProDOS 8 RAM disk content!
</descrip><p>
flow control because of a full buffer.
The driver defaults to slot 2. Call <tt/ser_ioctl(0, <slot>)/ prior to
- <tt/ser_open/ in order to select a different slot. <tt/ser_ioctl/ succeeds
- for all Apple II slots, but <tt/ser_open/ fails with
+ <tt/ser_open()/ in order to select a different slot. <tt/ser_ioctl()/
+ succeeds for all Apple II slots, but <tt/ser_open()/ fails with
<tt/SER_ERR_NO_DEVICE/ if there's no SSC firmware found in the selected slot.
</descrip><p>
supported by BASIC, the following syntax was chosen:
<tscreen><verb>
-]CALL2048:REM ARG1 " ARG2 IS QUOTED" ARG3 "" ARG5
+]CALL2051:REM ARG1 " ARG2 IS QUOTED" ARG3 "" ARG5
</verb></tscreen>
<enum>
<sect1>Interrupts<p>
The runtime for the enhanced Apple //e uses routines marked as <tt/.CONDES/
-type 2 for ProDOS interrupt handlers. Such routines must be written as simple
-machine language subroutines and will be called automatically by the interrupt
-handler code when they are linked into a program. See the discussion of the
-<tt/.CONDES/ feature in the <htmlurl url="ca65.html" name="assembler manual">.
+type <tt/interruptor/ for ProDOS 8 interrupt handlers. Such routines must be
+written as simple machine language subroutines and will be called automatically
+by the interrupt handler code when they are linked into a program. See the
+discussion of the <tt/.CONDES/ feature in the <htmlurl url="ca65.html"
+name="assembler manual">.
<sect>License<p>
This software is provided 'as-is', without any expressed or implied
-warranty. In no event will the authors be held liable for any damages
+warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
Using -S you may define the default starting address. If and how this
address is used depends on the config file in use. For the builtin
- configurations, only the "none" system honors an explicit start address,
- all other builtin config provide their own.
+ configurations, only the "none", "apple2" and "apple2enh" systems honor an
+ explicit start address, all other builtin config provide their own.
<tag><tt>-V, --version</tt></tag>
doc directory) and don't have a special format. So if you need a special
configuration, it's a good idea to start with the builtin configuration for
your system. In a first step, just replace <tt/-t target/ by <tt/-C
-configfile/. The go on and modify the config file to suit your needs.
+configfile/. Then go on and modify the config file to suit your needs.
-/* Color Defines
- * Since Apple2 does not support color text these defines are only
- * used to get the library to compile correctly. They should not be used
- * in user code
- */
+/* Color Defines */
#define COLOR_BLACK 0x00
-#define COLOR_WHITE 0x01
+#define COLOR_GREEN 0x01
+#define COLOR_VIOLET 0x02
+#define COLOR_WHITE 0x03
+#define COLOR_BLACK2 0x04
+#define COLOR_ORANGE 0x05
+#define COLOR_BLUE 0x06
+#define COLOR_WHITE2 0x07
+
+#define LORES_BLACK 0x00
+#define LORES_MAGENTA 0x01
+#define LORES_DARKBLUE 0x02
+#define LORES_VIOLET 0x03
+#define LORES_DARKGREEN 0x04
+#define LORES_GRAY 0x05
+#define LORES_BLUE 0x06
+#define LORES_CYAN 0x07
+#define LORES_BROWN 0x08
+#define LORES_ORANGE 0x09
+#define LORES_GRAY2 0x0A
+#define LORES_PINK 0x0B
+#define LORES_GREEN 0x0C
+#define LORES_YELLOW 0x0D
+#define LORES_AQUA 0x0E
+#define LORES_WHITE 0x0F
/* Characters codes */
#define CH_ENTER 0x0D
* ProDOS 8 1.6 - 0x16
* ProDOS 8 1.7 - 0x17
* ProDOS 8 1.8 - 0x18
- * ProDOS 8 1.9 - 0x18
+ * ProDOS 8 1.9 - 0x18 (!)
* ProDOS 8 2.0.1 - 0x21
* ProDOS 8 2.0.2 - 0x22
* ProDOS 8 2.0.3 - 0x23
#define TGI_MODE_160_200_4 2U /* 160x200, 4 colors */
#define TGI_MODE_640_200_2 3U /* 640x200, 2 colors (b/w) */
#define TGI_MODE_640_480_2 4U /* 640x480, 2 colors (b/w) */
-#define TGI_MODE_280_192_6 5U /* 280x192, 6 colors */
+#define TGI_MODE_280_192_8 5U /* 280x192, 8 colors */
+#define TGI_MODE_40_48_16 6U /* 40x48, 16 colors */
done
mv apple2/crt0.o apple2.o
cp apple2/apple2-auxmem.emd a2.auxmem.emd
- cp apple2/apple2-lc.emd a2.lc.emd
cp apple2/apple2-stdjoy.joy a2.stdjoy.joy
cp apple2/apple2-stdmou.mou a2.stdmou.mou
cp apple2/apple2-ssc.ser a2.ssc.ser
- cp apple2/apple2-40-40-16.tgi a2.lo.tgi
- cp apple2/apple2-280-192-6.tgi a2.hi.tgi
+ cp apple2/apple2-280-192-8.tgi a2.hi.tgi
+ cp apple2/apple2-40-48-16.tgi a2.lo.tgi
#-----------------------------------------------------------------------------
# Apple //e
done
mv apple2enh/crt0.o apple2enh.o
cp apple2enh/apple2-auxmem.emd a2e.auxmem.emd
- cp apple2enh/apple2-lc.emd a2e.lc.emd
cp apple2enh/apple2-stdjoy.joy a2e.stdjoy.joy
cp apple2enh/apple2-stdmou.mou a2e.stdmou.mou
cp apple2enh/apple2-ssc.ser a2e.ssc.ser
- cp apple2enh/apple2-40-40-16.tgi a2e.lo.tgi
- cp apple2enh/apple2-280-192-6.tgi a2e.hi.tgi
+ cp apple2enh/apple2-280-192-8.tgi a2e.hi.tgi
+ cp apple2enh/apple2-40-48-16.tgi a2e.lo.tgi
#-----------------------------------------------------------------------------
# Atari
close.o \
clrscr.o \
color.o \
+ cout.o \
cputc.o \
crt0.o \
ctype.o \
get_ostype.o \
gotoxy.o \
gotoy.o \
+ home.o \
initcwd.o \
joy_stddrv.o \
kbhit.o \
oserrlist.o \
oserror.o \
randomize.o \
- rcout.o \
+ rdkey.o \
read.o \
revers.o \
- rhome.o \
- rom.o \
- rpread.o \
- rrdkey.o \
- rvtabz.o \
rwcommon.o \
syschdir.o \
sysmkdir.o \
systime.o \
sysuname.o \
tgi_mode_table.o\
+ vtabz.o \
wherex.o \
wherey.o \
write.o
#--------------------------------------------------------------------------
# Drivers
-EMDS = apple2-auxmem.emd apple2-lc.emd
+EMDS = apple2-auxmem.emd
JOYS = apple2-stdjoy.joy
SERS = apple2-ssc.ser
-TGIS = apple2-40-40-16.tgi apple2-280-192-6.tgi
+TGIS = apple2-280-192-8.tgi apple2-40-48-16.tgi
#--------------------------------------------------------------------------
# Targets
+++ /dev/null
-;
-; Graphics driver for the 280x192x6 mode on the Apple II
-;
-; Stefan Haubenthal <polluks@sdf.lonestar.org>
-; Based on Maciej Witkowiak's circle routine
-;
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-mode.inc"
- .include "tgi-error.inc"
- .include "apple2.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; ROM entry points
-
-TEXT := $F399 ; Return to text screen
-HGR := $F3E2 ; Initialize and clear hi-res page 1.
-HCLR := $F3F2 ; Clear the current hi-res screen to black.
-HPOSN := $F411 ; Positions the hi-res cursor without
- ; plotting a point.
- ; Enter with (A) = Y-coordinate, and
- ; (Y,X) = X-coordinate.
-HPLOT := $F457 ; Calls HPOSN and tries to plot a dot at
- ; the cursor's position. If you are
- ; trying to plot a non-white color at
- ; a complementary color position, no
- ; dot will be plotted.
-HLIN := $F53A ; Draws a line from the last plotted
- ; point or line destination to:
- ; (X,A) = X-coordinate, and
- ; (Y) = Y-coordinate.
-DRAW := $F601 ; Draws a shape. Enter with (Y,X) = the
- ; address of the shape table, and (A) =
- ; the rotation factor. Uses the current
- ; color.
-SETHCOL := $F6EC ; Set the hi-res color to (X), where (X)
- ; must be between 0 and 7.
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table and constants.
-
-.segment "JUMPTABLE"
-
-; First part of the header is a structure that has a magic and defines the
-; capabilities of the driver
-
- .byte $74, $67, $69 ; "tgi"
- .byte TGI_API_VERSION ; TGI API version number
-xres: .word 280 ; X resolution
-yres: .word 192 ; Y resolution
- .byte 8 ; Number of drawing colors
- .byte 2 ; Number of screens available
- .byte 8 ; System font X size
- .byte 8 ; System font Y size
- .res 4, $00 ; Reserved for future extensions
-
-; Next comes the jump table. Currently all entries must be valid and may point
-; to an RTS for test versions (function not implemented).
-
- .addr INSTALL
- .addr UNINSTALL
- .addr INIT
- .addr DONE
- .addr GETERROR
- .addr CONTROL
- .addr CLEAR
- .addr SETVIEWPAGE
- .addr SETDRAWPAGE
- .addr SETCOLOR
- .addr SETPALETTE
- .addr GETPALETTE
- .addr GETDEFPALETTE
- .addr SETPIXEL
- .addr GETPIXEL
- .addr LINE
- .addr BAR
- .addr CIRCLE
- .addr TEXTSTYLE
- .addr OUTTEXT
- .addr 0 ; IRQ entry is unused
-
-; ------------------------------------------------------------------------
-; Data.
-
-; Variables mapped to the zero page segment variables. Some of these are
-; used for passing parameters to the driver.
-
-X1 = ptr1
-Y1 = ptr2
-X2 = ptr3
-Y2 = ptr4
-RADIUS = tmp1
-
-ADDR = tmp1
-TEMP = tmp3
-TEMP2 = tmp4
-TEMP3 = sreg
-TEMP4 = sreg+1
-
-; Circle stuff
-XX = ptr3 ; (2) CIRCLE
-YY = ptr4 ; (2) CIRCLE
-MaxO = sreg ; (overwritten by TEMP3+TEMP4, but restored from OG/OU anyway)
-XS = regsave ; (2) CIRCLE
-YS = regsave+2 ; (2) CIRCLE
-
-; Absolute variables used in the code
-
-.bss
-
-ERROR: .res 1 ; Error code
-
-; Line routine stuff (combined with CIRCLE to save space)
-
-OGora: .res 2
-OUkos: .res 2
-Y3: .res 2
-
-; Text output stuff
-TEXTMAGX = $E7
-TEXTMAGY = $E7
-TEXTDIR = $F9
-
-; Constants and tables
-
-.rodata
-
-DEFPALETTE: .byte $00, $05, $04, $01, $00, $08, $06, $01; 6 unique colors
-
-SHAPE: .byte $64,$01,$D0,$00,$D5,$00,$DA,$00,$E0,$00,$EF,$00,$FE,$00,$0C,$01
- .byte $19,$01,$1D,$01,$25,$01,$2D,$01,$3D,$01,$46,$01,$4B,$01,$52,$01
- .byte $56,$01,$60,$01,$70,$01,$77,$01,$83,$01,$8E,$01,$9A,$01,$A7,$01
- .byte $B6,$01,$BF,$01,$CE,$01,$DD,$01,$E2,$01,$E7,$01,$F9,$01,$03,$02
- .byte $15,$02,$1F,$02,$32,$02,$42,$02,$52,$02,$5E,$02,$6C,$02,$79,$02
- .byte $85,$02,$91,$02,$A1,$02,$A9,$02,$B2,$02,$BF,$02,$C5,$02,$D5,$02
- .byte $E5,$02,$F4,$02,$00,$03,$10,$03,$1F,$03,$2D,$03,$35,$03,$44,$03
- .byte $53,$03,$63,$03,$71,$03,$7B,$03,$85,$03,$91,$03,$97,$03,$A3,$03
- .byte $B6,$03,$BF,$03,$C3,$03,$CF,$03,$DC,$03,$E4,$03,$F3,$03,$00,$04
- .byte $0A,$04,$19,$04,$25,$04,$2A,$04,$32,$04,$3C,$04,$43,$04,$50,$04
- .byte $5A,$04,$66,$04,$72,$04,$7E,$04,$87,$04,$94,$04,$9C,$04,$A8,$04
- .byte $B4,$04,$C1,$04,$CC,$04,$DB,$04,$E6,$04,$EE,$04,$F3,$04,$FB,$04
- .byte $04,$05,$1A,$05,$1F,$05,$24,$05,$29,$05,$22,$01,$00,$00,$00,$00
- .byte $09,$89,$92,$92,$00,$36,$36,$16,$0E,$00,$0D,$FE,$6E,$96,$52,$00
- .byte $69,$FE,$17,$2D,$2D,$1E,$1F,$17,$2D,$2D,$1E,$1F,$6E,$4E,$00,$09
- .byte $8D,$3F,$BF,$0D,$15,$3F,$0E,$0D,$1E,$3F,$77,$71,$09,$00,$6D,$11
- .byte $DF,$77,$09,$1E,$17,$4D,$3A,$DF,$4E,$29,$0E,$00,$A9,$1F,$6E,$1E
- .byte $17,$0D,$0D,$1E,$DF,$0E,$6D,$0E,$00,$36,$96,$52,$00,$09,$1E,$17
- .byte $36,$15,$0E,$0E,$00,$15,$0E,$36,$1E,$17,$4E,$01,$00,$09,$8D,$1F
- .byte $1F,$0E,$2D,$1E,$17,$2D,$15,$1F,$1F,$4E,$4E,$01,$00,$89,$6E,$3A
- .byte $3F,$77,$31,$56,$09,$00,$92,$8A,$F6,$0D,$00,$52,$89,$3F,$B7,$52
- .byte $49,$00,$92,$92,$0E,$00,$49,$11,$17,$1E,$17,$1E,$56,$49,$01,$00
- .byte $29,$AD,$DF,$33,$4D,$35,$1F,$1F,$2E,$4D,$FE,$1B,$0E,$2D,$4E,$00
- .byte $31,$77,$36,$BE,$2D,$0E,$00,$29,$AD,$DF,$73,$49,$1E,$BF,$1E,$2E
- .byte $2D,$75,$00,$2D,$2D,$BE,$3E,$4E,$FE,$1B,$0E,$2D,$4E,$00,$49,$3E
- .byte $17,$0D,$FE,$33,$2D,$2D,$1E,$76,$01,$00,$2D,$2D,$DE,$1B,$2E,$2D
- .byte $15,$36,$DF,$73,$2D,$4E,$00,$09,$2D,$DE,$BB,$4D,$3A,$3F,$6E,$09
- .byte $FE,$1B,$0E,$2D,$4E,$00,$2D,$2D,$BE,$1E,$17,$36,$4E,$09,$00,$29
- .byte $AD,$DF,$33,$4D,$F1,$3F,$17,$4D,$31,$DF,$73,$2D,$4E,$00,$29,$AD
- .byte $DF,$33,$4D,$31,$3F,$77,$09,$1E,$DF,$2A,$75,$09,$00,$12,$16,$96
- .byte $01,$00,$52,$B2,$F6,$0D,$00,$49,$3E,$17,$2D,$2D,$35,$3F,$3F,$3F
- .byte $0E,$2D,$2D,$F5,$1B,$77,$4E,$09,$00,$12,$2D,$2D,$DE,$9B,$2D,$2D
- .byte $96,$01,$00,$49,$15,$FF,$13,$2D,$2D,$AD,$3F,$3F,$3F,$2E,$2D,$2D
- .byte $1E,$37,$4E,$09,$00,$29,$AD,$DF,$73,$09,$1E,$B6,$4E,$01,$00,$09
- .byte $2D,$3E,$37,$2D,$3E,$FF,$2A,$2D,$2D,$F5,$3F,$3F,$0E,$2D,$1E,$4D
- .byte $01,$00,$09,$15,$1F,$17,$4D,$31,$DF,$33,$2D,$2D,$FE,$1B,$6E,$09
- .byte $0E,$00,$2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$4D,$31,$DF,$33,$2D,$75
- .byte $01,$00,$29,$AD,$DF,$33,$36,$4D,$11,$DF,$73,$2D,$4E,$00,$2D,$AD
- .byte $DF,$6E,$31,$DF,$6E,$31,$DF,$17,$2D,$75,$01,$00,$2D,$2D,$DE,$1B
- .byte $6E,$11,$3F,$37,$36,$2D,$2D,$0E,$00,$2D,$2D,$DE,$1B,$6E,$11,$3F
- .byte $37,$36,$4E,$49,$00,$29,$AD,$DF,$33,$36,$4D,$35,$DF,$73,$2D,$75
- .byte $00,$4D,$31,$DF,$33,$4D,$31,$3F,$3F,$6E,$09,$FE,$1B,$6E,$09,$0E
- .byte $00,$2D,$1E,$36,$36,$17,$2D,$0E,$00,$49,$31,$36,$36,$DF,$73,$2D
- .byte $4E,$00,$4D,$F1,$DF,$6E,$1E,$37,$0D,$15,$DF,$6E,$09,$0E,$00,$36
- .byte $36,$36,$2D,$75,$00,$4D,$31,$FF,$37,$0D,$0D,$FE,$1F,$6E,$09,$FE
- .byte $1B,$6E,$09,$0E,$00,$4D,$31,$DF,$33,$6D,$31,$1F,$1F,$6E,$29,$FE
- .byte $1B,$6E,$09,$0E,$00,$29,$AD,$DF,$33,$4D,$31,$DF,$33,$4D,$31,$DF
- .byte $73,$2D,$4E,$00,$2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$36,$4E,$49,$00
- .byte $29,$AD,$DF,$33,$4D,$31,$DF,$33,$0D,$0D,$1E,$DF,$0E,$6D,$0E,$00
- .byte $2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$0D,$15,$DF,$6E,$09,$0E,$00,$29
- .byte $AD,$DF,$33,$4D,$3A,$77,$09,$FE,$1B,$0E,$2D,$4E,$00,$2D,$2D,$DE
- .byte $36,$36,$76,$09,$00,$4D,$31,$DF,$33,$4D,$31,$DF,$33,$4D,$31,$DF
- .byte $73,$2D,$4E,$00,$4D,$31,$DF,$33,$4D,$31,$DF,$33,$4D,$F1,$1F,$0E
- .byte $4E,$01,$00,$4D,$31,$DF,$33,$4D,$31,$1F,$1F,$6E,$0D,$3E,$1F,$37
- .byte $4D,$71,$00,$4D,$31,$DF,$73,$0D,$1E,$17,$0D,$15,$DF,$33,$4D,$71
- .byte $00,$4D,$31,$DF,$73,$0D,$1E,$36,$76,$09,$00,$2D,$2D,$BE,$1E,$17
- .byte $1E,$2E,$2D,$75,$00,$2D,$2D,$DE,$3B,$2E,$3E,$2E,$3E,$2E,$2D,$75
- .byte $00,$72,$15,$0E,$15,$56,$00,$2D,$2D,$3E,$2E,$3E,$2E,$3E,$DF,$2A
- .byte $2D,$75,$00,$49,$15,$3F,$17,$2D,$2D,$15,$3F,$3F,$3F,$4E,$2D,$3E
- .byte $37,$2D,$3E,$6F,$49,$00,$92,$92,$49,$11,$3F,$3F,$4D,$09,$00,$76
- .byte $96,$52,$00,$52,$2D,$35,$DF,$33,$4D,$31,$FF,$73,$6D,$0E,$00,$36
- .byte $2D,$AD,$DF,$33,$4D,$31,$DF,$33,$2D,$75,$01,$00,$52,$2D,$DE,$33
- .byte $76,$2D,$0E,$00,$49,$31,$DF,$2A,$2D,$FE,$1B,$6E,$09,$FE,$1B,$0E
- .byte $2D,$75,$00,$52,$2D,$15,$DF,$33,$2D,$2D,$DE,$1B,$0E,$2D,$75,$00
- .byte $09,$F5,$33,$8D,$3F,$77,$36,$4E,$01,$00,$52,$2D,$35,$DF,$33,$4D
- .byte $31,$3F,$77,$09,$1E,$3F,$4D,$01,$00,$36,$2D,$AD,$DF,$33,$4D,$31
- .byte $DF,$33,$4D,$71,$00,$16,$36,$36,$0E,$00,$09,$9E,$35,$36,$F6,$6F
- .byte $01,$00,$36,$4D,$1E,$1F,$2E,$15,$1F,$6E,$71,$00,$35,$36,$36,$17
- .byte $2D,$0E,$00,$12,$2D,$AD,$1F,$1F,$6E,$0D,$FE,$1F,$6E,$0D,$0E,$00
- .byte $12,$2D,$15,$DF,$6E,$31,$DF,$6E,$71,$00,$52,$2D,$15,$DF,$33,$4D
- .byte $31,$DF,$73,$2D,$4E,$00,$12,$2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$6E
- .byte $49,$00,$52,$2D,$35,$DF,$33,$4D,$31,$3F,$77,$09,$2E,$00,$12,$0D
- .byte $AD,$DF,$37,$36,$4E,$49,$00,$52,$2D,$F5,$DB,$0E,$2D,$15,$DF,$13
- .byte $2D,$75,$01,$00,$31,$17,$2D,$F5,$33,$76,$75,$00,$12,$4D,$31,$DF
- .byte $33,$4D,$31,$FF,$73,$6D,$0E,$00,$12,$4D,$31,$DF,$33,$4D,$F1,$1F
- .byte $0E,$4E,$01,$00,$12,$4D,$31,$DF,$33,$0D,$0D,$FE,$1F,$0E,$0D,$4E
- .byte $00,$12,$4D,$F1,$1F,$0E,$15,$1F,$17,$4D,$71,$00,$12,$4D,$31,$DF
- .byte $33,$4D,$31,$3F,$77,$09,$1E,$3F,$4D,$01,$00,$12,$2D,$2D,$1E,$17
- .byte $1E,$17,$2D,$2D,$0E,$00,$09,$F5,$33,$1E,$0E,$76,$75,$00,$36,$36
- .byte $36,$2E,$00,$AD,$AE,$17,$FE,$2A,$4E,$01,$00,$69,$11,$1F,$1F,$4E
- .byte $B1,$92,$09,$00,$2D,$2D,$35,$3F,$3F,$37,$2D,$2D,$35,$3F,$3F,$37
- .byte $2D,$2D,$35,$3F,$3F,$37,$2D,$2D,$75,$00,$40,$C0,$40,$18,$00,$40
- .byte $C0,$40,$43,$00,$40,$C0,$40,$08,$00,$19,$00,$00
-
-.code
-
-; ------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. May
-; initialize anything that has to be done just once. Is probably empty
-; most of the time.
-;
-; Must set an error code: NO
-;
-
-INSTALL:
-
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory. May
-; clean up anything done by INSTALL but is probably empty most of the time.
-;
-; Must set an error code: NO
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; INIT: Changes an already installed device from text mode to graphics
-; mode.
-; Note that INIT/DONE may be called multiple times while the driver
-; is loaded, while INSTALL is only called once, so any code that is needed
-; to initializes variables and so on must go here. Setting palette and
-; clearing the screen is not needed because this is called by the graphics
-; kernel later.
-; The graphics kernel will never call INIT when a graphics mode is already
-; active, so there is no need to protect against that.
-;
-; Must set an error code: YES
-;
-
-INIT:
-
-; Switch into graphics mode
-
- jsr HGR
- bit MIXCLR
-
-; Done, reset the error code
-
- lda #TGI_ERR_OK
- sta ERROR
- rts
-
-; ------------------------------------------------------------------------
-; DONE: Will be called to switch the graphics device back into text mode.
-; The graphics kernel will never call DONE when no graphics mode is active,
-; so there is no need to protect against that.
-;
-; Must set an error code: NO
-;
-
-DONE = TEXT
-
-; ------------------------------------------------------------------------
-; GETERROR: Return the error code in A and clear it.
-
-GETERROR:
- ldx #TGI_ERR_OK
- lda ERROR
- stx ERROR
- rts
-
-; ------------------------------------------------------------------------
-; CONTROL: Platform/driver specific entry point.
-;
-; Must set an error code: YES
-;
-
-CONTROL:
- lda #TGI_ERR_INV_FUNC
- sta ERROR
- rts
-
-; ------------------------------------------------------------------------
-; CLEAR: Clears the screen.
-;
-; Must set an error code: NO
-;
-
-CLEAR = HCLR
-
-; ------------------------------------------------------------------------
-; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
-; The page number is already checked to be valid by the graphics kernel.
-;
-; Must set an error code: NO (will only be called if page ok)
-;
-
-SETVIEWPAGE:
- tax
- beq @L1
- bit HISCR
- rts
-@L1: bit LOWSCR
- rts
-
-; ------------------------------------------------------------------------
-; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
-; The page number is already checked to be valid by the graphics kernel.
-;
-; Must set an error code: NO (will only be called if page ok)
-;
-
-SETDRAWPAGE:
- tax
- beq @L1
- lda #>$4000 ; Page 2
- .byte $2C
-@L1: lda #>$2000 ; Page 1
- sta $E6
- rts
-
-; ------------------------------------------------------------------------
-; SETCOLOR: Set the drawing color (in A). The new color is already checked
-; to be in a valid range (0..maxcolor-1).
-;
-; Must set an error code: NO (will only be called if color ok)
-;
-
-SETCOLOR:
- tax
- jmp SETHCOL
-
-; ------------------------------------------------------------------------
-; SETPALETTE: Set the palette (not available with all drivers/hardware).
-; A pointer to the palette is passed in ptr1. Must set an error if palettes
-; are not supported
-;
-; Must set an error code: YES
-;
-
-SETPALETTE:
- lda #TGI_ERR_INV_FUNC
- sta ERROR
- rts
-
-; ------------------------------------------------------------------------
-; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
-; set the palette should return the default palette here, so there's no
-; way for this function to fail.
-;
-; Must set an error code: NO
-;
-
-GETPALETTE:
-
-; ------------------------------------------------------------------------
-; GETDEFPALETTE: Return the default palette for the driver in A/X. All
-; drivers should return something reasonable here, even drivers that don't
-; support palettes, otherwise the caller has no way to determine the colors
-; of the (not changeable) palette.
-;
-; Must set an error code: NO (all drivers must have a default palette)
-;
-
-GETDEFPALETTE:
- lda #<DEFPALETTE
- ldx #>DEFPALETTE
- rts
-
-; ------------------------------------------------------------------------
-; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
-; color. The coordinates passed to this function are never outside the
-; visible screen area, so there is no need for clipping inside this function.
-;
-; Must set an error code: NO
-;
-
-SETPIXELCLIP:
- lda Y1+1
- bmi @finito ; y<0
- lda X1+1
- bmi @finito ; x<0
- lda X1
- ldx X1+1
- sta ADDR
- stx ADDR+1
- ldx #ADDR
- lda xres
- ldy xres+1
- jsr icmp ; ( x < xres ) ...
- bcs @finito
- lda Y1
- ldx Y1+1
- sta ADDR
- stx ADDR+1
- ldx #ADDR
- lda yres
- ldy yres+1
- jsr icmp ; ... && ( y < yres )
- bcc SETPIXEL
-@finito:rts
-
-SETPIXEL:
- ldx X1
- ldy X1+1
- lda Y1
- jmp HPLOT
-
-; ------------------------------------------------------------------------
-; GETPIXEL: Read the color value of a pixel and return it in A/X. The
-; coordinates passed to this function are never outside the visible screen
-; area, so there is no need for clipping inside this function.
-
-
-GETPIXEL:
- ldx X1
- ldy X1+1
- lda Y1
- jsr HPOSN ; 1st pixel
-HBASL = $26
-HMASK = $30
- ldx #$00
- lda (HBASL),y
- and HMASK
- beq @L1
- inx
-@L1: stx tmp1
-
- lda $E0 ; which neighbour
- tax
- and #$01
- bne @odd
- asl tmp1
- inx
- .byte $24
-@odd: dex
-
- ldy $E1
- lda $E2
- jsr HPOSN ; 2nd pixel
- ldx #$00
- lda (HBASL),y
- and HMASK
- beq @L2
- inx
-@L2: txa
- ora tmp1
- ldx #$00
- rts
-
-; ------------------------------------------------------------------------
-; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
-; X2/Y2 = ptr3/ptr4 using the current drawing color.
-;
-; Must set an error code: NO
-;
-
-LINE:
- ldx X1
- ldy X1+1
- lda Y1
- jsr HPOSN
- lda X2
- ldx X2+1
- ldy Y2
- jmp HLIN
-
-; ------------------------------------------------------------------------
-; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
-; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
-; Contrary to most other functions, the graphics kernel will sort and clip
-; the coordinates before calling the driver, so on entry the following
-; conditions are valid:
-; X1 <= X2
-; Y1 <= Y2
-; (X1 >= 0) && (X1 < XRES)
-; (X2 >= 0) && (X2 < XRES)
-; (Y1 >= 0) && (Y1 < YRES)
-; (Y2 >= 0) && (Y2 < YRES)
-;
-; Must set an error code: NO
-;
-
-BAR:
- inc Y2
-@L1: lda Y2
- pha
- lda Y1
- sta Y2
- jsr LINE
- pla
- sta Y2
- inc Y1
- cmp Y1
- bne @L1
- rts
-
-; ------------------------------------------------------------------------
-; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
-; radius in tmp1 and the current drawing color.
-;
-; Must set an error code: NO
-;
-
-CIRCLE:
- lda RADIUS
- bne @L1
- jmp SETPIXELCLIP ; Plot as a point
-
-@L1: sta XX
- ; x = r;
- lda #$00
- sta XX+1
- sta YY
- sta YY+1
- sta MaxO
- sta MaxO+1
- ; y =0; mo=0;
- lda X1
- ldx X1+1
- sta XS
- stx XS+1
- lda Y1
- ldx Y1+1
- sta YS
- stx YS+1 ; XS/YS to remember the center
-
- ; while (y<x) {
-@L013B: ldx #YY
- lda XX
- ldy XX+1
- jsr icmp
- bcc @L12
- rts
-@L12: ; plot points in 8 slices...
- lda XS
- add XX
- sta X1
- lda XS+1
- adc XX+1
- sta X1+1 ; x1 = xs+x
- lda YS
- add YY
- sta Y1
- pha
- lda YS+1
- adc YY+1
- sta Y1+1 ; (stack)=ys+y, y1=(stack)
- pha
- jsr SETPIXELCLIP ; plot(xs+x,ys+y)
- lda YS
- sub YY
- sta Y1
- sta Y3
- lda YS+1
- sbc YY+1
- sta Y1+1 ; y3 = y1 = ys-y
- sta Y3+1
- jsr SETPIXELCLIP ; plot(xs+x,ys-y)
- pla
- sta Y1+1
- pla
- sta Y1 ; y1 = ys+y
- lda XS
- sub XX
- sta X1
- lda XS+1
- sbc XX+1
- sta X1+1
- jsr SETPIXELCLIP ; plot (xs-x,ys+y)
- lda Y3
- sta Y1
- lda Y3+1
- sta Y1+1
- jsr SETPIXELCLIP ; plot (xs-x,ys-y)
-
- lda XS
- add YY
- sta X1
- lda XS+1
- adc YY+1
- sta X1+1 ; x1 = xs+y
- lda YS
- add XX
- sta Y1
- pha
- lda YS+1
- adc XX+1
- sta Y1+1 ; (stack)=ys+x, y1=(stack)
- pha
- jsr SETPIXELCLIP ; plot(xs+y,ys+x)
- lda YS
- sub XX
- sta Y1
- sta Y3
- lda YS+1
- sbc XX+1
- sta Y1+1 ; y3 = y1 = ys-x
- sta Y3+1
- jsr SETPIXELCLIP ; plot(xs+y,ys-x)
- pla
- sta Y1+1
- pla
- sta Y1 ; y1 = ys+x(stack)
- lda XS
- sub YY
- sta X1
- lda XS+1
- sbc YY+1
- sta X1+1
- jsr SETPIXELCLIP ; plot (xs-y,ys+x)
- lda Y3
- sta Y1
- lda Y3+1
- sta Y1+1
- jsr SETPIXELCLIP ; plot (xs-y,ys-x)
-
- ; og = mo+y+y+1
- lda MaxO
- ldx MaxO+1
- add YY
- tay
- txa
- adc YY+1
- tax
- tya
- add YY
- tay
- txa
- adc YY+1
- tax
- tya
- add #$01
- bcc @L0143
- inx
-@L0143: sta OGora
- stx OGora+1
- ; ou = og-x-x+1
- sub XX
- tay
- txa
- sbc XX+1
- tax
- tya
- sub XX
- tay
- txa
- sbc XX+1
- tax
- tya
- add #$01
- bcc @L0146
- inx
-@L0146: sta OUkos
- stx OUkos+1
- ; ++y
- inc YY
- bne @L0148
- inc YY+1
-@L0148: ; if (abs(ou)<abs(og))
- lda OUkos
- ldy OUkos+1
- jsr abs
- sta TEMP3
- sty TEMP4
- lda OGora
- ldy OGora+1
- jsr abs
- ldx #TEMP3
- jsr icmp
- bpl @L0149
- ; { --x;
- lda XX
- sub #$01
- sta XX
- bcs @L014E
- dec XX+1
-@L014E: ; mo = ou; }
- lda OUkos
- ldx OUkos+1
- jmp @L014G
- ; else { mo = og }
-@L0149: lda OGora
- ldx OGora+1
-@L014G: sta MaxO
- stx MaxO+1
- ; }
- jmp @L013B
-
-; ------------------------------------------------------------------------
-; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
-; direction is passend in X/Y, the text direction is passed in A.
-;
-; Must set an error code: NO
-;
-
-TEXTSTYLE:
- stx TEXTMAGX
- sty TEXTMAGY
- asl ; 16 <=> 90þ
- asl
- asl
- asl
- sta TEXTDIR
- rts
-
-
-; ------------------------------------------------------------------------
-; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
-; current text style. The text to output is given as a zero terminated
-; string with address in ptr3.
-;
-; Must set an error code: NO
-;
-
-OUTTEXT:
- ldx X1
- ldy X1+1
- lda Y1
- jsr HPOSN
- lda SHAPE+2*99
- add #<SHAPE
- sta tmp3
- lda SHAPE+2*99+1
- adc #>SHAPE
- sta tmp3+1
-
- ldy #$00
-@L1: lda (ptr3),y
- beq @end
- sub #$1F ; no controls
- asl ; offset*2
- tax
- lda SHAPE,x
- add #<SHAPE
- sta tmp1
- lda SHAPE+1,x
- adc #>SHAPE
- sta tmp1+1
- tya
- pha
- ldx tmp1
- ldy tmp1+1
- lda TEXTDIR
- jsr DRAW
- ldx tmp3
- ldy tmp3+1
- lda TEXTDIR
- jsr DRAW
- pla
- tay
- iny
- bne @L1
-@end: rts
-
-;-------------
-; copies of some runtime routines
-
-abs:
- ; a/y := abs(a/y)
- cpy #$00
- bpl @L1
- ; negay
- clc
- eor #$FF
- adc #$01
- pha
- tya
- eor #$FF
- adc #$00
- tay
- pla
-@L1: rts
-
-icmp:
- ; compare a/y to zp,x
- sta TEMP ; TEMP/TEMP2 - arg2
- sty TEMP2
- lda $00,x
- pha
- lda $01,x
- tay
- pla
- tax
- tya ; x/a - arg1 (a=high)
-
- sub TEMP2
- bne @L4
- cpx TEMP
- beq @L3
- adc #$FF
- ora #$01
-@L3: rts
-@L4: bvc @L3
- eor #$FF
- ora #$01
- rts
--- /dev/null
+;
+; Graphics driver for the 280x192x8 mode on the Apple II
+;
+; Stefan Haubenthal <polluks@sdf.lonestar.org>
+; Oliver Schmidt <ol.sc@web.de>
+; Based on Maciej Witkowiak's circle routine
+;
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-mode.inc"
+ .include "tgi-error.inc"
+ .include "apple2.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+
+; Zero page stuff
+
+HBASL := $26
+HMASK := $30
+PAGE := $E6
+SCALE := $E7
+ROT := $F9
+
+; Graphics entry points, by cbmnut (applenut??) cbmnut@hushmail.com
+
+TEXT := $F399 ; Return to text screen
+HGR2 := $F3D8 ; Initialize and clear hi-res page 2.
+HGR := $F3E2 ; Initialize and clear hi-res page 1.
+HCLR := $F3F2 ; Clear the current hi-res screen to black.
+BKGND := $F3F6 ; Clear the current hi-res screen to the
+ ; last plotted color (from ($1C).
+HPOSN := $F411 ; Positions the hi-res cursor without
+ ; plotting a point.
+ ; Enter with (A) = Y-coordinate, and
+ ; (Y,X) = X-coordinate.
+HPLOT := $F457 ; Calls HPOSN and tries to plot a dot at
+ ; the cursor's position. If you are
+ ; trying to plot a non-white color at
+ ; a complementary color position, no
+ ; dot will be plotted.
+HLIN := $F53A ; Draws a line from the last plotted
+ ; point or line destination to:
+ ; (X,A) = X-coordinate, and
+ ; (Y) = Y-coordinate.
+HFIND := $F5CB ; Converts the hi-res coursor's position
+ ; back to X- and Y-coordinates; stores
+ ; X-coordinate at $E0,E1 and Y-coordinate
+ ; at $E2.
+DRAW := $F601 ; Draws a shape. Enter with (Y,X) = the
+ ; address of the shape table, and (A) =
+ ; the rotation factor. Uses the current
+ ; color.
+XDRAW := $F65D ; Draws a shape by inverting the existing
+ ; color of the dots the shape draws over.
+ ; Same entry parameters as DRAW.
+SETHCOL := $F6EC ; Set the hi-res color to (X), where (X)
+ ; must be between 0 and 7.
+
+; ------------------------------------------------------------------------
+
+; Variables mapped to the zero page segment variables. Some of these are
+; used for passing parameters to the driver.
+
+X1 := ptr1
+Y1 := ptr2
+X2 := ptr3
+Y2 := ptr4
+RADIUS := tmp1
+
+ADDR := tmp1 ; (2) SETPIXELCLIP
+TEMP := tmp3 ; icmp
+TEMP2 := tmp4 ; icmp
+XX := ptr3 ; (2) CIRCLE
+YY := ptr4 ; (2) CIRCLE
+TEMP3 := sreg ; CIRCLE
+TEMP4 := sreg+1 ; CIRCLE
+MaxO := sreg ; (overwritten by TEMP3+TEMP4, but restored from OG/OU anyway)
+XS := regsave ; (2) CIRCLE
+YS := regsave+2 ; (2) CIRCLE
+
+; ------------------------------------------------------------------------
+
+ .segment "JUMPTABLE"
+
+; Header. Includes jump table and constants.
+
+; First part of the header is a structure that has a magic and defines the
+; capabilities of the driver
+
+ .byte $74, $67, $69 ; "tgi"
+ .byte TGI_API_VERSION ; TGI API version number
+xres: .word 280 ; X resolution
+yres: .word 192 ; Y resolution
+ .byte 8 ; Number of drawing colors
+ .byte 2 ; Number of screens available
+ .byte 8 ; System font X size
+ .byte 8 ; System font Y size
+ .res 4, $00 ; Reserved for future extensions
+
+; Next comes the jump table. Currently all entries must be valid and may point
+; to an RTS for test versions (function not implemented).
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr INIT
+ .addr DONE
+ .addr GETERROR
+ .addr CONTROL
+ .addr CLEAR
+ .addr SETVIEWPAGE
+ .addr SETDRAWPAGE
+ .addr SETCOLOR
+ .addr SETPALETTE
+ .addr GETPALETTE
+ .addr GETDEFPALETTE
+ .addr SETPIXEL
+ .addr GETPIXEL
+ .addr LINE
+ .addr BAR
+ .addr CIRCLE
+ .addr TEXTSTYLE
+ .addr OUTTEXT
+ .addr 0 ; IRQ entry is unused
+
+; ------------------------------------------------------------------------
+
+ .bss
+
+; Absolute variables used in the code
+
+ERROR: .res 1 ; Error code
+
+ .ifdef __APPLE2ENH__
+Set80: .res 1 ; Set 80 column store
+ .endif
+
+; Circle stuff
+
+OGora: .res 2
+OUkos: .res 2
+Y3: .res 2
+
+; ------------------------------------------------------------------------
+
+ .rodata
+
+; Constants and tables
+
+DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
+
+SHAPE: .byte $64,$01,$D0,$00,$D5,$00,$DA,$00,$E0,$00,$EF,$00,$FE,$00,$0C,$01
+ .byte $19,$01,$1D,$01,$25,$01,$2D,$01,$3D,$01,$46,$01,$4B,$01,$52,$01
+ .byte $56,$01,$60,$01,$70,$01,$77,$01,$83,$01,$8E,$01,$9A,$01,$A7,$01
+ .byte $B6,$01,$BF,$01,$CE,$01,$DD,$01,$E2,$01,$E7,$01,$F9,$01,$03,$02
+ .byte $15,$02,$1F,$02,$32,$02,$42,$02,$52,$02,$5E,$02,$6C,$02,$79,$02
+ .byte $85,$02,$91,$02,$A1,$02,$A9,$02,$B2,$02,$BF,$02,$C5,$02,$D5,$02
+ .byte $E5,$02,$F4,$02,$00,$03,$10,$03,$1F,$03,$2D,$03,$35,$03,$44,$03
+ .byte $53,$03,$63,$03,$71,$03,$7B,$03,$85,$03,$91,$03,$97,$03,$A3,$03
+ .byte $B6,$03,$BF,$03,$C3,$03,$CF,$03,$DC,$03,$E4,$03,$F3,$03,$00,$04
+ .byte $0A,$04,$19,$04,$25,$04,$2A,$04,$32,$04,$3C,$04,$43,$04,$50,$04
+ .byte $5A,$04,$66,$04,$72,$04,$7E,$04,$87,$04,$94,$04,$9C,$04,$A8,$04
+ .byte $B4,$04,$C1,$04,$CC,$04,$DB,$04,$E6,$04,$EE,$04,$F3,$04,$FB,$04
+ .byte $04,$05,$1A,$05,$1F,$05,$24,$05,$29,$05,$22,$01,$00,$00,$00,$00
+ .byte $09,$89,$92,$92,$00,$36,$36,$16,$0E,$00,$0D,$FE,$6E,$96,$52,$00
+ .byte $69,$FE,$17,$2D,$2D,$1E,$1F,$17,$2D,$2D,$1E,$1F,$6E,$4E,$00,$09
+ .byte $8D,$3F,$BF,$0D,$15,$3F,$0E,$0D,$1E,$3F,$77,$71,$09,$00,$6D,$11
+ .byte $DF,$77,$09,$1E,$17,$4D,$3A,$DF,$4E,$29,$0E,$00,$A9,$1F,$6E,$1E
+ .byte $17,$0D,$0D,$1E,$DF,$0E,$6D,$0E,$00,$36,$96,$52,$00,$09,$1E,$17
+ .byte $36,$15,$0E,$0E,$00,$15,$0E,$36,$1E,$17,$4E,$01,$00,$09,$8D,$1F
+ .byte $1F,$0E,$2D,$1E,$17,$2D,$15,$1F,$1F,$4E,$4E,$01,$00,$89,$6E,$3A
+ .byte $3F,$77,$31,$56,$09,$00,$92,$8A,$F6,$0D,$00,$52,$89,$3F,$B7,$52
+ .byte $49,$00,$92,$92,$0E,$00,$49,$11,$17,$1E,$17,$1E,$56,$49,$01,$00
+ .byte $29,$AD,$DF,$33,$4D,$35,$1F,$1F,$2E,$4D,$FE,$1B,$0E,$2D,$4E,$00
+ .byte $31,$77,$36,$BE,$2D,$0E,$00,$29,$AD,$DF,$73,$49,$1E,$BF,$1E,$2E
+ .byte $2D,$75,$00,$2D,$2D,$BE,$3E,$4E,$FE,$1B,$0E,$2D,$4E,$00,$49,$3E
+ .byte $17,$0D,$FE,$33,$2D,$2D,$1E,$76,$01,$00,$2D,$2D,$DE,$1B,$2E,$2D
+ .byte $15,$36,$DF,$73,$2D,$4E,$00,$09,$2D,$DE,$BB,$4D,$3A,$3F,$6E,$09
+ .byte $FE,$1B,$0E,$2D,$4E,$00,$2D,$2D,$BE,$1E,$17,$36,$4E,$09,$00,$29
+ .byte $AD,$DF,$33,$4D,$F1,$3F,$17,$4D,$31,$DF,$73,$2D,$4E,$00,$29,$AD
+ .byte $DF,$33,$4D,$31,$3F,$77,$09,$1E,$DF,$2A,$75,$09,$00,$12,$16,$96
+ .byte $01,$00,$52,$B2,$F6,$0D,$00,$49,$3E,$17,$2D,$2D,$35,$3F,$3F,$3F
+ .byte $0E,$2D,$2D,$F5,$1B,$77,$4E,$09,$00,$12,$2D,$2D,$DE,$9B,$2D,$2D
+ .byte $96,$01,$00,$49,$15,$FF,$13,$2D,$2D,$AD,$3F,$3F,$3F,$2E,$2D,$2D
+ .byte $1E,$37,$4E,$09,$00,$29,$AD,$DF,$73,$09,$1E,$B6,$4E,$01,$00,$09
+ .byte $2D,$3E,$37,$2D,$3E,$FF,$2A,$2D,$2D,$F5,$3F,$3F,$0E,$2D,$1E,$4D
+ .byte $01,$00,$09,$15,$1F,$17,$4D,$31,$DF,$33,$2D,$2D,$FE,$1B,$6E,$09
+ .byte $0E,$00,$2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$4D,$31,$DF,$33,$2D,$75
+ .byte $01,$00,$29,$AD,$DF,$33,$36,$4D,$11,$DF,$73,$2D,$4E,$00,$2D,$AD
+ .byte $DF,$6E,$31,$DF,$6E,$31,$DF,$17,$2D,$75,$01,$00,$2D,$2D,$DE,$1B
+ .byte $6E,$11,$3F,$37,$36,$2D,$2D,$0E,$00,$2D,$2D,$DE,$1B,$6E,$11,$3F
+ .byte $37,$36,$4E,$49,$00,$29,$AD,$DF,$33,$36,$4D,$35,$DF,$73,$2D,$75
+ .byte $00,$4D,$31,$DF,$33,$4D,$31,$3F,$3F,$6E,$09,$FE,$1B,$6E,$09,$0E
+ .byte $00,$2D,$1E,$36,$36,$17,$2D,$0E,$00,$49,$31,$36,$36,$DF,$73,$2D
+ .byte $4E,$00,$4D,$F1,$DF,$6E,$1E,$37,$0D,$15,$DF,$6E,$09,$0E,$00,$36
+ .byte $36,$36,$2D,$75,$00,$4D,$31,$FF,$37,$0D,$0D,$FE,$1F,$6E,$09,$FE
+ .byte $1B,$6E,$09,$0E,$00,$4D,$31,$DF,$33,$6D,$31,$1F,$1F,$6E,$29,$FE
+ .byte $1B,$6E,$09,$0E,$00,$29,$AD,$DF,$33,$4D,$31,$DF,$33,$4D,$31,$DF
+ .byte $73,$2D,$4E,$00,$2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$36,$4E,$49,$00
+ .byte $29,$AD,$DF,$33,$4D,$31,$DF,$33,$0D,$0D,$1E,$DF,$0E,$6D,$0E,$00
+ .byte $2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$0D,$15,$DF,$6E,$09,$0E,$00,$29
+ .byte $AD,$DF,$33,$4D,$3A,$77,$09,$FE,$1B,$0E,$2D,$4E,$00,$2D,$2D,$DE
+ .byte $36,$36,$76,$09,$00,$4D,$31,$DF,$33,$4D,$31,$DF,$33,$4D,$31,$DF
+ .byte $73,$2D,$4E,$00,$4D,$31,$DF,$33,$4D,$31,$DF,$33,$4D,$F1,$1F,$0E
+ .byte $4E,$01,$00,$4D,$31,$DF,$33,$4D,$31,$1F,$1F,$6E,$0D,$3E,$1F,$37
+ .byte $4D,$71,$00,$4D,$31,$DF,$73,$0D,$1E,$17,$0D,$15,$DF,$33,$4D,$71
+ .byte $00,$4D,$31,$DF,$73,$0D,$1E,$36,$76,$09,$00,$2D,$2D,$BE,$1E,$17
+ .byte $1E,$2E,$2D,$75,$00,$2D,$2D,$DE,$3B,$2E,$3E,$2E,$3E,$2E,$2D,$75
+ .byte $00,$72,$15,$0E,$15,$56,$00,$2D,$2D,$3E,$2E,$3E,$2E,$3E,$DF,$2A
+ .byte $2D,$75,$00,$49,$15,$3F,$17,$2D,$2D,$15,$3F,$3F,$3F,$4E,$2D,$3E
+ .byte $37,$2D,$3E,$6F,$49,$00,$92,$92,$49,$11,$3F,$3F,$4D,$09,$00,$76
+ .byte $96,$52,$00,$52,$2D,$35,$DF,$33,$4D,$31,$FF,$73,$6D,$0E,$00,$36
+ .byte $2D,$AD,$DF,$33,$4D,$31,$DF,$33,$2D,$75,$01,$00,$52,$2D,$DE,$33
+ .byte $76,$2D,$0E,$00,$49,$31,$DF,$2A,$2D,$FE,$1B,$6E,$09,$FE,$1B,$0E
+ .byte $2D,$75,$00,$52,$2D,$15,$DF,$33,$2D,$2D,$DE,$1B,$0E,$2D,$75,$00
+ .byte $09,$F5,$33,$8D,$3F,$77,$36,$4E,$01,$00,$52,$2D,$35,$DF,$33,$4D
+ .byte $31,$3F,$77,$09,$1E,$3F,$4D,$01,$00,$36,$2D,$AD,$DF,$33,$4D,$31
+ .byte $DF,$33,$4D,$71,$00,$16,$36,$36,$0E,$00,$09,$9E,$35,$36,$F6,$6F
+ .byte $01,$00,$36,$4D,$1E,$1F,$2E,$15,$1F,$6E,$71,$00,$35,$36,$36,$17
+ .byte $2D,$0E,$00,$12,$2D,$AD,$1F,$1F,$6E,$0D,$FE,$1F,$6E,$0D,$0E,$00
+ .byte $12,$2D,$15,$DF,$6E,$31,$DF,$6E,$71,$00,$52,$2D,$15,$DF,$33,$4D
+ .byte $31,$DF,$73,$2D,$4E,$00,$12,$2D,$AD,$DF,$33,$4D,$F1,$3F,$37,$6E
+ .byte $49,$00,$52,$2D,$35,$DF,$33,$4D,$31,$3F,$77,$09,$2E,$00,$12,$0D
+ .byte $AD,$DF,$37,$36,$4E,$49,$00,$52,$2D,$F5,$DB,$0E,$2D,$15,$DF,$13
+ .byte $2D,$75,$01,$00,$31,$17,$2D,$F5,$33,$76,$75,$00,$12,$4D,$31,$DF
+ .byte $33,$4D,$31,$FF,$73,$6D,$0E,$00,$12,$4D,$31,$DF,$33,$4D,$F1,$1F
+ .byte $0E,$4E,$01,$00,$12,$4D,$31,$DF,$33,$0D,$0D,$FE,$1F,$0E,$0D,$4E
+ .byte $00,$12,$4D,$F1,$1F,$0E,$15,$1F,$17,$4D,$71,$00,$12,$4D,$31,$DF
+ .byte $33,$4D,$31,$3F,$77,$09,$1E,$3F,$4D,$01,$00,$12,$2D,$2D,$1E,$17
+ .byte $1E,$17,$2D,$2D,$0E,$00,$09,$F5,$33,$1E,$0E,$76,$75,$00,$36,$36
+ .byte $36,$2E,$00,$AD,$AE,$17,$FE,$2A,$4E,$01,$00,$69,$11,$1F,$1F,$4E
+ .byte $B1,$92,$09,$00,$2D,$2D,$35,$3F,$3F,$37,$2D,$2D,$35,$3F,$3F,$37
+ .byte $2D,$2D,$35,$3F,$3F,$37,$2D,$2D,$75,$00,$40,$C0,$40,$18,$00,$40
+ .byte $C0,$40,$43,$00,$40,$C0,$40,$08,$00,$19,$00,$00
+
+; ------------------------------------------------------------------------
+
+ .code
+
+; INIT: Changes an already installed device from text mode to graphics mode.
+; Note that INIT/DONE may be called multiple times while the driver
+; is loaded, while INSTALL is only called once, so any code that is needed
+; to initializes variables and so on must go here. Setting palette and
+; clearing the screen is not needed because this is called by the graphics
+; kernel later.
+; The graphics kernel will never call INIT when a graphics mode is already
+; active, so there is no need to protect against that.
+; Must set an error code: YES
+INIT:
+ .ifdef __APPLE2ENH__
+ ; Save and clear 80 column store
+ lda RD80COL
+ sta Set80
+ sta CLR80COL
+ .endif
+
+ ; Switch into graphics mode
+ bit HIRES
+ bit MIXCLR
+ bit TXTCLR
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta ERROR
+
+ ; Fall through
+
+; INSTALL routine. Is called after the driver is loaded into memory. May
+; initialize anything that has to be done just once. Is probably empty
+; most of the time.
+; Must set an error code: NO
+INSTALL:
+ ; Fall through
+
+; UNINSTALL routine. Is called before the driver is removed from memory. May
+; clean up anything done by INSTALL but is probably empty most of the time.
+; Must set an error code: NO
+UNINSTALL:
+ rts
+
+; DONE: Will be called to switch the graphics device back into text mode.
+; The graphics kernel will never call DONE when no graphics mode is active,
+; so there is no need to protect against that.
+; Must set an error code: NO
+DONE:
+ ; Switch into text mode
+ bit TXTSET
+ bit LOWSCR
+
+ .ifdef __APPLE2ENH__
+ ; Restore 80 column store
+ lda Set80
+ bpl :+
+ sta SET80COL
+: bit LORES ; Limit SET80COL-HISCR to text
+ .endif
+ rts
+
+; GETERROR: Return the error code in A and clear it.
+GETERROR:
+ lda ERROR
+ ldx #TGI_ERR_OK
+ stx ERROR
+ rts
+
+; CLEAR: Clears the screen.
+; Must set an error code: NO
+CLEAR:
+ bit $C082 ; Switch in ROM
+ jsr HCLR
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
+; The page number is already checked to be valid by the graphics kernel.
+; Must set an error code: NO (will only be called if page ok)
+SETVIEWPAGE:
+ tax
+ .assert LOWSCR + 1 = HISCR, error
+ lda LOWSCR,x ; No BIT absolute,X available
+ rts
+
+; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
+; The page number is already checked to be valid by the graphics kernel.
+; Must set an error code: NO (will only be called if page ok)
+SETDRAWPAGE:
+ tax
+ beq :+
+ lda #>$4000 ; Page 2
+ .byte $2C ; BIT absolute
+: lda #>$2000 ; Page 1
+ sta PAGE
+ rts
+
+; SETCOLOR: Set the drawing color (in A). The new color is already checked
+; to be in a valid range (0..maxcolor-1).
+; Must set an error code: NO (will only be called if color ok)
+SETCOLOR:
+ bit $C082 ; Switch in ROM
+ tax
+ jsr SETHCOL
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; CONTROL: Platform/driver specific entry point.
+; Must set an error code: YES
+CONTROL:
+ ; Fall through
+
+; SETPALETTE: Set the palette (not available with all drivers/hardware).
+; A pointer to the palette is passed in ptr1. Must set an error if palettes
+; are not supported
+; Must set an error code: YES
+SETPALETTE:
+ lda #TGI_ERR_INV_FUNC
+ sta ERROR
+ rts
+
+; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
+; set the palette should return the default palette here, so there's no
+; way for this function to fail.
+; Must set an error code: NO
+GETPALETTE:
+ ; Fall through
+
+; GETDEFPALETTE: Return the default palette for the driver in A/X. All
+; drivers should return something reasonable here, even drivers that don't
+; support palettes, otherwise the caller has no way to determine the colors
+; of the (not changeable) palette.
+; Must set an error code: NO (all drivers must have a default palette)
+GETDEFPALETTE:
+ lda #<DEFPALETTE
+ ldx #>DEFPALETTE
+ rts
+
+; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
+; color. The coordinates passed to this function are never outside the
+; visible screen area, so there is no need for clipping inside this function.
+; Must set an error code: NO
+SETPIXEL:
+ bit $C082 ; Switch in ROM
+ ldx X1
+ ldy X1+1
+ lda Y1
+ jsr HPLOT
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+SETPIXELCLIP:
+ lda Y1+1
+ bmi :+ ; y < 0
+ lda X1+1
+ bmi :+ ; x < 0
+ lda X1
+ ldx X1+1
+ sta ADDR
+ stx ADDR+1
+ ldx #ADDR
+ lda xres
+ ldy xres+1
+ jsr icmp ; ( x < xres ) ...
+ bcs :+
+ lda Y1
+ ldx Y1+1
+ sta ADDR
+ stx ADDR+1
+ ldx #ADDR
+ lda yres
+ ldy yres+1
+ jsr icmp ; ... && ( y < yres )
+ bcc SETPIXEL
+: rts
+
+; GETPIXEL: Read the color value of a pixel and return it in A/X. The
+; coordinates passed to this function are never outside the visible screen
+; area, so there is no need for clipping inside this function.
+GETPIXEL:
+ bit $C082 ; Switch in ROM
+ ldx X1
+ ldy X1+1
+ lda Y1
+ jsr HPOSN
+ lda (HBASL),y
+ and HMASK
+ asl
+ beq :+ ; 0 (black)
+ lda #$03 ; 3 (white)
+: bcc :+
+ adc #$03 ; += 4 (black -> black2, white -> white2)
+: ldx #$00
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
+; X2/Y2 = ptr3/ptr4 using the current drawing color.
+; Must set an error code: NO
+LINE:
+ bit $C082 ; Switch in ROM
+ ldx X1
+ ldy X1+1
+ lda Y1
+ jsr HPOSN
+ lda X2
+ ldx X2+1
+ ldy Y2
+ jsr HLIN
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
+; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
+; Contrary to most other functions, the graphics kernel will sort and clip
+; the coordinates before calling the driver, so on entry the following
+; conditions are valid:
+; X1 <= X2
+; Y1 <= Y2
+; (X1 >= 0) && (X1 < XRES)
+; (X2 >= 0) && (X2 < XRES)
+; (Y1 >= 0) && (Y1 < YRES)
+; (Y2 >= 0) && (Y2 < YRES)
+; Must set an error code: NO
+BAR:
+ inc Y2
+: lda Y2
+ pha
+ lda Y1
+ sta Y2
+ jsr LINE
+ pla
+ sta Y2
+ inc Y1
+ cmp Y1
+ bne :-
+ rts
+
+; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
+; radius in tmp1 and the current drawing color.
+; Must set an error code: NO
+CIRCLE:
+ lda RADIUS
+ bne :+
+ jmp SETPIXELCLIP ; Plot as a point
+: sta XX
+
+ ; x = r
+ lda #$00
+ sta XX+1
+ sta YY
+ sta YY+1
+ sta MaxO
+ sta MaxO+1
+
+ ; y = 0, mo = 0
+ lda X1
+ ldx X1+1
+ sta XS
+ stx XS+1
+ lda Y1
+ ldx Y1+1
+ sta YS
+ stx YS+1 ; XS/YS to remember the center
+
+ ; while (y < x) {
+while: ldx #YY
+ lda XX
+ ldy XX+1
+ jsr icmp
+ bcc :+
+ rts
+
+ ; Plot points in 8 slices...
+: lda XS
+ add XX
+ sta X1
+ lda XS+1
+ adc XX+1
+ sta X1+1 ; x1 = xs + x
+ lda YS
+ add YY
+ sta Y1
+ pha
+ lda YS+1
+ adc YY+1
+ sta Y1+1 ; (stack) = ys + y, y1 = (stack)
+ pha
+ jsr SETPIXELCLIP ; plot (xs + x, ys + y)
+ lda YS
+ sub YY
+ sta Y1
+ sta Y3
+ lda YS+1
+ sbc YY+1
+ sta Y1+1 ; y3 = y1 = ys - y
+ sta Y3+1
+ jsr SETPIXELCLIP ; plot (xs + x, ys - y)
+ pla
+ sta Y1+1
+ pla
+ sta Y1 ; y1 = ys + y
+ lda XS
+ sub XX
+ sta X1
+ lda XS+1
+ sbc XX+1
+ sta X1+1
+ jsr SETPIXELCLIP ; plot (xs - x, ys + y)
+ lda Y3
+ sta Y1
+ lda Y3+1
+ sta Y1+1
+ jsr SETPIXELCLIP ; plot (xs - x, ys - y)
+
+ lda XS
+ add YY
+ sta X1
+ lda XS+1
+ adc YY+1
+ sta X1+1 ; x1 = xs + y
+ lda YS
+ add XX
+ sta Y1
+ pha
+ lda YS+1
+ adc XX+1
+ sta Y1+1 ; (stack) = ys + x, y1 = (stack)
+ pha
+ jsr SETPIXELCLIP ; plot (xs + y, ys + x)
+ lda YS
+ sub XX
+ sta Y1
+ sta Y3
+ lda YS+1
+ sbc XX+1
+ sta Y1+1 ; y3 = y1 = ys - x
+ sta Y3+1
+ jsr SETPIXELCLIP ; plot (xs + y, ys - x)
+ pla
+ sta Y1+1
+ pla
+ sta Y1 ; y1 = ys + x(stack)
+ lda XS
+ sub YY
+ sta X1
+ lda XS+1
+ sbc YY+1
+ sta X1+1
+ jsr SETPIXELCLIP ; plot (xs - y, ys + x)
+ lda Y3
+ sta Y1
+ lda Y3+1
+ sta Y1+1
+ jsr SETPIXELCLIP ; plot (xs - y, ys - x)
+
+ ; og = mo + y + y + 1
+ lda MaxO
+ ldx MaxO+1
+ add YY
+ tay
+ txa
+ adc YY+1
+ tax
+ tya
+ add YY
+ tay
+ txa
+ adc YY+1
+ tax
+ tya
+ add #$01
+ bcc :+
+ inx
+: sta OGora
+ stx OGora+1
+
+ ; ou = og - x - x + 1
+ sub XX
+ tay
+ txa
+ sbc XX+1
+ tax
+ tya
+ sub XX
+ tay
+ txa
+ sbc XX+1
+ tax
+ tya
+ add #$01
+ bcc :+
+ inx
+: sta OUkos
+ stx OUkos+1
+
+ ; ++y
+ inc YY
+ bne :+
+ inc YY+1
+
+ ; if (abs (ou) < abs (og)) {
+: lda OUkos
+ ldy OUkos+1
+ jsr abs
+ sta TEMP3
+ sty TEMP4
+ lda OGora
+ ldy OGora+1
+ jsr abs
+ ldx #TEMP3
+ jsr icmp
+ bpl :++
+
+ ; --x
+ lda XX
+ sub #$01
+ sta XX
+ bcs :+
+ dec XX+1
+
+ ; mo = ou }
+: lda OUkos
+ ldx OUkos+1
+ jmp :++
+
+ ; else mo = og
+: lda OGora
+ ldx OGora+1
+: sta MaxO
+ stx MaxO+1
+
+ ; }
+ jmp while
+
+; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
+; direction is passend in X/Y, the text direction is passed in A.
+; Must set an error code: NO
+TEXTSTYLE:
+ stx SCALE
+ asl ; 16 <=> 90þ
+ asl
+ asl
+ asl
+ sta ROT
+ rts
+
+; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
+; current text style. The text to output is given as a zero terminated
+; string with address in ptr3.
+; Must set an error code: NO
+OUTTEXT:
+ bit $C082 ; Switch in ROM
+ ldx X1
+ ldy X1+1
+ lda Y1
+ jsr HPOSN
+ lda SHAPE+2*99
+ add #<SHAPE
+ sta tmp3
+ lda SHAPE+2*99+1
+ adc #>SHAPE
+ sta tmp3+1
+
+ ldy #$00
+: lda (ptr3),y
+ beq :+
+ sub #$1F ; No controls
+ asl ; Offset * 2
+ tax
+ lda SHAPE,x
+ add #<SHAPE
+ sta tmp1
+ lda SHAPE+1,x
+ adc #>SHAPE
+ sta tmp1+1
+ tya
+ pha
+ ldx tmp1
+ ldy tmp1+1
+ lda ROT
+ jsr DRAW
+ ldx tmp3
+ ldy tmp3+1
+ lda ROT
+ jsr DRAW
+ pla
+ tay
+ iny
+ bne :-
+: bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; Copies of some runtime routines
+
+abs:
+ ; A/Y := abs (A/Y)
+ cpy #$00
+ bpl :+
+ clc
+ eor #$FF
+ adc #$01
+ pha
+ tya
+ eor #$FF
+ adc #$00
+ tay
+ pla
+: rts
+
+icmp:
+ ; Compare A/Y to zp,X
+ sta TEMP ; TEMP/TEMP2 - arg2
+ sty TEMP2
+ lda $00,x
+ pha
+ lda $01,x
+ tay
+ pla
+ tax
+ tya ; X/A - arg1 (a = high)
+
+ sub TEMP2
+ bne :++
+ cpx TEMP
+ beq :+
+ adc #$FF
+ ora #$01
+: rts
+: bvc :+
+ eor #$FF
+ ora #$01
+: rts
+++ /dev/null
-;
-; Graphics driver for the 40x40x16 mode on the Apple II
-;
-; Stefan Haubenthal <polluks@sdf.lonestar.org>
-; Based on Maciej Witkowiak's line and circle routine
-;
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-mode.inc"
- .include "tgi-error.inc"
- .include "apple2.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Constants
-
-H2 = $2C
-PLOT = $F800
-HLINE = $F819
-CLRTOP = $F836
-SETCOL = $F864
-SCRN = $F871
-SETGR = $FB40
-VTABZ = $FC24
-
-; ------------------------------------------------------------------------
-; ROM entry points
-
-COUT := $FDED ; Vector to user output routine
-TEXT := $F399 ; Return to text screen
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table and constants.
-
-.segment "JUMPTABLE"
-
-; First part of the header is a structure that has a magic and defines the
-; capabilities of the driver
-
- .byte $74, $67, $69 ; "tgi"
- .byte TGI_API_VERSION ; TGI API version number
-xres: .word 40 ; X resolution
-yres: .word 40 ; Y resolution
- .byte 16 ; Number of drawing colors
- .byte 1 ; Number of screens available
- .byte 8 ; System font X size
- .byte 8 ; System font Y size
- .res 4, $00 ; Reserved for future extensions
-
-; Next comes the jump table. Currently all entries must be valid and may point
-; to an RTS for test versions (function not implemented).
-
- .addr INSTALL
- .addr UNINSTALL
- .addr INIT
- .addr DONE
- .addr GETERROR
- .addr CONTROL
- .addr CLEAR
- .addr SETVIEWPAGE
- .addr SETDRAWPAGE
- .addr SETCOLOR
- .addr SETPALETTE
- .addr GETPALETTE
- .addr GETDEFPALETTE
- .addr SETPIXEL
- .addr GETPIXEL
- .addr LINE
- .addr BAR
- .addr CIRCLE
- .addr TEXTSTYLE
- .addr OUTTEXT
- .addr 0 ; IRQ entry is unused
-
-; ------------------------------------------------------------------------
-; Data.
-
-; Variables mapped to the zero page segment variables. Some of these are
-; used for passing parameters to the driver.
-
-X1 = ptr1
-Y1 = ptr2
-X2 = ptr3
-Y2 = ptr4
-RADIUS = tmp1
-
-ADDR = tmp1
-TEMP = tmp3
-TEMP2 = tmp4
-TEMP3 = sreg
-TEMP4 = sreg+1
-
-; Line routine stuff (must be on zpage)
-PB = ptr3 ; (2) LINE
-UB = ptr4 ; (2) LINE
-ERR = regsave ; (2) LINE
-NX = regsave+2 ; (2) LINE
-; Circle stuff
-XX = ptr3 ; (2) CIRCLE
-YY = ptr4 ; (2) CIRCLE
-MaxO = sreg ; (overwritten by TEMP3+TEMP4, but restored from OG/OU anyway)
-XS = regsave ; (2) CIRCLE
-YS = regsave+2 ; (2) CIRCLE
-
-; Absolute variables used in the code
-
-.bss
-
-ERROR: .res 1 ; Error code
-
-; Line routine stuff (combined with CIRCLE to save space)
-
-OGora:
-COUNT: .res 2
-OUkos:
-NY: .res 2
-Y3:
-DX: .res 1
-DY: .res 1
-AY: .res 1
-
-; Constants and tables
-
-.rodata
-
-DEFPALETTE: .byte $00, $0F, $01, $0E, $03, $04, $02, $0D
- .byte $09, $08, $0B, $05, $0A, $0C, $06, $07
-
-.code
-
-; ------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. May
-; initialize anything that has to be done just once. Is probably empty
-; most of the time.
-;
-; Must set an error code: NO
-;
-
-INSTALL:
-
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory. May
-; clean up anything done by INSTALL but is probably empty most of the time.
-;
-; Must set an error code: NO
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; INIT: Changes an already installed device from text mode to graphics
-; mode.
-; Note that INIT/DONE may be called multiple times while the driver
-; is loaded, while INSTALL is only called once, so any code that is needed
-; to initializes variables and so on must go here. Setting palette and
-; clearing the screen is not needed because this is called by the graphics
-; kernel later.
-; The graphics kernel will never call INIT when a graphics mode is already
-; active, so there is no need to protect against that.
-;
-; Must set an error code: YES
-;
-
-INIT:
-
-; Switch into graphics mode
-
- jsr SETGR
-
-; Done, reset the error code
-
- lda #TGI_ERR_OK
- sta ERROR
- rts
-
-; ------------------------------------------------------------------------
-; DONE: Will be called to switch the graphics device back into text mode.
-; The graphics kernel will never call DONE when no graphics mode is active,
-; so there is no need to protect against that.
-;
-; Must set an error code: NO
-;
-
-DONE = TEXT
-
-; ------------------------------------------------------------------------
-; GETERROR: Return the error code in A and clear it.
-
-GETERROR:
- ldx #TGI_ERR_OK
- lda ERROR
- stx ERROR
- rts
-
-; ------------------------------------------------------------------------
-; CONTROL: Platform/driver specific entry point.
-;
-; Must set an error code: YES
-;
-
-CONTROL:
- lda #TGI_ERR_INV_FUNC
- sta ERROR
- rts
-
-; ------------------------------------------------------------------------
-; CLEAR: Clears the screen.
-;
-; Must set an error code: NO
-;
-
-CLEAR = CLRTOP
-
-; ------------------------------------------------------------------------
-; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
-; The page number is already checked to be valid by the graphics kernel.
-;
-; Must set an error code: NO (will only be called if page ok)
-;
-
-SETVIEWPAGE:
-
-; ------------------------------------------------------------------------
-; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
-; The page number is already checked to be valid by the graphics kernel.
-;
-; Must set an error code: NO (will only be called if page ok)
-;
-
-SETDRAWPAGE:
- rts
-
-; ------------------------------------------------------------------------
-; SETCOLOR: Set the drawing color (in A). The new color is already checked
-; to be in a valid range (0..maxcolor-1).
-;
-; Must set an error code: NO (will only be called if color ok)
-;
-
-SETCOLOR = SETCOL
-
-; ------------------------------------------------------------------------
-; SETPALETTE: Set the palette (not available with all drivers/hardware).
-; A pointer to the palette is passed in ptr1. Must set an error if palettes
-; are not supported
-;
-; Must set an error code: YES
-;
-
-SETPALETTE:
- lda #TGI_ERR_INV_FUNC
- sta ERROR
- rts
-
-; ------------------------------------------------------------------------
-; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
-; set the palette should return the default palette here, so there's no
-; way for this function to fail.
-;
-; Must set an error code: NO
-;
-
-GETPALETTE:
-
-; ------------------------------------------------------------------------
-; GETDEFPALETTE: Return the default palette for the driver in A/X. All
-; drivers should return something reasonable here, even drivers that don't
-; support palettes, otherwise the caller has no way to determine the colors
-; of the (not changeable) palette.
-;
-; Must set an error code: NO (all drivers must have a default palette)
-;
-
-GETDEFPALETTE:
- lda #<DEFPALETTE
- ldx #>DEFPALETTE
- rts
-
-; ------------------------------------------------------------------------
-; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
-; color. The coordinates passed to this function are never outside the
-; visible screen area, so there is no need for clipping inside this function.
-;
-; Must set an error code: NO
-;
-
-SETPIXELCLIP:
- lda Y1+1
- bmi @finito ; y<0
- lda X1+1
- bmi @finito ; x<0
- lda X1
- ldx X1+1
- sta ADDR
- stx ADDR+1
- ldx #ADDR
- lda xres
- ldy xres+1
- jsr icmp ; ( x < xres ) ...
- bcs @finito
- lda Y1
- ldx Y1+1
- sta ADDR
- stx ADDR+1
- ldx #ADDR
- lda yres
- ldy yres+1
- jsr icmp ; ... && ( y < yres )
- bcc SETPIXEL
-@finito:rts
-
-SETPIXEL:
- lda X1
- ldy Y1
- jmp PLOT
-
-; ------------------------------------------------------------------------
-; GETPIXEL: Read the color value of a pixel and return it in A/X. The
-; coordinates passed to this function are never outside the visible screen
-; area, so there is no need for clipping inside this function.
-
-
-GETPIXEL:
- lda X1
- ldy Y1
- jsr SCRN
- ldx #$00
- rts
-
-; ------------------------------------------------------------------------
-; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
-; X2/Y2 = ptr3/ptr4 using the current drawing color.
-;
-; Must set an error code: NO
-;
-
-LINE:
- ; nx = abs(x2 - x1)
- lda X2
- sub X1
- sta NX
- lda X2+1
- sbc X1+1
- tay
- lda NX
- jsr abs
- sta NX
- sty NX+1
- ; ny = abs(y2 - y1)
- lda Y2
- sub Y1
- sta NY
- lda Y2+1
- sbc Y1+1
- tay
- lda NY
- jsr abs
- sta NY
- sty NY+1
- ; if (x2>x1)
- ldx #X2
- lda X1
- ldy X1+1
- jsr icmp
- bcc @L0243
- beq @L0243
- ; dx = 1;
- lda #$01
- bne @L0244
- ; else
- ; dx = -1;
-@L0243: lda #$FF
-@L0244: sta DX
- ; if (y2>y1)
- ldx #Y2
- lda Y1
- ldy Y1+1
- jsr icmp
- bcc @L024A
- beq @L024A
- ; dy = 1;
- lda #$01
- bne @L024B
- ; else
- ; dy = -1;
-@L024A: lda #$FF
-@L024B: sta DY
- ; err = ay = 0;
- lda #$00
- sta ERR
- sta ERR+1
- sta AY
-
- ; if (nx<ny) {
- ldx #NX
- lda NY
- ldy NY+1
- jsr icmp
- bcs @L0255
- ; nx <-> ny
- lda NX
- ldx NY
- sta NY
- stx NX
- lda NX+1
- ldx NY+1
- sta NY+1
- stx NX+1
- ; ay = dx
- lda DX
- sta AY
- ; dx = dy = 0;
- lda #$00
- sta DX
- sta DY
- ; ny = - ny;
-@L0255: lda NY
- ldy NY+1
- jsr neg
- sta NY
- sty NY+1
- ; for (count=nx;count>0;--count) {
- lda NX
- ldx NX+1
- sta COUNT
- stx COUNT+1
-@L0166: lda COUNT ; count>0
- ora COUNT+1
- bne @L0167
- rts
- ; setpixel(X1,Y1)
-@L0167: jsr SETPIXELCLIP
- ; pb = err + ny
- lda ERR
- add NY
- sta PB
- lda ERR+1
- adc NY+1
- sta PB+1
- tax
- ; ub = pb + nx
- lda PB
- add NX
- sta UB
- txa
- adc NX+1
- sta UB+1
- ; x1 = x1 + dx
- ldx #$00
- lda DX
- bpl @L027B
- dex
-@L027B: add X1
- sta X1
- txa
- adc X1+1
- sta X1+1
- ; y1 = y1 + ay
- ldx #$00
- lda AY
- bpl @L027E
- dex
-@L027E: add Y1
- sta Y1
- txa
- adc Y1+1
- sta Y1+1
- ; if (abs(pb)<abs(ub)) {
- lda PB
- ldy PB+1
- jsr abs
- sta TEMP3
- sty TEMP4
- lda UB
- ldy UB+1
- jsr abs
- ldx #TEMP3
- jsr icmp
- bpl @L027F
- ; err = pb
- lda PB
- ldx PB+1
- jmp @L0312
- ; } else { x1 = x1 + ay
-@L027F:
- ldx #$00
- lda AY
- bpl @L0288
- dex
-@L0288: add X1
- sta X1
- txa
- adc X1+1
- sta X1+1
- ; y1 = y1 + dy
- ldx #$00
- lda DY
- bpl @L028B
- dex
-@L028B: add Y1
- sta Y1
- txa
- adc Y1+1
- sta Y1+1
- ; err = ub }
- lda UB
- ldx UB+1
-@L0312:
- sta ERR
- stx ERR+1
- ; } (--count)
- sec
- lda COUNT
- sbc #$01
- sta COUNT
- bcc @L0260
- jmp @L0166
-@L0260: dec COUNT+1
- jmp @L0166
-
-; ------------------------------------------------------------------------
-; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
-; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
-; Contrary to most other functions, the graphics kernel will sort and clip
-; the coordinates before calling the driver, so on entry the following
-; conditions are valid:
-; X1 <= X2
-; Y1 <= Y2
-; (X1 >= 0) && (X1 < XRES)
-; (X2 >= 0) && (X2 < XRES)
-; (Y1 >= 0) && (Y1 < YRES)
-; (Y2 >= 0) && (Y2 < YRES)
-;
-; Must set an error code: NO
-;
-
-BAR:
- inc Y2
- ldx X2
- stx H2
-@L1: ldy X1
- lda Y1
- jsr HLINE
- inc Y1
- lda Y2
- cmp Y1
- bne @L1
- rts
-
-; ------------------------------------------------------------------------
-; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
-; radius in tmp1 and the current drawing color.
-;
-; Must set an error code: NO
-;
-
-CIRCLE:
- lda RADIUS
- bne @L1
- jmp SETPIXELCLIP ; Plot as a point
-
-@L1: sta XX
- ; x = r;
- lda #$00
- sta XX+1
- sta YY
- sta YY+1
- sta MaxO
- sta MaxO+1
- ; y =0; mo=0;
- lda X1
- ldx X1+1
- sta XS
- stx XS+1
- lda Y1
- ldx Y1+1
- sta YS
- stx YS+1 ; XS/YS to remember the center
-
- ; while (y<x) {
-@L013B: ldx #YY
- lda XX
- ldy XX+1
- jsr icmp
- bcc @L12
- rts
-@L12: ; plot points in 8 slices...
- lda XS
- add XX
- sta X1
- lda XS+1
- adc XX+1
- sta X1+1 ; x1 = xs+x
- lda YS
- add YY
- sta Y1
- pha
- lda YS+1
- adc YY+1
- sta Y1+1 ; (stack)=ys+y, y1=(stack)
- pha
- jsr SETPIXELCLIP ; plot(xs+x,ys+y)
- lda YS
- sub YY
- sta Y1
- sta Y3
- lda YS+1
- sbc YY+1
- sta Y1+1 ; y3 = y1 = ys-y
- sta Y3+1
- jsr SETPIXELCLIP ; plot(xs+x,ys-y)
- pla
- sta Y1+1
- pla
- sta Y1 ; y1 = ys+y
- lda XS
- sub XX
- sta X1
- lda XS+1
- sbc XX+1
- sta X1+1
- jsr SETPIXELCLIP ; plot (xs-x,ys+y)
- lda Y3
- sta Y1
- lda Y3+1
- sta Y1+1
- jsr SETPIXELCLIP ; plot (xs-x,ys-y)
-
- lda XS
- add YY
- sta X1
- lda XS+1
- adc YY+1
- sta X1+1 ; x1 = xs+y
- lda YS
- add XX
- sta Y1
- pha
- lda YS+1
- adc XX+1
- sta Y1+1 ; (stack)=ys+x, y1=(stack)
- pha
- jsr SETPIXELCLIP ; plot(xs+y,ys+x)
- lda YS
- sub XX
- sta Y1
- sta Y3
- lda YS+1
- sbc XX+1
- sta Y1+1 ; y3 = y1 = ys-x
- sta Y3+1
- jsr SETPIXELCLIP ; plot(xs+y,ys-x)
- pla
- sta Y1+1
- pla
- sta Y1 ; y1 = ys+x(stack)
- lda XS
- sub YY
- sta X1
- lda XS+1
- sbc YY+1
- sta X1+1
- jsr SETPIXELCLIP ; plot (xs-y,ys+x)
- lda Y3
- sta Y1
- lda Y3+1
- sta Y1+1
- jsr SETPIXELCLIP ; plot (xs-y,ys-x)
-
- ; og = mo+y+y+1
- lda MaxO
- ldx MaxO+1
- add YY
- tay
- txa
- adc YY+1
- tax
- tya
- add YY
- tay
- txa
- adc YY+1
- tax
- tya
- add #$01
- bcc @L0143
- inx
-@L0143: sta OGora
- stx OGora+1
- ; ou = og-x-x+1
- sub XX
- tay
- txa
- sbc XX+1
- tax
- tya
- sub XX
- tay
- txa
- sbc XX+1
- tax
- tya
- add #$01
- bcc @L0146
- inx
-@L0146: sta OUkos
- stx OUkos+1
- ; ++y
- inc YY
- bne @L0148
- inc YY+1
-@L0148: ; if (abs(ou)<abs(og))
- lda OUkos
- ldy OUkos+1
- jsr abs
- sta TEMP3
- sty TEMP4
- lda OGora
- ldy OGora+1
- jsr abs
- ldx #TEMP3
- jsr icmp
- bpl @L0149
- ; { --x;
- lda XX
- sub #$01
- sta XX
- bcs @L014E
- dec XX+1
-@L014E: ; mo = ou; }
- lda OUkos
- ldx OUkos+1
- jmp @L014G
- ; else { mo = og }
-@L0149: lda OGora
- ldx OGora+1
-@L014G: sta MaxO
- stx MaxO+1
- ; }
- jmp @L013B
-
-; ------------------------------------------------------------------------
-; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
-; direction is passend in X/Y, the text direction is passed in A.
-;
-; Must set an error code: NO
-;
-
-TEXTSTYLE:
- rts
-
-
-; ------------------------------------------------------------------------
-; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
-; current text style. The text to output is given as a zero terminated
-; string with address in ptr3.
-;
-; Must set an error code: NO
-;
-
-OUTTEXT:
- lda ptr1
- sta CH
- lda ptr2
- jsr VTABZ
- ldy #$00
-@L1: lda (ptr3),y
- ora #$80
- jsr COUT
- iny
- cmp #$80
- bne @L1
- rts
-
-;-------------
-; copies of some runtime routines
-
-abs:
- ; a/y := abs(a/y)
- cpy #$00
- bpl absend
- ; negay
-neg: clc
- eor #$FF
- adc #$01
- pha
- tya
- eor #$FF
- adc #$00
- tay
- pla
-absend: rts
-
-icmp:
- ; compare a/y to zp,x
- sta TEMP ; TEMP/TEMP2 - arg2
- sty TEMP2
- lda $00,x
- pha
- lda $01,x
- tay
- pla
- tax
- tya ; x/a - arg1 (a=high)
-
- sub TEMP2
- bne @L4
- cpx TEMP
- beq @L3
- adc #$FF
- ora #$01
-@L3: rts
-@L4: bvc @L3
- eor #$FF
- ora #$01
- rts
--- /dev/null
+;
+; Graphics driver for the 40x48x16 mode on the Apple II
+;
+; Stefan Haubenthal <polluks@sdf.lonestar.org>
+; Oliver Schmidt <ol.sc@web.de>
+; Based on Maciej Witkowiak's line and circle routine
+;
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-mode.inc"
+ .include "tgi-error.inc"
+ .include "apple2.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+
+; Zero page stuff
+
+H2 := $2C
+
+; ROM entry points
+
+TEXT := $F399
+PLOT := $F800
+HLINE := $F819
+CLRSCR := $F832
+SETCOL := $F864
+SCRN := $F871
+SETGR := $FB40
+HOME := $FC58
+
+; ------------------------------------------------------------------------
+
+; Variables mapped to the zero page segment variables. Some of these are
+; used for passing parameters to the driver.
+
+X1 := ptr1
+Y1 := ptr2
+X2 := ptr3
+Y2 := ptr4
+RADIUS := tmp1
+
+ADDR := tmp1
+TEMP := tmp3
+TEMP2 := tmp4
+TEMP3 := sreg
+TEMP4 := sreg+1
+
+; Line routine stuff (must be on zpage)
+
+PB := ptr3 ; (2) LINE
+UB := ptr4 ; (2) LINE
+ERR := regsave ; (2) LINE
+NX := regsave+2 ; (2) LINE
+
+; Circle routine stuff (must be on zpage)
+
+XX := ptr3 ; (2) CIRCLE
+YY := ptr4 ; (2) CIRCLE
+MaxO := sreg ; (overwritten by TEMP3+TEMP4, but restored from OG/OU anyway)
+XS := regsave ; (2) CIRCLE
+YS := regsave+2 ; (2) CIRCLE
+
+; ------------------------------------------------------------------------
+
+ .segment "JUMPTABLE"
+
+; Header. Includes jump table and constants.
+
+; First part of the header is a structure that has a magic and defines the
+; capabilities of the driver
+
+ .byte $74, $67, $69 ; "tgi"
+ .byte TGI_API_VERSION ; TGI API version number
+xres: .word 40 ; X resolution
+yres: .word 48 ; Y resolution
+ .byte 16 ; Number of drawing colors
+ .byte 1 ; Number of screens available
+ .byte 8 ; System font X size
+ .byte 8 ; System font Y size
+ .res 4, $00 ; Reserved for future extensions
+
+; Next comes the jump table. Currently all entries must be valid and may point
+; to an RTS for test versions (function not implemented).
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr INIT
+ .addr DONE
+ .addr GETERROR
+ .addr CONTROL
+ .addr CLEAR
+ .addr SETVIEWPAGE
+ .addr SETDRAWPAGE
+ .addr SETCOLOR
+ .addr SETPALETTE
+ .addr GETPALETTE
+ .addr GETDEFPALETTE
+ .addr SETPIXEL
+ .addr GETPIXEL
+ .addr LINE
+ .addr BAR
+ .addr CIRCLE
+ .addr TEXTSTYLE
+ .addr OUTTEXT
+ .addr 0 ; IRQ entry is unused
+
+; ------------------------------------------------------------------------
+
+ .bss
+
+; Absolute variables used in the code
+
+ERROR: .res 1 ; Error code
+
+; Line routine stuff (combined with circle routine stuff to save space)
+
+OGora:
+COUNT: .res 2
+OUkos:
+NY: .res 2
+Y3:
+DX: .res 1
+DY: .res 1
+AX: .res 1
+AY: .res 1
+
+; ------------------------------------------------------------------------
+
+ .rodata
+
+; Constants and tables
+
+DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
+ .byte $08, $09, $0A, $0B, $0C, $0D, $0E, $0F
+
+; ------------------------------------------------------------------------
+
+ .code
+
+; INIT: Changes an already installed device from text mode to graphics mode.
+; Note that INIT/DONE may be called multiple times while the driver
+; is loaded, while INSTALL is only called once, so any code that is needed
+; to initializes variables and so on must go here. Setting palette and
+; clearing the screen is not needed because this is called by the graphics
+; kernel later.
+; The graphics kernel will never call INIT when a graphics mode is already
+; active, so there is no need to protect against that.
+; Must set an error code: YES
+INIT:
+ ; Switch into graphics mode
+ bit $C082 ; Switch in ROM
+ jsr SETGR
+ bit MIXCLR
+ bit $C080 ; Switch in LC bank 2 for R/O
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta ERROR
+
+ ; Fall through
+
+; INSTALL routine. Is called after the driver is loaded into memory. May
+; initialize anything that has to be done just once. Is probably empty
+; most of the time.
+; Must set an error code: NO
+INSTALL:
+ ; Fall through
+
+; UNINSTALL routine. Is called before the driver is removed from memory. May
+; clean up anything done by INSTALL but is probably empty most of the time.
+; Must set an error code: NO
+UNINSTALL:
+ ; Fall through
+
+; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
+; The page number is already checked to be valid by the graphics kernel.
+; Must set an error code: NO (will only be called if page ok)
+SETVIEWPAGE:
+ ; Fall through
+
+; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
+; The page number is already checked to be valid by the graphics kernel.
+; Must set an error code: NO (will only be called if page ok)
+SETDRAWPAGE:
+ ; Fall through
+
+; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
+; direction is passend in X/Y, the text direction is passed in A.
+; Must set an error code: NO
+TEXTSTYLE:
+ ; Fall through
+
+; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
+; current text style. The text to output is given as a zero terminated
+; string with address in ptr3.
+; Must set an error code: NO
+OUTTEXT:
+ rts
+
+; DONE: Will be called to switch the graphics device back into text mode.
+; The graphics kernel will never call DONE when no graphics mode is active,
+; so there is no need to protect against that.
+; Must set an error code: NO
+DONE:
+ bit $C082 ; Switch in ROM
+ jsr TEXT
+ jsr HOME
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; GETERROR: Return the error code in A and clear it.
+GETERROR:
+ lda ERROR
+ ldx #TGI_ERR_OK
+ stx ERROR
+ rts
+
+; CLEAR: Clears the screen.
+; Must set an error code: NO
+CLEAR:
+ bit $C082 ; Switch in ROM
+ jsr CLRSCR
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; SETCOLOR: Set the drawing color (in A). The new color is already checked
+; to be in a valid range (0..maxcolor-1).
+; Must set an error code: NO (will only be called if color ok)
+SETCOLOR:
+ bit $C082 ; Switch in ROM
+ jsr SETCOL
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; CONTROL: Platform/driver specific entry point.
+; Must set an error code: YES
+CONTROL:
+ ; Fall through
+
+; SETPALETTE: Set the palette (not available with all drivers/hardware).
+; A pointer to the palette is passed in ptr1. Must set an error if palettes
+; are not supported
+; Must set an error code: YES
+SETPALETTE:
+ lda #TGI_ERR_INV_FUNC
+ sta ERROR
+ rts
+
+; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
+; set the palette should return the default palette here, so there's no
+; way for this function to fail.
+; Must set an error code: NO
+GETPALETTE:
+ ; Fall through
+
+; GETDEFPALETTE: Return the default palette for the driver in A/X. All
+; drivers should return something reasonable here, even drivers that don't
+; support palettes, otherwise the caller has no way to determine the colors
+; of the (not changeable) palette.
+; Must set an error code: NO (all drivers must have a default palette)
+GETDEFPALETTE:
+ lda #<DEFPALETTE
+ ldx #>DEFPALETTE
+ rts
+
+; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
+; color. The coordinates passed to this function are never outside the
+; visible screen area, so there is no need for clipping inside this function.
+; Must set an error code: NO
+SETPIXEL:
+ bit $C082 ; Switch in ROM
+ ldy X1
+ lda Y1
+ jsr PLOT
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+SETPIXELCLIP:
+ lda Y1+1
+ bmi :+ ; y < 0
+ lda X1+1
+ bmi :+ ; x < 0
+ lda X1
+ ldx X1+1
+ sta ADDR
+ stx ADDR+1
+ ldx #ADDR
+ lda xres
+ ldy xres+1
+ jsr icmp ; ( x < xres ) ...
+ bcs :+
+ lda Y1
+ ldx Y1+1
+ sta ADDR
+ stx ADDR+1
+ ldx #ADDR
+ lda yres
+ ldy yres+1
+ jsr icmp ; ... && ( y < yres )
+ bcc SETPIXEL
+: rts
+
+; GETPIXEL: Read the color value of a pixel and return it in A/X. The
+; coordinates passed to this function are never outside the visible screen
+; area, so there is no need for clipping inside this function.
+GETPIXEL:
+ bit $C082 ; Switch in ROM
+ ldy X1
+ lda Y1
+ jsr SCRN
+ ldx #$00
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
+; X2/Y2 = ptr3/ptr4 using the current drawing color.
+; Must set an error code: NO
+LINE:
+ ; nx = abs (x2 - x1)
+ lda X2
+ sub X1
+ sta NX
+ lda X2+1
+ sbc X1+1
+ tay
+ lda NX
+ jsr abs
+ sta NX
+ sty NX+1
+
+ ; ny = abs (y2 - y1)
+ lda Y2
+ sub Y1
+ sta NY
+ lda Y2+1
+ sbc Y1+1
+ tay
+ lda NY
+ jsr abs
+ sta NY
+ sty NY+1
+
+ ; if (x2 >= x1)
+ ldx #X2
+ lda X1
+ ldy X1+1
+ jsr icmp
+ bcc :+
+
+ ; dx = 1
+ lda #$01
+ bne :++
+
+ ; else
+ ; dx = -1
+: lda #$FF
+: sta DX
+
+ ; if (y2 >= y1)
+ ldx #Y2
+ lda Y1
+ ldy Y1+1
+ jsr icmp
+ bcc :+
+
+ ; dy = 1
+ lda #$01
+ bne :++
+
+ ; else
+ ; dy = -1
+: lda #$FF
+: sta DY
+
+ ; err = ax = ay = 0
+ lda #$00
+ sta ERR
+ sta ERR+1
+ sta AX
+ sta AY
+
+ ; if (nx < ny) {
+ ldx #NX
+ lda NY
+ ldy NY+1
+ jsr icmp
+ bcs :+
+
+ ; nx <-> ny
+ lda NX
+ ldx NY
+ sta NY
+ stx NX
+ lda NX+1
+ ldx NY+1
+ sta NY+1
+ stx NX+1
+
+ ; ax = dx
+ lda DX
+ sta AX
+
+ ; ay = dy
+ lda DY
+ sta AY
+
+ ; dx = dy = 0 }
+ lda #$00
+ sta DX
+ sta DY
+
+ ; ny = - ny
+: lda NY
+ ldy NY+1
+ jsr neg
+ sta NY
+ sty NY+1
+
+ ; for (count = nx; count > 0; --count) {
+ lda NX
+ ldx NX+1
+ sta COUNT
+ stx COUNT+1
+for: lda COUNT ; count > 0
+ ora COUNT+1
+ bne :+
+ rts
+
+ ; setpixel (X1, Y1)
+: jsr SETPIXELCLIP
+
+ ; pb = err + ny
+ lda ERR
+ add NY
+ sta PB
+ lda ERR+1
+ adc NY+1
+ sta PB+1
+ tax
+
+ ; ub = pb + nx
+ lda PB
+ add NX
+ sta UB
+ txa
+ adc NX+1
+ sta UB+1
+
+ ; x1 = x1 + dx
+ ldx #$00
+ lda DX
+ bpl :+
+ dex
+: add X1
+ sta X1
+ txa
+ adc X1+1
+ sta X1+1
+
+ ; y1 = y1 + ay
+ ldx #$00
+ lda AY
+ bpl :+
+ dex
+: add Y1
+ sta Y1
+ txa
+ adc Y1+1
+ sta Y1+1
+
+ ; if (abs (pb) < abs (ub)) {
+ lda PB
+ ldy PB+1
+ jsr abs
+ sta TEMP3
+ sty TEMP4
+ lda UB
+ ldy UB+1
+ jsr abs
+ ldx #TEMP3
+ jsr icmp
+ bpl :+
+
+ ; err = pb }
+ lda PB
+ ldx PB+1
+ jmp next
+
+ ; else { x1 = x1 + ax
+: ldx #$00
+ lda AX
+ bpl :+
+ dex
+: add X1
+ sta X1
+ txa
+ adc X1+1
+ sta X1+1
+
+ ; y1 = y1 + dy
+ ldx #$00
+ lda DY
+ bpl :+
+ dex
+: add Y1
+ sta Y1
+ txa
+ adc Y1+1
+ sta Y1+1
+
+ ; err = ub }
+ lda UB
+ ldx UB+1
+next: sta ERR
+ stx ERR+1
+
+ ; } (--count)
+ lda COUNT
+ sub #$01
+ sta COUNT
+ bcc :+
+ jmp for
+: dec COUNT+1
+ jmp for
+
+; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
+; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
+; Contrary to most other functions, the graphics kernel will sort and clip
+; the coordinates before calling the driver, so on entry the following
+; conditions are valid:
+; X1 <= X2
+; Y1 <= Y2
+; (X1 >= 0) && (X1 < XRES)
+; (X2 >= 0) && (X2 < XRES)
+; (Y1 >= 0) && (Y1 < YRES)
+; (Y2 >= 0) && (Y2 < YRES)
+; Must set an error code: NO
+BAR:
+ bit $C082 ; Switch in ROM
+ inc Y2
+ ldx X2
+ stx H2
+: ldy X1
+ lda Y1
+ jsr HLINE
+ inc Y1
+ lda Y2
+ cmp Y1
+ bne :-
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the
+; radius in tmp1 and the current drawing color.
+; Must set an error code: NO
+CIRCLE:
+ lda RADIUS
+ bne :+
+ jmp SETPIXELCLIP ; Plot as a point
+: sta XX
+
+ ; x = r
+ lda #$00
+ sta XX+1
+ sta YY
+ sta YY+1
+ sta MaxO
+ sta MaxO+1
+
+ ; y = 0, mo = 0
+ lda X1
+ ldx X1+1
+ sta XS
+ stx XS+1
+ lda Y1
+ ldx Y1+1
+ sta YS
+ stx YS+1 ; XS/YS to remember the center
+
+ ; while (y < x) {
+while: ldx #YY
+ lda XX
+ ldy XX+1
+ jsr icmp
+ bcc :+
+ rts
+
+ ; Plot points in 8 slices...
+: lda XS
+ add XX
+ sta X1
+ lda XS+1
+ adc XX+1
+ sta X1+1 ; x1 = xs + x
+ lda YS
+ add YY
+ sta Y1
+ pha
+ lda YS+1
+ adc YY+1
+ sta Y1+1 ; (stack) = ys + y, y1 = (stack)
+ pha
+ jsr SETPIXELCLIP ; plot (xs + x, ys + y)
+ lda YS
+ sub YY
+ sta Y1
+ sta Y3
+ lda YS+1
+ sbc YY+1
+ sta Y1+1 ; y3 = y1 = ys - y
+ sta Y3+1
+ jsr SETPIXELCLIP ; plot (xs + x, ys - y)
+ pla
+ sta Y1+1
+ pla
+ sta Y1 ; y1 = ys + y
+ lda XS
+ sub XX
+ sta X1
+ lda XS+1
+ sbc XX+1
+ sta X1+1
+ jsr SETPIXELCLIP ; plot (xs - x, ys + y)
+ lda Y3
+ sta Y1
+ lda Y3+1
+ sta Y1+1
+ jsr SETPIXELCLIP ; plot (xs - x, ys - y)
+
+ lda XS
+ add YY
+ sta X1
+ lda XS+1
+ adc YY+1
+ sta X1+1 ; x1 = xs + y
+ lda YS
+ add XX
+ sta Y1
+ pha
+ lda YS+1
+ adc XX+1
+ sta Y1+1 ; (stack) = ys + x, y1 = (stack)
+ pha
+ jsr SETPIXELCLIP ; plot (xs + y, ys + x)
+ lda YS
+ sub XX
+ sta Y1
+ sta Y3
+ lda YS+1
+ sbc XX+1
+ sta Y1+1 ; y3 = y1 = ys - x
+ sta Y3+1
+ jsr SETPIXELCLIP ; plot (xs + y, ys - x)
+ pla
+ sta Y1+1
+ pla
+ sta Y1 ; y1 = ys + x(stack)
+ lda XS
+ sub YY
+ sta X1
+ lda XS+1
+ sbc YY+1
+ sta X1+1
+ jsr SETPIXELCLIP ; plot (xs - y, ys + x)
+ lda Y3
+ sta Y1
+ lda Y3+1
+ sta Y1+1
+ jsr SETPIXELCLIP ; plot (xs - y, ys - x)
+
+ ; og = mo + y + y + 1
+ lda MaxO
+ ldx MaxO+1
+ add YY
+ tay
+ txa
+ adc YY+1
+ tax
+ tya
+ add YY
+ tay
+ txa
+ adc YY+1
+ tax
+ tya
+ add #$01
+ bcc :+
+ inx
+: sta OGora
+ stx OGora+1
+
+ ; ou = og - x - x + 1
+ sub XX
+ tay
+ txa
+ sbc XX+1
+ tax
+ tya
+ sub XX
+ tay
+ txa
+ sbc XX+1
+ tax
+ tya
+ add #$01
+ bcc :+
+ inx
+: sta OUkos
+ stx OUkos+1
+
+ ; ++y
+ inc YY
+ bne :+
+ inc YY+1
+
+ ; if (abs (ou) < abs (og)) {
+: lda OUkos
+ ldy OUkos+1
+ jsr abs
+ sta TEMP3
+ sty TEMP4
+ lda OGora
+ ldy OGora+1
+ jsr abs
+ ldx #TEMP3
+ jsr icmp
+ bpl :++
+
+ ; --x
+ lda XX
+ sub #$01
+ sta XX
+ bcs :+
+ dec XX+1
+
+ ; mo = ou }
+: lda OUkos
+ ldx OUkos+1
+ jmp :++
+
+ ; else mo = og
+: lda OGora
+ ldx OGora+1
+: sta MaxO
+ stx MaxO+1
+
+ ; }
+ jmp while
+
+; Copies of some runtime routines
+
+abs:
+ ; A/Y := abs (A/Y)
+ cpy #$00
+ bpl :+
+
+ ; A/Y := neg (A/Y)
+neg: clc
+ eor #$FF
+ adc #$01
+ pha
+ tya
+ eor #$FF
+ adc #$00
+ tay
+ pla
+: rts
+
+icmp:
+ ; Compare A/Y to zp,X
+ sta TEMP ; TEMP/TEMP2 - arg2
+ sty TEMP2
+ lda $00,x
+ pha
+ lda $01,x
+ tay
+ pla
+ tax
+ tya ; X/A - arg1 (a = high)
+
+ sub TEMP2
+ bne :++
+ cpx TEMP
+ beq :+
+ adc #$FF
+ ora #$01
+: rts
+: bvc :+
+ eor #$FF
+ ora #$01
+: rts
;
-; Standard joystick driver for the Apple ][. May be used multiple times when
-; linked to the statically application.
+; Standard joystick driver for the Apple ][. May be used multiple times
+; when statically linked to the application.
;
; Ullrich von Bassewitz, 2003-05-02
+; Oliver Schmidt, 2008-02-25
; Using the readjoy code from Stefan Haubenthal
;
.macpack generic
-
; ------------------------------------------------------------------------
+
; Constants
-OFFS = 10
+THRESHOLD = 20 ; Deviation from center triggering movement
; ------------------------------------------------------------------------
+
; ROM entry points
PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
; ------------------------------------------------------------------------
-; Header. Includes jump table
-.segment "JUMPTABLE"
+; Header. Includes jump table.
+
+ .segment "JUMPTABLE"
; Driver signature
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
; Button state masks (8 values)
- .byte $40
- .byte $80
.byte $10
.byte $20
+ .byte $04
.byte $08
- .byte $00 ; FIRE2 not available
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
+ .byte $40
+ .byte $80
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
-; Jump table.
+; Jump table
.addr INSTALL
.addr UNINSTALL
.addr COUNT
.addr READJOY
- .addr 0 ; IRQ not used
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
+ .addr 0 ; IRQ not used
; ------------------------------------------------------------------------
-; Data.
-
-.code
+ .code
-; ------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present and determine the amount of
; memory available.
; Must return an JOY_ERR_xx code in a/x.
-;
-
INSTALL:
lda #<JOY_ERR_OK
ldx #>JOY_ERR_OK
-; rts ; Run into UNINSTALL instead
+ ; Fall through
-; ------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory.
; Can do cleanup or whatever. Must not return anything.
-;
-
UNINSTALL:
rts
-
-; ------------------------------------------------------------------------
; COUNT: Return the total number of available joysticks in a/x.
-;
-
COUNT:
- lda #<JOY_COUNT
- ldx #>JOY_COUNT
+ lda #$02 ; Number of joysticks we support
+ ldx #$00
rts
-; ------------------------------------------------------------------------
; READ: Read a particular joystick passed in A.
-;
-
READJOY:
- and #$01 ; Fix joystick number
- asl a ;
- tax ; Joystick number (0,2) into X
-
-; Read joystick
-
- lda BUTN0,x ; Check fire button
- and #$80 ; BTN 0 0 0 0 0 0 0
-
+ bit $C082 ; Switch in ROM
+ and #$01 ; Restrict joystick number
+
+ ; Read horizontal paddle
+ asl ; Joystick number -> paddle number
+ tax ; Set paddle number (0, 2)
+ jsr PREAD ; Read paddle value
+ lda #$00 ; 0 0 0 0 0 0 0 0
+ cpy #127 - THRESHOLD
+ ror ; !LEFT 0 0 0 0 0 0 0
+ cpy #127 + THRESHOLD
+ ror ; RIGHT !LEFT 0 0 0 0 0 0
+
+ ; Read vertical paddle
pha
- jsr PREAD ; Read first paddle value
+ inx ; Set paddle number (1, 3)
+ jsr PREAD ; Read paddle value
pla
- cpy #127-OFFS
- ror a ; /LEFT BTN 0 0 0 0 0 0
- cpy #127+OFFS
- ror a ; RIGHT /LEFT BTN 0 0 0 0 0
-
- inx
- pha
- jsr PREAD ; Read second paddle
- pla
- cpy #127-OFFS
- ror a ; /UP RIGHT /LEFT BTN 0 0 0 0
- cpy #127+OFFS
- ror a ; DOWN /UP RIGHT /LEFT BTN 0 0 0
- eor #%01010000 ; DOWN UP RIGHT LEFT BTN 0 0 0
-
- ldx #$00 ; fix X
+ cpy #127 - THRESHOLD
+ ror ; !UP RIGHT !LEFT 0 0 0 0 0
+ cpy #127 + THRESHOLD
+ ror ; DOWN !UP RIGHT !LEFT 0 0 0 0
+
+ ; Read primary button
+ tay
+ lda BUTN0-1,x ; Check button (1, 3)
+ asl
+ tya
+ ror ; FIRE DOWN !UP RIGHT !LEFT 0 0 0
+
+ ; Read secondary button
+ tay
+ inx
+ txa
+ and #$03 ; IIgs has fourth button at TAPEIN
+ tax
+ lda BUTN0-1,x ; Check button (2, 0)
+ asl
+ tya
+ ror ; FIRE2 FIRE DOWN !UP RIGHT !LEFT 0 0
+
+ ; Finalize
+ eor #%00010100 ; FIRE2 FIRE DOWN UP RIGHT LEFT 0 0
+ ldx #$00
+ bit $C080 ; Switch in LC bank 2 for R/O
rts
-
-
asl
sta yparam+1
- .ifdef __APPLE2ENH__
- ; Save LC read state
- ldx #<ROMIN
- bit RDLCRAM
- bpl :+
- ldx #<LCBANK1
- bit RDLCBNK2
- bpl :+
- ldx #<LCBANK2
-: phx
-
- ; The AppleMouse II Card needs the ROM swapped in
+ ; The AppleMouse II Card needs the ROM switched in
; to be able to detect an Apple //e and use RDVBL
- sta ROMIN ; STA keeps LC write state
- .endif
+ bit $C082
; Reset mouse hardware
ldx #INITMOUSE
jsr firmware
- .ifdef __APPLE2ENH__
- ; Restore LC read state
- plx
- sta $C000,x ; STA keeps LC write state
- .endif
+ ; Switch in LC bank 2 for R/O
+ bit $C080
; Turn mouse on
lda #%00000001
; 80 column video switches
CLR80COL:= $C000 ; Disable 80 column store
SET80COL:= $C001 ; Enable 80 column store
+RD80COL := $C018 ; >127 if 80 column store enabled
RD80VID := $C01F ; >127 if 80 column video enabled
; Character set switches
LCBANK1 := $C08B ; Swap in LC bank 1
; Video mode switches
+TXTCLR := $C050 ; Display graphics
+TXTSET := $C051 ; Display text
MIXCLR := $C052 ; Disable 4 lines of text
MIXSET := $C053 ; Enable 4 lines of text
LOWSCR := $C054 ; Page 1
--- /dev/null
+;
+; Oliver Schmidt, 03.03.2007
+;
+; COUT routine
+;
+
+ .export COUT
+
+ .include "apple2.inc"
+
+ .segment "LOWCODE"
+
+COUT:
+ ; Switch in ROM and call COUT
+ bit $C082
+ jsr $FDED ; Vector to user output routine
+
+ ; Switch in LC bank 2 for R/O and return
+ bit $C080
+ rts
.import zerobss
.import initlib, donelib
.import callmain, callirq
- .import COUT
- .import __STARTUP_LOAD__, __BSS_LOAD__ ; Linker generated
+ .import __RAM_START__ , __RAM_LAST__ ; Linker generated
+ .import __MOVE_START__, __MOVE_LAST__ ; Linker generated
+ .import __LC_START__ , __LC_LAST__ ; Linker generated
+ .import __BSS_RUN__ , __INIT_SIZE__ ; Linker generated
.import __INTERRUPTOR_COUNT__ ; Linker generated
.include "zeropage.inc"
.include "apple2.inc"
- .include "mli.inc"
+
+ .linecont +
; ------------------------------------------------------------------------
.segment "EXEHDR"
- .addr __STARTUP_LOAD__ ; Start address
- .word __BSS_LOAD__ - __STARTUP_LOAD__ ; Size
+ .addr __RAM_START__ ; Start address
+ .word __BSS_RUN__ - __RAM_START__ + \
+ __MOVE_LAST__ - __MOVE_START__ ; Size
; ------------------------------------------------------------------------
ldx #$FF
txs ; Init stack pointer
- ; Delegate all further processing to keep STARTUP small
+ ; Switch in LC bank 2 for W/O
+ bit $C081
+ bit $C081
+
+ ; Set source start address
+ lda #<(__BSS_RUN__ + __INIT_SIZE__)
+ ldy #>(__BSS_RUN__ + __INIT_SIZE__)
+ sta $9B
+ sty $9C
+
+ ; Set source last address
+ lda #<(__BSS_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
+ ldy #>(__BSS_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
+ sta $96
+ sty $97
+
+ ; Set destination last address
+ lda #<__LC_LAST__
+ ldy #>__LC_LAST__
+ sta $94
+ sty $95
+
+ ; Call into Applesoft Block Transfer Utility - which handles zero
+ ; sized blocks well - to move content of the LC memory area
+ jsr $D396 ; BLTU + 3
+
+ ; Set source start address
+ lda #<__BSS_RUN__
+ ldy #>__BSS_RUN__
+ sta $9B
+ sty $9C
+
+ ; Set source last address
+ lda #<(__BSS_RUN__ + __INIT_SIZE__)
+ ldy #>(__BSS_RUN__ + __INIT_SIZE__)
+ sta $96
+ sty $97
+
+ ; Set destination last address
+ lda #<__RAM_LAST__
+ ldy #>__RAM_LAST__
+ sta $94
+ sty $95
+
+ ; Call into Applesoft Block Transfer Utility - which handles moving
+ ; overlapping blocks upwards well - to move the INIT segment
+ jsr $D396 ; BLTU + 3
+
+ ; Delegate all further processing to keep the STARTUP segment small
jsr init
; Avoid re-entrance of donelib. This is also the _exit entry
_exit: ldx #<exit
lda #>exit
jsr reset ; Setup RESET vector
+
+ ; Switch in ROM in case it wasn't already switched in by a RESET
+ bit $C082
; Call module destructors
jsr donelib
; Deallocate interrupt vector table entry
dec params ; Adjust parameter count
- jsr ENTRY
+ jsr $BF00 ; MLI call entry point
.byte $41 ; Dealloc interrupt
.addr params
dex
bpl :-
+ ; Clear the BSS data
+ jsr zerobss
+
; Save the original RESET vector
ldx #$02
: lda SOFTEV,x
lda #>_exit
jsr reset ; Setup RESET vector
- ; Clear the BSS data
- jsr zerobss
-
; Setup the stack
lda HIMEM
sta sp
beq :+
; Check for ProDOS
- lda ENTRY
+ lda $BF00 ; MLI call entry point
cmp #$4C ; Is MLI present? (JMP opcode)
bne prterr
; Allocate interrupt vector table entry
- jsr ENTRY
+ jsr $BF00 ; MLI call entry point
.byte $40 ; Alloc interrupt
.addr params
bcs prterr
; Call module constructors
: jsr initlib
+ ; Switch in LC bank 2 for R/O
+ bit $C080
+
; Push arguments and call main()
jmp callmain
; Print error message and return
prterr: ldx #msglen-1
: lda errmsg,x
- jsr COUT
+ jsr $FDED ; COUT
dex
bpl :-
rts
: sec
rts
-; ------------------------------------------------------------------------
-
- .code
-
; Setup RESET vector
reset: stx SOFTEV
sta SOFTEV+1
zpsave: .res zpspace
-rvsave: .res 3
-
params: .byte $02 ; Parameter count
intnum: .byte $00 ; Interrupt number
- .addr intrpt ; Interrupt handler
\ No newline at end of file
+ .addr intrpt ; Interrupt handler
+
+; ------------------------------------------------------------------------
+
+ .bss
+
+rvsave: .res 3
cmp #MAX_FDS
bcs error
-
; Convert handle to fdtab slot
.assert .sizeof(FD) = 4, error
asl
;
.export _gotoxy, _gotox
-
.import popa, VTABZ
.include "apple2.inc"
;
.export _gotoy
-
.import VTABZ
.include "apple2.inc"
--- /dev/null
+;
+; Oliver Schmidt, 03.03.2007
+;
+; HOME routine
+;
+
+ .export HOME
+
+ .include "apple2.inc"
+
+ .segment "LOWCODE"
+
+HOME:
+ ; Switch in ROM and call HOME
+ bit $C082
+ jsr $FC58 ; Clear current text screen
+
+ ; Switch in LC bank 2 for R/O and return
+ bit $C080
+ rts
-DIR* __fastcall__ opendir (const char* name)
+DIR* __fastcall__ opendir (register const char* name)
{
- DIR* dir;
+ register DIR* dir;
/* Alloc DIR */
if ((dir = malloc (sizeof (*dir))) == NULL) {
+++ /dev/null
-;
-; Ullrich von Bassewitz, 2004-06-03
-;
-; Rom COUT routine
-;
-
- .export COUT
-
-COUT := $FDED ; Vector to user output routine
-
--- /dev/null
+;
+; Oliver Schmidt, 03.03.2007
+;
+; RDKEY routine
+;
+
+ .export RDKEY
+
+ .include "apple2.inc"
+
+ .segment "LOWCODE"
+
+RDKEY:
+ ; Switch in ROM and call RDKEY
+ bit $C082
+ jsr $FD0C ; Display prompt and read key from user input routine
+
+ ; Switch in LC bank 2 for R/O and return
+ bit $C080
+ rts
-struct dirent* __fastcall__ readdir (DIR* dir)
+struct dirent* __fastcall__ readdir (register DIR* dir)
{
- unsigned char* entry;
+ register unsigned char* entry;
/* Search for the next active directory entry */
do {
-void __fastcall__ rewinddir (DIR* dir)
+void __fastcall__ rewinddir (register DIR* dir)
{
/* Rewind directory file */
if (lseek (dir->fd, 0, SEEK_SET)) {
+++ /dev/null
-;
-; Oliver Schmidt, 30.05.2004
-;
-; Apple2 ROM routines
-;
-
- .export TEXT
- .export HGR2
- .export HGR
- .export HCLR
- .export BKGND
- .export HPOSN
- .export HPLOT
- .export HLIN
- .export HFIND
- .export DRAW
- .export XDRAW
- .export SETHCOL
-
-; Graphics entry points, by cbmnut (applenut??) cbmnut@hushmail.com
-TEXT := $F399 ; Return to text screen
-HGR2 := $F3D8 ; Initialize and clear hi-res page 2.
-HGR := $F3E2 ; Initialize and clear hi-res page 1.
-HCLR := $F3F2 ; Clear the current hi-res screen to black.
-BKGND := $F3F6 ; Clear the current hi-res screen to the
- ; last plotted color (from ($1C).
-HPOSN := $F411 ; Positions the hi-res cursor without
- ; plotting a point.
- ; Enter with (A) = Y-coordinate, and
- ; (Y,X) = X-coordinate.
-HPLOT := $F457 ; Calls HPOSN and tries to plot a dot at
- ; the cursor's position. If you are
- ; trying to plot a non-white color at
- ; a complementary color position, no
- ; dot will be plotted.
-HLIN := $F53A ; Draws a line from the last plotted
- ; point or line destination to:
- ; (X,A) = X-coordinate, and
- ; (Y) = Y-coordinate.
-HFIND := $F5CB ; Converts the hi-res coursor's position
- ; back to X- and Y-coordinates; stores
- ; X-coordinate at $E0,E1 and Y-coordinate
- ; at $E2.
-DRAW := $F601 ; Draws a shape. Enter with (Y,X) = the
- ; address of the shape table, and (A) =
- ; the rotation factor. Uses the current
- ; color.
-XDRAW := $F65D ; Draws a shape by inverting the existing
- ; color of the dots the shape draws over.
- ; Same entry parameters as DRAW.
-SETHCOL := $F6EC ; Set the hi-res color to (X), where (X)
- ; must be between 0 and 7.
-
+++ /dev/null
-;
-; Ullrich von Bassewitz, 2004-06-03
-;
-; Rom PREAD routine
-;
-
- .export PREAD
-
-PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
-
+++ /dev/null
-;
-; Ullrich von Bassewitz, 2004-06-03
-;
-; Rom RDKEY routine
-;
-
- .export RDKEY
-
-RDKEY := $FD0C ; Display prompt and read key from user input routine
-
+++ /dev/null
-;
-; Ullrich von Bassewitz, 2004-06-03
-;
-; Rom VTABZ routine
-;
-
- .export VTABZ
-
-VTABZ := $FC24 ; Generate text base address
; BEWARE: The current implementation of tgi_map_mode does not work with tables
; larger that 255 bytes!
-.rodata
+ .rodata
_tgi_mode_table:
.ifdef __APPLE2ENH__
- .byte TGI_MODE_280_192_6, "A2E.HI.TGI", 0
- .byte TGI_MODE_40_40_16, "A2E.LO.TGI", 0
-; .byte TGI_MODE_560_192_2, "A2E.DHI.TGI", 0
+ .byte TGI_MODE_280_192_8, "A2E.HI.TGI", 0
+ .byte TGI_MODE_40_48_16, "A2E.LO.TGI", 0
.else
- .byte TGI_MODE_280_192_6, "A2.HI.TGI", 0
- .byte TGI_MODE_40_40_16, "A2.LO.TGI", 0
-; .byte TGI_MODE_560_192_2, "A2.DHI.TGI", 0
+ .byte TGI_MODE_280_192_8, "A2.HI.TGI", 0
+ .byte TGI_MODE_40_48_16, "A2.LO.TGI", 0
.endif
- .byte 0 ; End marker
+ .byte 0 ; End marker
--- /dev/null
+;
+; Oliver Schmidt, 03.03.2007
+;
+; VTABZ routine
+;
+
+ .export VTABZ
+
+ .include "apple2.inc"
+
+ .segment "LOWCODE"
+
+VTABZ:
+ ; Switch in ROM and call VTABZ
+ bit $C082
+ jsr $FC24 ; Generate text base address
+
+ ; Switch in LC bank 2 and return
+ bit $C080
+ rts
close.o \
clrscr.o \
color.o \
+ cout.o \
cputc.o \
crt0.o \
ctype.o \
get_ostype.o \
gotoxy.o \
gotoy.o \
+ home.o \
initcwd.o \
joy_stddrv.o \
kbhit.o \
oserrlist.o \
oserror.o \
randomize.o \
- rcout.o \
+ rdkey.o \
read.o \
revers.o \
- rhome.o \
- rom.o \
- rpread.o \
- rrdkey.o \
- rvtabz.o \
rwcommon.o \
syschdir.o \
sysmkdir.o \
sysuname.o \
textframe.o \
tgi_mode_table.o\
+ vtabz.o \
wherex.o \
wherey.o \
write.o
#--------------------------------------------------------------------------
# Drivers
-EMDS = apple2-auxmem.emd apple2-lc.emd
+EMDS = apple2-auxmem.emd
JOYS = apple2-stdjoy.joy
SERS = apple2-ssc.ser
-TGIS = apple2-40-40-16.tgi apple2-280-192-6.tgi
+TGIS = apple2-280-192-8.tgi apple2-40-48-16.tgi
#--------------------------------------------------------------------------
# Targets
hello: $(CRT0) hello.o $(CLIB)
@$(LD) -t $(SYS) -m $(basename $@).map -o $@ $^
-# The apple machines need the start address adjusted for the mandelbrot demo
+# The Apple machines need the start address adjusted for the mandelbrot demo
ifeq "$(SYS)" "apple2"
mandelbrot: $(CRT0) mandelbrot.o $(CLIB)
@$(LD) -t $(SYS) -m $(basename $@).map --start-addr 0x4000 -o $@ $^
sieve: $(CRT0) sieve.o $(CLIB)
@$(LD) -t $(SYS) -m $(basename $@).map -o $@ $^
-# The apple machines need the start address adjusted for the tgidemo
+# The Apple machines need the start address adjusted for the tgidemo
ifeq "$(SYS)" "apple2"
tgidemo: $(CRT0) tgidemo.o $(CLIB)
@$(LD) -t $(SYS) -m $(basename $@).map --start-addr 0x4000 -o $@ $^
/* Graphics definitions */
#if defined(__APPLE2__) || defined(__APPLE2ENH__)
-# define GRAPHMODE TGI_MODE_280_192_6
+# define GRAPHMODE TGI_MODE_280_192_8
#else
# define GRAPHMODE TGI_MODE_320_200_2
#endif
-#define SCREEN_X (tgi_getmaxx()+1)
-#define SCREEN_Y (tgi_getmaxy()+1)
-#define MAXCOL (tgi_getmaxcolor()+1)
+#define SCREEN_X (tgi_getxres())
+#define SCREEN_Y (tgi_getyres())
+#define MAXCOL (tgi_getcolorcount())
#define maxiterations 32
#define fpshift (10)
#if defined(__APPLE2__) || defined(__APPLE2ENH__)
-# define TGI_MODE TGI_MODE_280_192_6
-# define PAL_BACK 0
-# define PAL_FORE 3
-# define COLOR_LIGHTRED 0 /* Dummy */
+# define TGI_MODE TGI_MODE_280_192_8
#else
-# define TGI_MODE TGI_MODE_320_200_2
-# define PAL_BACK 0
-# define PAL_FORE 1
+# define TGI_MODE TGI_MODE_320_200_2
#endif
+#define COLOR_BACK COLOR_BLACK
+#define COLOR_FORE COLOR_WHITE
/*****************************************************************************/
0x22,0x20,0x1F,0x1E,0x1D,0x1C,0x1B,0x1A,0x19,0x18,
0x17,0x16,0x15,0x14,0x13,0x12,0x12,0x11,0x10,0x10,
0x0F,0x0E,0x0E,0x0D,0x0D,0x0C,0x0C,0x0C,0x0B,0x0B,
- 0x0B,0x0B,0x0B,0x0B,0x0B,0x0A,0x0B,0x0B,0x0B,0x0B,
+ 0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,0x0B,
0x0B,0x0B,0x0B,0x0C,0x0C,0x0C,0x0D,0x0D,0x0E,0x0E,
0x0F,0x10,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x16,
0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,
0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB6,0xB7,0xB8,0xB8,
0xB9,0xBA,0xBA,0xBB,0xBB,0xBC,0xBC,0xBC,0xBD,0xBD,
- 0xBD,0xBD,0xBD,0xBD,0xBD,0xBE,0xBD,0xBD,0xBD,0xBD,
+ 0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,
0xBD,0xBD,0xBD,0xBC,0xBC,0xBC,0xBB,0xBB,0xBA,0xBA,
0xB9,0xB8,0xB8,0xB7,0xB6,0xB6,0xB5,0xB4,0xB3,0xB2,
0xB1,0xB0,0xAF,0xAE,0xAD,0xAC,0xAB,0xAA,0xA9,0xA8,
/* Driver stuff */
-static unsigned XRes;
-static unsigned YRes;
+static unsigned MaxX;
+static unsigned MaxY;
static void DoCircles (void)
{
- static const unsigned char Palette[2] = { COLOR_WHITE, COLOR_LIGHTRED };
+ static const unsigned char Palette[2] = { COLOR_WHITE, COLOR_ORANGE };
unsigned char I;
- unsigned char Color = PAL_FORE;
- unsigned X = XRes / 2;
- unsigned Y = YRes / 2;
+ unsigned char Color = COLOR_FORE;
+ unsigned X = MaxX / 2;
+ unsigned Y = MaxY / 2;
tgi_setpalette (Palette);
while (!kbhit ()) {
- tgi_setcolor (PAL_FORE);
- tgi_line (0, 0, XRes-1, YRes-1);
- tgi_line (0, YRes-1, XRes-1, 0);
+ tgi_setcolor (COLOR_FORE);
+ tgi_line (0, 0, MaxX, MaxY);
+ tgi_line (0, MaxY, MaxX, 0);
tgi_setcolor (Color);
for (I = 10; I < 240; I += 10) {
tgi_circle (X, Y, I);
}
- Color = Color == PAL_FORE ? PAL_BACK : PAL_FORE;
+ Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE;
}
cgetc ();
unsigned char Color;
tgi_setpalette (Palette);
- Color = PAL_BACK;
+ Color = COLOR_BACK;
while (1) {
- for (Y = 0; Y < YRes; Y += 10) {
- for (X = 0; X < XRes; X += 10) {
+ for (Y = 0; Y <= MaxY; Y += 10) {
+ for (X = 0; X <= MaxX; X += 10) {
tgi_setcolor (Color);
tgi_bar (X, Y, X+9, Y+9);
- Color = Color == PAL_FORE ? PAL_BACK : PAL_FORE;
+ Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE;
if (kbhit ()) {
cgetc ();
tgi_clear ();
return;
}
}
- Color = Color == PAL_FORE ? PAL_BACK : PAL_FORE;
+ Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE;
}
- Color = Color == PAL_FORE ? PAL_BACK : PAL_FORE;
+ Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE;
}
}
unsigned X, I;
tgi_setpalette (Palette);
- tgi_setcolor (PAL_FORE);
- tgi_line (10, 10, 10, YRes-10);
- tgi_lineto (XRes-10, YRes-10);
+ tgi_setcolor (COLOR_FORE);
+ tgi_line (10, 10, 10, MaxY-10);
+ tgi_lineto (MaxX-10, MaxY-10);
tgi_line (8, 12, 10, 10);
tgi_lineto (12, 12);
- tgi_line (XRes-12, YRes-12, XRes-10, YRes-10);
- tgi_lineto (XRes-12, YRes-8);
- for (I = 0, X = 10; X < XRes-10; ++X) {
+ tgi_line (MaxX-12, MaxY-12, MaxX-10, MaxY-10);
+ tgi_lineto (MaxX-12, MaxY-8);
+ for (I = 0, X = 10; X < MaxX-10; ++X) {
tgi_setpixel (X, SinusTable[I]);
if (++I >= sizeof (SinusTable)) {
I = 0;
unsigned X;
tgi_setpalette (Palette);
- tgi_setcolor (PAL_FORE);
+ tgi_setcolor (COLOR_FORE);
- for (X = 0; X < YRes; X+=10) {
- tgi_line (0, 0, YRes, X);
- tgi_line (0, 0, X, YRes);
- tgi_line (YRes, YRes, 0, YRes-X);
- tgi_line (YRes, YRes, YRes-X, 0);
+ for (X = 0; X <= MaxY; X += 10) {
+ tgi_line (0, 0, MaxY, X);
+ tgi_line (0, 0, X, MaxY);
+ tgi_line (MaxY, MaxY, 0, MaxY-X);
+ tgi_line (MaxY, MaxY, MaxY-X, 0);
}
cgetc ();
CheckError ("tgi_init");
/* Get stuff from the driver */
- XRes = tgi_getxres ();
- YRes = tgi_getyres ();
+ MaxX = tgi_getmaxx ();
+ MaxY = tgi_getmaxy ();
/* Set the palette, set the border color */
Border = bordercolor (COLOR_BLACK);
FEATURES {
- STARTADDRESS: default = $0800;
+ STARTADDRESS: default = $0803;
}
MEMORY {
- ZP: start = $0080, size = $001A, define = yes;
+ ZP: start = $0080, size = $001A, define = yes;
HEADER: start = $0000, size = $0004, file = %O;
- RAM: start = %S, size = $9600 - %S, file = %O;
+ RAM: start = %S, size = $9600 - %S, file = %O, define = yes;
+ MOVE: start = $0000, size = $FFFF, file = %O, define = yes;
+ LC: start = $D400, size = $0C00, define = yes;
}
SEGMENTS {
- EXEHDR: load = HEADER, type = ro;
- STARTUP: load = RAM, type = ro, define = yes;
- LOWCODE: load = RAM, type = ro, optional = yes;
- INIT: load = RAM, type = ro, define = yes, optional = yes;
- CODE: load = RAM, type = ro;
- RODATA: load = RAM, type = ro;
- DATA: load = RAM, type = rw;
- BSS: load = RAM, type = bss, define = yes;
- HEAP: load = RAM, type = bss, optional = yes; # must sit just below stack
- ZEROPAGE: load = ZP, type = zp;
+ ZEROPAGE: load = ZP, type = zp;
+ EXEHDR: load = HEADER, type = ro;
+ STARTUP: load = RAM, type = ro;
+ LOWCODE: load = RAM, type = ro;
+ CODE: load = RAM, type = ro;
+ RODATA: load = RAM, type = ro;
+ DATA: load = RAM, type = rw;
+ BSS: load = RAM, type = bss, define = yes;
+ INIT: load = MOVE, run = RAM, type = ro, define = yes;
+ HIGHCODE: load = MOVE, run = LC, type = ro, optional = yes;
}
FEATURES {
CONDES: segment = INIT,
- type = constructor,
- label = __CONSTRUCTOR_TABLE__,
- count = __CONSTRUCTOR_COUNT__;
+ type = constructor,
+ label = __CONSTRUCTOR_TABLE__,
+ count = __CONSTRUCTOR_COUNT__;
CONDES: segment = RODATA,
- type = destructor,
- label = __DESTRUCTOR_TABLE__,
- count = __DESTRUCTOR_COUNT__;
+ type = destructor,
+ label = __DESTRUCTOR_TABLE__,
+ count = __DESTRUCTOR_COUNT__;
CONDES: type = interruptor,
- segment = RODATA,
- label = __INTERRUPTOR_TABLE__,
- count = __INTERRUPTOR_COUNT__;
+ segment = RODATA,
+ label = __INTERRUPTOR_TABLE__,
+ count = __INTERRUPTOR_COUNT__;
}
SYMBOLS {
- __STACKSIZE__ = $800; # 2K stack
+ __STACKSIZE__ = $0800; # 2k stack
}