- No complex shell logic.
- "Source file shadowing" for all targets via vpath.
- Dependency handling.
- True incremental build.
- Don't write into source directories.
- Easy cleanup by just removing 'wrk'.
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = apple2
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-mou.o: %.mou
- @$(CO) -o $(*)-mou.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-mou.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS= closedir.o \
- opendir.o \
- readdir.o \
- rewinddir.o
-
-S_OBJS= _scrsize.o \
- break.o \
- cclear.o \
- cgetc.o \
- chline.o \
- close.o \
- clrscr.o \
- color.o \
- cout.o \
- cputc.o \
- crt0.o \
- ctype.o \
- curdevice.o \
- cvline.o \
- devicedir.o \
- dioclose.o \
- diocommon.o \
- dioopen.o \
- dioread.o \
- diosectcount.o \
- diosectsize.o \
- diowrite.o \
- dosdetect.o \
- exec.o \
- exehdr.o \
- filedes.o \
- filename.o \
- get_ostype.o \
- getdevice.o \
- gotoxy.o \
- gotoy.o \
- home.o \
- initcwd.o \
- iobuf.o \
- irq.o \
- isdevice.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- mainargs.o \
- mcbdefault.o \
- mli.o \
- mouse_stat_stddrv.o \
- mouse_stddrv.o \
- open.o \
- oserrlist.o \
- oserror.o \
- randomize.o \
- rdkey.o \
- read.o \
- reboot.o \
- revers.o \
- rwcommon.o \
- syschdir.o \
- sysmkdir.o \
- sysremove.o \
- sysrename.o \
- sysrmdir.o \
- systime.o \
- sysuname.o \
- tgi_colors.o \
- tgi_stat_stddrv.o \
- tgi_stddrv.o \
- toascii.o \
- vtabz.o \
- wherex.o \
- wherey.o \
- write.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(MOUS:.mou=-mou.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-S_EXTRA_OBJS= \
- extra/iobuf-0800.o
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS = apple2-auxmem.emd
-
-JOYS = apple2-stdjoy.joy
-
-MOUS = apple2-stdmou.mou
-
-SERS = apple2-ssc.ser
-
-TGIS = apple2-280-192-8.tgi apple2-40-48-16.tgi
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS) $(S_EXTRA_OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS) $(S_EXTRA_OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(MOUS:.mou=.o) $(MOUS:.mou=-mou.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
+++ /dev/null
-;
-; Graphics driver for the 280x192x8 mode on the Apple II
-;
-; Stefan Haubenthal <polluks@sdf.lonestar.org>
-; Oliver Schmidt <ol.sc@web.de>
-;
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
- .include "apple2.inc"
-
-; ------------------------------------------------------------------------
-
-; 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
-
-; ------------------------------------------------------------------------
-
- .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
- .word 280 ; X resolution
- .word 192 ; Y resolution
- .byte 8 ; Number of drawing colors
-pages: .byte 2 ; Number of screens available
- .byte 7 ; System font X size
- .byte 8 ; System font Y size
- .word $00EA ; Aspect ratio (based on 4/3 display)
- .byte 0 ; TGI driver flags
-
-; Next comes the jump table. With the exception of IRQ, 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 TEXTSTYLE
- .addr OUTTEXT
- .addr 0 ; IRQ entry is unused
-
-; ------------------------------------------------------------------------
-
- .bss
-
-; Absolute variables used in the code
-
-ERROR: .res 1 ; Error code
-
-; ------------------------------------------------------------------------
-
- .rodata
-
-; Constants and tables
-
-DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
-
-FONT:
- ; Beagle Bros Shape Mechanic font F.ASCII.SMALL
- ; modified to exactly reproduce the text glyphs
- .incbin "../apple2/apple2-280-192-8.fnt"
-
-; ------------------------------------------------------------------------
-
- .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:
- .ifdef __APPLE2ENH__
- ; No page switching if 80 column store is enabled
- bit RD80COL
- bpl :+
- lda #$01
- sta pages
-: .endif
-
- ; 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
-
-; 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 MIXCLR
- bit HIRES
- bit TXTCLR
-
- ; Beagle Bros Shape Mechanic fonts don't
- ; scale well so use fixed scaling factor
- lda #$01
- sta SCALE
-
- ; 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:
- ; Switch into text mode
- bit TXTSET
- bit LOWSCR
-
- .ifdef __APPLE2ENH__
- ; Limit SET80COL-HISCR to text
- bit LORES
- .endif
-
- ; Reset the text window top
- lda #$00
- sta WNDTOP
- rts
-
-; GETERROR: Return the error code in A and clear it.
-GETERROR:
- lda ERROR
- ldx #TGI_ERR_OK
- stx ERROR
- rts
-
-; CONTROL: Platform/driver specific entry point.
-; Must set an error code: YES
-CONTROL:
- ; Check data msb and code to be 0
- ora ptr1+1
- bne err
-
- ; Check data lsb to be [0..1]
- lda ptr1
- cmp #1+1
- bcs err
-
- ; Set text window top
- tax
- beq :+
- lda #20
-: sta WNDTOP
-
- ; Switch 4 lines of text
- .assert MIXCLR + 1 = MIXSET, error
- lda MIXCLR,x ; No BIT absolute,X available
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- beq :+ ; Branch always
-
- ; Done, set the error code
-err: lda #TGI_ERR_INV_ARG
-: sta 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
-
-; 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
-
-; 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
-
-; 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:
- cmp #TGI_TEXT_VERTICAL
- bne :+
- lda #48
-: 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
- lda X1
- ldy X1+1
- ldx ROT
- php ; Save Z flag
- beq :+ ; Not horizontal
- sec
- sbc #$07 ; Adjust X
- bcs :+
- dey
-: tax
- lda Y1
- plp ; Restore Z flag
- bne :+ ; Not vertical
- sec
- sbc #$07 ; Adjust Y
-: jsr HPOSN
- clc
- lda FONT+2*99 ; "connection char"
- adc #<FONT
- sta ptr4
- lda FONT+2*99+1 ; "connection char"
- adc #>FONT
- sta ptr4+1
- ldy #$00
-: lda (ptr3),y
- beq :+
- sty tmp1 ; Save string index
- sec
- sbc #$1F ; No control chars
- asl ; Offset * 2
- tay
- clc
- lda FONT,y
- adc #<FONT
- tax
- lda FONT+1,y
- adc #>FONT
- tay
- lda ROT
- jsr DRAW ; Draw char from string
- ldx ptr4
- ldy ptr4+1
- lda ROT
- jsr DRAW ; Draw "connection char"
- ldy tmp1 ; Restore string index
- iny
- bne :- ; Branch always
-: bit $C080 ; Switch in LC bank 2 for R/O
- 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>
-;
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
- .include "apple2.inc"
-
-; ------------------------------------------------------------------------
-
-; Zero page stuff
-
-H2 := $2C
-COLOR := $30
-
-; ROM entry points
-
-TEXT := $F399
-PLOT := $F800
-HLINE := $F819
-CLRSC2 := $F838
-SETCOL := $F864
-SCRN := $F871
-SETGR := $FB40
-HOME := $FC58
-
-; Used for passing parameters to the driver
-
-X1 := ptr1
-Y1 := ptr2
-X2 := ptr3
-Y2 := ptr4
-
-; ------------------------------------------------------------------------
-
- .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
- .word 40 ; X resolution
- .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
- .word $0198 ; Aspect ratio (based on 4/3 display)
- .byte 0 ; TGI driver flags
-
-; Next comes the jump table. With the exception of IRQ, 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 TEXTSTYLE
- .addr OUTTEXT
- .addr 0 ; IRQ entry is unused
-
-; ------------------------------------------------------------------------
-
- .bss
-
-ERROR: .res 1 ; Error code
-MIX: .res 1 ; 4 lines of text
-
-; ------------------------------------------------------------------------
-
- .rodata
-
-DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
- .byte $08, $09, $0A, $0B, $0C, $0D, $0E, $0F
-
-TGI2COL: .byte $00, $0C, $03, $0F, $01, $09, $06, $02
- .byte $04, $05, $07, $08, $0A, $0B, $0D, $0E
-
-COL2TGI: .byte $00, $04, $07, $02, $08, $09, $06, $0A
- .byte $0B, $05, $0C, $0D, $01, $0E, $0F, $03
-
-MAXY: .byte 47, 39
-
-; ------------------------------------------------------------------------
-
- .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
- sta MIX
-
- ; 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
- lda COLOR ; Save current drawing color
- pha
- ldx MIX
- ldy MAXY,x ; Max Y depends on 4 lines of text
- jsr CLRSC2
- pla
- sta COLOR ; Restore current drawing color
- 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
- tax
- lda TGI2COL,x
- 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:
- ; Check data msb and code to be 0
- ora ptr1+1
- bne err
-
- ; Check data lsb to be [0..1]
- lda ptr1
- cmp #1+1
- bcs err
- bit $C082 ; Switch in ROM
-
- ; Switch 4 lines of text
- tax
- .assert MIXCLR + 1 = MIXSET, error
- lda MIXCLR,x ; No BIT absolute,X available
-
- ; Save current switch setting
- txa
- sta MIX
- bne text
-
- ; Clear 8 lines of graphics
- lda COLOR ; Save current drawing color
- pha
- lda #39 ; Rightmost column
- sta H2
- ldx #40 ; First line
-: txa
- ldy #$00 ; Leftmost column
- sty COLOR ; Black
- jsr HLINE ; Preserves X
- inx
- cpx #47+1 ; Last line
- bcc :-
- pla
- sta COLOR ; Restore current drawing color
- bcs :+ ; Branch always
-
- ; Clear 4 lines of text
-text: jsr HOME
-: bit $C080 ; Switch in LC bank 2 for R/O
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- beq :+ ; Branch always
-
- ; Done, set the error code
-err: lda #TGI_ERR_INV_ARG
-: sta ERROR
- rts
-
-; 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
-
-; 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
- tax
- lda COL2TGI,x
- ldx #$00
- 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:
- bit $C082 ; Switch in ROM
- lda X2
- sta H2
- inc Y2
- ldx Y1
-: txa
- ldy X1
- jsr HLINE ; Preserves X
- inx
- cpx Y2
- bcc :-
- bit $C080 ; Switch in LC bank 2 for R/O
- rts
-
-; ------------------------------------------------------------------------
-
-.include "../tgi/tgidrv_line.inc"
+++ /dev/null
-;
-; Extended memory driver for the Apple II auxiliary memory
-;
-; Stefan Haubenthal, 2003-12-12
-; Ullrich von Bassewitz, 2002-12-02
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word DEINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-BASE = $0200
-AUXCARD = $C30C ; Card signature
-AUXMOVE = $C311 ; Auxiliary move routine
-PAGES = ($C000 - BASE) / 256
-
-; ------------------------------------------------------------------------
-; Data.
-
-.data
-curpage: .byte $FF ; Current page number (invalid)
-
-.bss
-window: .res 256 ; Memory "window"
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx #0
- lda AUXCARD
- and #$f0
- cmp #$80
- bne @L1
- lda #EM_ERR_OK
- rts
-@L1: lda #EM_ERR_NO_DEVICE
-; rts
-
-; ------------------------------------------------------------------------
-; DEINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-DEINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda #<PAGES
- ldx #>PAGES
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage ; Remember the new page
-
- clc
- adc #>BASE
- sta ptr1+1
- ldy #$00
- sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
-; Transfer one page
-
- clc ; Direction flag
- jsr transfer ; Transfer one page
-
-; Return the memory window
-
- lda #<window
- ldx #>window ; Return the window address
-
-; Done
-
-done: rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage ; Get the current page
- cmp #$FF
- beq done ; Jump if no page mapped
-
- clc
- adc #>BASE
- sta ptr2+1
- ldy #$00
- sty ptr2
-
- lda #<window
- sta ptr1
- lda #>window
- sta ptr1+1
- lda #<$FF
- sta ptr4
- lda #>$FF
- sta ptr4+1
- sec ; Direction flag
-
-; Transfer one page/all bytes
-
-transfer:
- php
- clc
- lda ptr1
- sta $3C
- adc ptr4
- sta $3E
- lda ptr1+1
- sta $3D
- adc ptr4+1
- sta $3F
- lda ptr2
- sta $42
- lda ptr2+1
- sta $43
- plp
- jmp AUXMOVE
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- clc
- adc #>BASE
- sta ptr1+1 ; From
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; To
- clc ; Direction flag
-
-common: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- sta ptr4
- iny
- lda (ptr3),y ; Get number of pages
- sta ptr4+1
-
- jmp transfer
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO: sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr2
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- clc
- adc #>BASE
- sta ptr2+1 ; To
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr1
- iny
- lda (ptr3),y
- sta ptr1+1 ; From
-
- sec ; Direction flag
- jmp common
+++ /dev/null
-;
-; Serial driver for the Apple II Super Serial Card.
-;
-; Oliver Schmidt, 21.04.2005
-;
-; The driver is based on the cc65 rs232 module, which in turn is based on
-; Craig Bruce device driver for the Switftlink/Turbo-232.
-;
-; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
-;
-; This software is Public Domain. It is in Buddy assembler format.
-;
-; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
-; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
-; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
-; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
-;
-; The code assumes that the kernal + I/O are in context. On the C128, call
-; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
-; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
-; interrupt handling assumes that the 65816 is in 6502-emulation mode.
-;
-
- .include "zeropage.inc"
- .include "ser-kernel.inc"
- .include "ser-error.inc"
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
- .segment "JUMPTABLE"
-
- ; Driver signature
- .byte $73, $65, $72 ; "ser"
- .byte SER_API_VERSION ; Serial API version number
-
- ; Jump table.
- .addr INSTALL
- .addr UNINSTALL
- .addr OPEN
- .addr CLOSE
- .addr GET
- .addr PUT
- .addr STATUS
- .addr IOCTL
- .addr IRQ
-
-;----------------------------------------------------------------------------
-; I/O definitions
-
-ACIA = $C088
-ACIA_DATA = ACIA+0 ; Data register
-ACIA_STATUS = ACIA+1 ; Status register
-ACIA_CMD = ACIA+2 ; Command register
-ACIA_CTRL = ACIA+3 ; Control register
-
-;----------------------------------------------------------------------------
-; Global variables
-
- .bss
-
-RecvHead: .res 1 ; Head of receive buffer
-RecvTail: .res 1 ; Tail of receive buffer
-RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
-SendHead: .res 1 ; Head of send buffer
-SendTail: .res 1 ; Tail of send buffer
-SendFreeCnt: .res 1 ; Number of bytes in send buffer
-
-Stopped: .res 1 ; Flow-stopped flag
-RtsOff: .res 1 ;
-
-RecvBuf: .res 256 ; Receive buffers: 256 bytes
-SendBuf: .res 256 ; Send buffers: 256 bytes
-
-Index: .res 1 ; I/O register index
-
- .data
-
-Slot: .byte $02 ; Default to SSC in slot 2
-
- .rodata
-
- ; Tables used to translate RS232 params into register values
-BaudTable: ; bit7 = 1 means setting is invalid
- .byte $FF ; SER_BAUD_45_5
- .byte $01 ; SER_BAUD_50
- .byte $02 ; SER_BAUD_75
- .byte $03 ; SER_BAUD_110
- .byte $04 ; SER_BAUD_134_5
- .byte $05 ; SER_BAUD_150
- .byte $06 ; SER_BAUD_300
- .byte $07 ; SER_BAUD_600
- .byte $08 ; SER_BAUD_1200
- .byte $09 ; SER_BAUD_1800
- .byte $0A ; SER_BAUD_2400
- .byte $0B ; SER_BAUD_3600
- .byte $0C ; SER_BAUD_4800
- .byte $0D ; SER_BAUD_7200
- .byte $0E ; SER_BAUD_9600
- .byte $0F ; SER_BAUD_19200
- .byte $FF ; SER_BAUD_38400
- .byte $FF ; SER_BAUD_57600
- .byte $FF ; SER_BAUD_115200
- .byte $FF ; SER_BAUD_230400
-BitTable:
- .byte $60 ; SER_BITS_5
- .byte $40 ; SER_BITS_6
- .byte $20 ; SER_BITS_7
- .byte $00 ; SER_BITS_8
-StopTable:
- .byte $00 ; SER_STOP_1
- .byte $80 ; SER_STOP_2
-ParityTable:
- .byte $00 ; SER_PAR_NONE
- .byte $20 ; SER_PAR_ODD
- .byte $60 ; SER_PAR_EVEN
- .byte $A0 ; SER_PAR_MARK
- .byte $E0 ; SER_PAR_SPACE
-IdOfsTable:
- .byte $05 ; Pascal 1.0 ID byte
- .byte $07 ; Pascal 1.0 ID byte
- .byte $0B ; Pascal 1.1 generic signature byte
- .byte $0C ; Device signature byte
-IdValTable:
- .byte $38 ; Fixed
- .byte $18 ; Fixed
- .byte $01 ; Fixed
- .byte $31 ; Serial or parallel I/O card type 1
-
-IdTableLen = * - IdValTable
-
- .code
-
-;----------------------------------------------------------------------------
-; INSTALL: Is called after the driver is loaded into memory. If possible,
-; check if the hardware is present. Must return an SER_ERR_xx code in a/x.
-;
-; Since we don't have to manage the IRQ vector on the Apple II, this is
-; actually the same as:
-;
-; UNINSTALL: Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-;
-; and:
-;
-; CLOSE: Close the port and disable interrupts. Called without parameters.
-; Must return an SER_ERR_xx code in a/x.
-
-INSTALL:
-UNINSTALL:
-CLOSE:
- ldx Index ; Check for open port
- beq :+
-
- ; Deactivate DTR and disable 6551 interrupts
- lda #%00001010
- sta ACIA_CMD,x
-
- ; Done, return an error code
-: lda #<SER_ERR_OK
- tax ; A is zero
- stx Index ; Mark port as closed
- rts
-
-;----------------------------------------------------------------------------
-; OPEN: A pointer to a ser_params structure is passed in ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-OPEN:
- ldx #<$C000
- stx ptr2
- lda #>$C000
- ora Slot
- sta ptr2+1
-
- ; Check Pascal 1.1 Firmware Protocol ID bytes
-: ldy IdOfsTable,x
- lda IdValTable,x
- cmp (ptr2),y
- bne NoDevice
- inx
- cpx #IdTableLen
- bcc :-
-
- ; Convert slot to I/O register index
- lda Slot
- asl
- asl
- asl
- asl
- tax
-
- ; Check if the handshake setting is valid
- ldy #SER_PARAMS::HANDSHAKE ; Handshake
- lda (ptr1),y
- cmp #SER_HS_HW ; This is all we support
- bne InvParam
-
- ; Initialize buffers
- ldy #$00
- sty Stopped
- sty RecvHead
- sty RecvTail
- sty SendHead
- sty SendTail
- dey ; Y = 255
- sty RecvFreeCnt
- sty SendFreeCnt
-
- ; Set the value for the control register, which contains stop bits,
- ; word length and the baud rate.
- ldy #SER_PARAMS::BAUDRATE
- lda (ptr1),y ; Baudrate index
- tay
- lda BaudTable,y ; Get 6551 value
- bmi InvBaud ; Branch if rate not supported
- sta tmp1
-
- ldy #SER_PARAMS::DATABITS ; Databits
- lda (ptr1),y
- tay
- lda BitTable,y
- ora tmp1
- sta tmp1
-
- ldy #SER_PARAMS::STOPBITS ; Stopbits
- lda (ptr1),y
- tay
- lda StopTable,y
- ora tmp1
- ora #%00010000 ; Receiver clock source = baudrate
- sta ACIA_CTRL,x
-
- ; Set the value for the command register. We remember the base value
- ; in RtsOff, since we will have to manipulate ACIA_CMD often.
- ldy #SER_PARAMS::PARITY ; Parity
- lda (ptr1),y
- tay
- lda ParityTable,y
- ora #%00000001 ; DTR active
- sta RtsOff
- ora #%00001000 ; Enable receive interrupts
- sta ACIA_CMD,x
-
- ; Done
- stx Index ; Mark port as open
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
- ; Device (hardware) not found
-NoDevice:lda #<SER_ERR_NO_DEVICE
- ldx #>SER_ERR_NO_DEVICE
- rts
-
- ; Invalid parameter
-InvParam:lda #<SER_ERR_INIT_FAILED
- ldx #>SER_ERR_INIT_FAILED
- rts
-
- ; Baud rate not available
-InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
- ldx #>SER_ERR_BAUD_UNAVAIL
- rts
-
-;----------------------------------------------------------------------------
-; GET: Will fetch a character from the receive buffer and store it into the
-; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
-; returned.
-
-GET:
- ldx Index
- ldy SendFreeCnt ; Send data if necessary
- iny ; Y == $FF?
- beq :+
- lda #$00 ; TryHard = false
- jsr TryToSend
-
- ; Check for buffer empty
-: lda RecvFreeCnt ; (25)
- cmp #$FF
- bne :+
- lda #<SER_ERR_NO_DATA
- ldx #>SER_ERR_NO_DATA
- rts
-
- ; Check for flow stopped & enough free: release flow control
-: ldy Stopped ; (34)
- beq :+
- cmp #63
- bcc :+
- lda #$00
- sta Stopped
- lda RtsOff
- ora #%00001000
- sta ACIA_CMD,x
-
- ; Get byte from buffer
-: ldy RecvHead ; (41)
- lda RecvBuf,y
- inc RecvHead
- inc RecvFreeCnt
- ldx #$00 ; (59)
- sta (ptr1,x)
- txa ; Return code = 0
- rts
-
-;----------------------------------------------------------------------------
-; PUT: Output character in A.
-; Must return an SER_ERR_xx code in a/x.
-
-PUT:
- ldx Index
-
- ; Try to send
- ldy SendFreeCnt
- iny ; Y = $FF?
- beq :+
- pha
- lda #$00 ; TryHard = false
- jsr TryToSend
- pla
-
- ; Put byte into send buffer & send
-: ldy SendFreeCnt
- bne :+
- lda #<SER_ERR_OVERFLOW
- ldx #>SER_ERR_OVERFLOW
- rts
-
-: ldy SendTail
- sta SendBuf,y
- inc SendTail
- dec SendFreeCnt
- lda #$FF ; TryHard = true
- jsr TryToSend
- lda #<SER_ERR_OK
- tax
- rts
-
-;----------------------------------------------------------------------------
-; STATUS: Return the status in the variable pointed to by ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-STATUS:
- ldx Index
- lda ACIA_STATUS,x
- ldx #$00
- sta (ptr1,x)
- txa ; SER_ERR_OK
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an SER_ERR_xx code in a/x.
-
-IOCTL:
- ; Check data msb and code to be 0
- ora ptr1+1
- bne :+
-
- ; Check data lsb to be [1..7]
- ldx ptr1
- beq :+
- cpx #7+1
- bcs :+
-
- stx Slot
- tax ; SER_ERR_OK
- rts
-
-: lda #<SER_ERR_INV_IOCTL
- ldx #>SER_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
-; registers are already saved, no parameters are passed, but the carry flag
-; is clear on entry. The routine must return with carry set if the interrupt
-; was handled, otherwise with carry clear.
-
-IRQ:
- ldx Index ; Check for open port
- beq Done
- lda ACIA_STATUS,x ; Check ACIA status for receive interrupt
- and #$08
- beq Done ; Jump if no ACIA interrupt
- lda ACIA_DATA,x ; Get byte from ACIA
- ldy RecvFreeCnt ; Check if we have free space left
- beq Flow ; Jump if no space in receive buffer
- ldy RecvTail ; Load buffer pointer
- sta RecvBuf,y ; Store received byte in buffer
- inc RecvTail ; Increment buffer pointer
- dec RecvFreeCnt ; Decrement free space counter
- ldy RecvFreeCnt ; Check for buffer space low
- cpy #33
- bcc Flow ; Assert flow control if buffer space low
- rts ; Interrupt handled (carry already set)
-
- ; Assert flow control if buffer space too low
-Flow: lda RtsOff
- sta ACIA_CMD,x
- sta Stopped
- sec ; Interrupt handled
-Done: rts
-
-;----------------------------------------------------------------------------
-; Try to send a byte. Internal routine. A = TryHard
-
-TryToSend:
- sta tmp1 ; Remember tryHard flag
-Again: lda SendFreeCnt
- cmp #$FF
- beq Quit ; Bail out
-
- ; Check for flow stopped
- lda Stopped
- bne Quit ; Bail out
-
- ; Check that ACIA is ready to send
- lda ACIA_STATUS,x
- and #$10
- bne Send
- bit tmp1 ; Keep trying if must try hard
- bmi Again
-Quit: rts
-
- ; Send byte and try again
-Send: ldy SendHead
- lda SendBuf,y
- sta ACIA_DATA,x
- inc SendHead
- inc SendFreeCnt
- jmp Again
+++ /dev/null
-;
-; 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
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "apple2.inc"
-
-; ------------------------------------------------------------------------
-
-; Constants
-
-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"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $10
- .byte $20
- .byte $04
- .byte $08
- .byte $40
- .byte $80
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READJOY
- .addr 0 ; IRQ not used
-
-; ------------------------------------------------------------------------
-
- .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
- ; 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 #$02 ; Number of joysticks we support
- ldx #$00
- rts
-
-; READ: Read a particular joystick passed in A.
-READJOY:
- 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
- inx ; Set paddle number (1, 3)
- jsr PREAD ; Read paddle value
- pla
- 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
+++ /dev/null
-;
-; Driver for the AppleMouse II Card.
-;
-; Oliver Schmidt, 03.09.2005
-;
-
- .include "zeropage.inc"
- .include "mouse-kernel.inc"
- .include "apple2.inc"
-
-; ------------------------------------------------------------------------
-
-SETMOUSE = $12 ; Sets mouse mode
-SERVEMOUSE = $13 ; Services mouse interrupt
-READMOUSE = $14 ; Reads mouse position
-CLEARMOUSE = $15 ; Clears mouse position to 0 (for delta mode)
-POSMOUSE = $16 ; Sets mouse position to a user-defined pos
-CLAMPMOUSE = $17 ; Sets mouse bounds in a window
-HOMEMOUSE = $18 ; Sets mouse to upper-left corner of clamp win
-INITMOUSE = $19 ; Resets mouse clamps to default values and
- ; sets mouse position to 0,0
-
-pos1_lo := $0478
-pos1_hi := $0578
-pos2_lo := $04F8
-pos2_hi := $05F8
-status := $0778
-
-; ------------------------------------------------------------------------
-
- .segment "JUMPTABLE"
-
- ; Driver signature
- .byte $6D, $6F, $75 ; "mou"
- .byte MOUSE_API_VERSION ; Mouse driver API version number
-
- ; Jump table.
- .addr INSTALL
- .addr UNINSTALL
- .addr HIDE
- .addr SHOW
- .addr SETBOX
- .addr GETBOX
- .addr MOVE
- .addr BUTTONS
- .addr POS
- .addr INFO
- .addr IOCTL
- .addr IRQ
-
- ; Mouse driver flags
- .byte MOUSE_FLAG_EARLY_IRQ
-
- ; Callback table, set by the kernel before INSTALL is called
-CHIDE: jmp $0000 ; Hide the cursor
-CSHOW: jmp $0000 ; Show the cursor
-CMOVEX: jmp $0000 ; Move the cursor to X coord
-CMOVEY: jmp $0000 ; Move the cursor to Y coord
-
-; ------------------------------------------------------------------------
-
- .bss
-
-box: .tag MOUSE_BOX
-info: .tag MOUSE_INFO
-slot: .res 1
-visible:.res 1
-
-; ------------------------------------------------------------------------
-
- .rodata
-
-offsets:.byte $05 ; Pascal 1.0 ID byte
- .byte $07 ; Pascal 1.0 ID byte
- .byte $0B ; Pascal 1.1 generic signature byte
- .byte $0C ; Device signature byte
-
-values: .byte $38 ; Fixed
- .byte $18 ; Fixed
- .byte $01 ; Fixed
- .byte $20 ; X-Y pointing device type 0
-
-size = * - values
-
-inibox: .word 0 ; MinX
- .word 0 ; MinY
- .word 279 ; MaxX
- .word 191 ; MaxY
-
-; ------------------------------------------------------------------------
-
- .data
-
-firmware:
- ; Lookup and patch firmware address lobyte
-lookup: ldy $FF00,x ; Patched at runtime
- sty jump+1 ; Modify code below
-
- ; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse:
- ; "Enter all mouse routines (...) with the X register set to $Cn
- ; and Y register set to $n0, where n = the slot number."
-xparam: ldx #$FF ; Patched at runtime
-yparam: ldy #$FF ; Patched at runtime
-
-jump: jmp $FFFF ; Patched at runtime
-
-; ------------------------------------------------------------------------
-
- .code
-
-; INSTALL: Is called after the driver is loaded into memory. If possible,
-; check if the hardware is present. Must return an MOUSE_ERR_xx code in A/X.
-INSTALL:
- lda #<$C000
- sta ptr1
- lda #>$C000
- sta ptr1+1
-
- ; Search for AppleMouse II firmware in slots 1 - 7
-next: inc ptr1+1
- lda ptr1+1
- cmp #>$C800
- bcc :+
-
- ; Mouse firmware not found
- lda #<MOUSE_ERR_NO_DEVICE
- ldx #>MOUSE_ERR_NO_DEVICE
- rts
-
- ; Check Pascal 1.1 Firmware Protocol ID bytes
-: ldx #size - 1
-: ldy offsets,x
- lda values,x
- cmp (ptr1),y
- bne next
- dex
- bpl :-
-
- ; Get and patch firmware address hibyte
- lda ptr1+1
- sta lookup+2
- sta xparam+1
- sta jump+2
-
- ; Disable interrupts now because setting the slot number makes
- ; the IRQ handler (maybe called due to some non-mouse IRQ) try
- ; calling the firmware which isn't correctly set up yet
- sei
-
- ; Convert to and save slot number
- and #$0F
- sta slot
-
- ; Convert to and patch I/O register index
- asl
- asl
- asl
- asl
- sta yparam+1
-
- ; The AppleMouse II Card needs the ROM switched in
- ; to be able to detect an Apple //e and use RDVBL
- bit $C082
-
- ; Reset mouse hardware
- ldx #INITMOUSE
- jsr firmware
-
- ; Switch in LC bank 2 for R/O
- bit $C080
-
- ; Turn mouse on
- lda #%00000001
- ldx #SETMOUSE
- jsr firmware
-
- ; Set initial mouse clamps
- lda #<inibox
- ldx #>inibox
- jsr SETBOX
-
- ; Set initial mouse position
- ldx slot
- lda #<(279 / 2)
- sta pos1_lo,x
- lda #>(279 / 2)
- sta pos1_hi,x
- lda #<(191 / 2)
- sta pos2_lo,x
- lda #>(191 / 2)
- sta pos2_hi,x
- ldx #POSMOUSE
- jsr firmware
-
- ; Update cursor
- jsr update
-
- ; Turn VBL interrupt on
- lda #%00001001
- ldx #SETMOUSE
-common: jsr firmware
-
- ; Enable interrupts and return success
- cli
- lda #<MOUSE_ERR_OK
- ldx #>MOUSE_ERR_OK
- rts
-
-; UNINSTALL: Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-UNINSTALL:
- ; Hide cursor
- sei
- jsr CHIDE
-
- ; Turn mouse off
- lda #%00000000
- ldx #SETMOUSE
- bne common ; Branch always
-
-; SETBOX: Set the mouse bounding box. The parameters are passed as they come
-; from the C program, that is, a pointer to a mouse_box struct in A/X.
-; No checks are done if the mouse is currently inside the box, this is the job
-; of the caller. It is not necessary to validate the parameters, trust the
-; caller and save some code here. No return code required.
-SETBOX:
- sta ptr1
- stx ptr1+1
-
- ; Set x clamps
- ldx #$00
- ldy #MOUSE_BOX::MINX
- jsr :+
-
- ; Set y clamps
- ldx #$01
- ldy #MOUSE_BOX::MINY
-
- ; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse:
- ; "Disable interrupts before placing position information in the
- ; screen holes."
-: sei
-
- ; Set low clamp
- lda (ptr1),y
- sta box,y
- sta pos1_lo
- iny
- lda (ptr1),y
- sta box,y
- sta pos1_hi
-
- ; Skip one word
- iny
- iny
-
- ; Set high clamp
- iny
- lda (ptr1),y
- sta box,y
- sta pos2_lo
- iny
- lda (ptr1),y
- sta box,y
- sta pos2_hi
-
- txa
- ldx #CLAMPMOUSE
- bne common ; Branch always
-
-; GETBOX: Return the mouse bounding box. The parameters are passed as they
-; come from the C program, that is, a pointer to a mouse_box struct in A/X.
-GETBOX:
- sta ptr1
- stx ptr1+1
-
- ldy #.sizeof(MOUSE_BOX)-1
-: lda box,y
- sta (ptr1),y
- dey
- bpl :-
- rts
-
-; MOVE: Move the mouse to a new position. The position is passed as it comes
-; from the C program, that is: x on the stack and y in A/X. The C wrapper will
-; remove the parameter from the stack on return.
-; No checks are done if the new position is valid (within the bounding box or
-; the screen). No return code required.
-MOVE:
- ldy slot
- sei
-
- ; Set y
- sta pos2_lo,y
- txa
- sta pos2_hi,y
-
- tya
- tax
- ldy #$00 ; Start at top of stack
-
- ; Set x
- lda (sp),y
- iny
- sta pos1_lo,x
- lda (sp),y
- sta pos1_hi,x
-
- ; Update cursor
- jsr update
-
- ldx #POSMOUSE
- bne common ; Branch always
-
-; HIDE: Is called to hide the mouse cursor. The mouse kernel manages a
-; counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently visible and should get hidden. For most drivers,
-; no special action is required besides hiding the mouse cursor.
-; No return code required.
-HIDE:
- dec visible
- sei
- jsr CHIDE
- cli
- rts
-
-; SHOW: Is called to show the mouse cursor. The mouse kernel manages a
-; counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently hidden and should become visible. For most drivers,
-; no special action is required besides enabling the mouse cursor.
-; No return code required.
-SHOW:
- inc visible
- rts
-
-; BUTTONS: Return the button mask in A/X.
-BUTTONS:
- lda info + MOUSE_INFO::BUTTONS
- ldx #$00
- rts
-
-; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
-; No return code required.
-POS:
- ldy #.sizeof(MOUSE_POS)-1
- bne copy ; Branch always
-
-; INFO: Returns mouse position and current button mask in the MOUSE_INFO
-; struct pointed to by ptr1. No return code required.
-INFO:
- ldy #.sizeof(MOUSE_INFO)-1
-copy: sei
-: lda info,y
- sta (ptr1),y
- dey
- bpl :-
- cli
- rts
-
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an MOUSE_ERR_xx code in A/X.
-IOCTL:
- lda #<MOUSE_ERR_INV_IOCTL
- ldx #>MOUSE_ERR_INV_IOCTL
- rts
-
-; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
-; registers are already saved, no parameters are passed, but the carry flag
-; is clear on entry. The routine must return with carry set if the interrupt
-; was handled, otherwise with carry clear.
-IRQ:
- ; Check for installed mouse
- lda slot
- beq done
-
- ; Check for mouse interrupt
- ldx #SERVEMOUSE
- jsr firmware
- bcc :+
- clc ; Interrupt not handled
-done: rts
-
-: ldx #READMOUSE
- jsr firmware
-
- ; Get status
- ldy slot
- lda status,y
- tax ; Save status
-
- ; Extract button down values
- asl ; C = Button 0 is currently down
- and #%00100000 ; !Z = Button 1 is currently down
-
- ; Set button mask
- beq :+
- lda #MOUSE_BTN_RIGHT
-: bcc :+
- ora #MOUSE_BTN_LEFT
-: sta info + MOUSE_INFO::BUTTONS
-
- ; Check for mouse movement
- txa ; Restore status
- and #%00100000 ; X or Y changed since last READMOUSE
- beq :+
-
- ; Remove the cursor at the old position
-update: jsr CHIDE
-
- ; Get and set the new X position
- ldy slot
- lda pos1_lo,y
- ldx pos1_hi,y
- sta info + MOUSE_POS::XCOORD
- stx info + MOUSE_POS::XCOORD+1
- jsr CMOVEX
-
- ; Get and set the new Y position
- ldy slot
- lda pos2_lo,y
- ldx pos2_hi,y
- sta info + MOUSE_POS::YCOORD
- stx info + MOUSE_POS::YCOORD+1
- jsr CMOVEY
-
- ; Check for visibility
-: lda visible
- beq :+
-
- ; Draw the cursor at the new position
- jsr CSHOW
-: sec ; Interrupt handled
- rts
--- /dev/null
+;
+; Extended memory driver for the Apple II auxiliary memory
+;
+; Stefan Haubenthal, 2003-12-12
+; Ullrich von Bassewitz, 2002-12-02
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word DEINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BASE = $0200
+AUXCARD = $C30C ; Card signature
+AUXMOVE = $C311 ; Auxiliary move routine
+PAGES = ($C000 - BASE) / 256
+
+; ------------------------------------------------------------------------
+; Data.
+
+.data
+curpage: .byte $FF ; Current page number (invalid)
+
+.bss
+window: .res 256 ; Memory "window"
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx #0
+ lda AUXCARD
+ and #$f0
+ cmp #$80
+ bne @L1
+ lda #EM_ERR_OK
+ rts
+@L1: lda #EM_ERR_NO_DEVICE
+; rts
+
+; ------------------------------------------------------------------------
+; DEINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+DEINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda #<PAGES
+ ldx #>PAGES
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage ; Remember the new page
+
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+; Transfer one page
+
+ clc ; Direction flag
+ jsr transfer ; Transfer one page
+
+; Return the memory window
+
+ lda #<window
+ ldx #>window ; Return the window address
+
+; Done
+
+done: rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage ; Get the current page
+ cmp #$FF
+ beq done ; Jump if no page mapped
+
+ clc
+ adc #>BASE
+ sta ptr2+1
+ ldy #$00
+ sty ptr2
+
+ lda #<window
+ sta ptr1
+ lda #>window
+ sta ptr1+1
+ lda #<$FF
+ sta ptr4
+ lda #>$FF
+ sta ptr4+1
+ sec ; Direction flag
+
+; Transfer one page/all bytes
+
+transfer:
+ php
+ clc
+ lda ptr1
+ sta $3C
+ adc ptr4
+ sta $3E
+ lda ptr1+1
+ sta $3D
+ adc ptr4+1
+ sta $3F
+ lda ptr2
+ sta $42
+ lda ptr2+1
+ sta $43
+ plp
+ jmp AUXMOVE
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ clc
+ adc #>BASE
+ sta ptr1+1 ; From
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; To
+ clc ; Direction flag
+
+common: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ sta ptr4
+ iny
+ lda (ptr3),y ; Get number of pages
+ sta ptr4+1
+
+ jmp transfer
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO: sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr2
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ clc
+ adc #>BASE
+ sta ptr2+1 ; To
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr1
+ iny
+ lda (ptr3),y
+ sta ptr1+1 ; From
+
+ sec ; Direction flag
+ jmp common
--- /dev/null
+;
+; 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
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "apple2.inc"
+
+; ------------------------------------------------------------------------
+
+; Constants
+
+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"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $10
+ .byte $20
+ .byte $04
+ .byte $08
+ .byte $40
+ .byte $80
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READJOY
+ .addr 0 ; IRQ not used
+
+; ------------------------------------------------------------------------
+
+ .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
+ ; 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 #$02 ; Number of joysticks we support
+ ldx #$00
+ rts
+
+; READ: Read a particular joystick passed in A.
+READJOY:
+ 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
+ inx ; Set paddle number (1, 3)
+ jsr PREAD ; Read paddle value
+ pla
+ 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
--- /dev/null
+;
+; Driver for the AppleMouse II Card.
+;
+; Oliver Schmidt, 03.09.2005
+;
+
+ .include "zeropage.inc"
+ .include "mouse-kernel.inc"
+ .include "apple2.inc"
+
+; ------------------------------------------------------------------------
+
+SETMOUSE = $12 ; Sets mouse mode
+SERVEMOUSE = $13 ; Services mouse interrupt
+READMOUSE = $14 ; Reads mouse position
+CLEARMOUSE = $15 ; Clears mouse position to 0 (for delta mode)
+POSMOUSE = $16 ; Sets mouse position to a user-defined pos
+CLAMPMOUSE = $17 ; Sets mouse bounds in a window
+HOMEMOUSE = $18 ; Sets mouse to upper-left corner of clamp win
+INITMOUSE = $19 ; Resets mouse clamps to default values and
+ ; sets mouse position to 0,0
+
+pos1_lo := $0478
+pos1_hi := $0578
+pos2_lo := $04F8
+pos2_hi := $05F8
+status := $0778
+
+; ------------------------------------------------------------------------
+
+ .segment "JUMPTABLE"
+
+ ; Driver signature
+ .byte $6D, $6F, $75 ; "mou"
+ .byte MOUSE_API_VERSION ; Mouse driver API version number
+
+ ; Jump table.
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr HIDE
+ .addr SHOW
+ .addr SETBOX
+ .addr GETBOX
+ .addr MOVE
+ .addr BUTTONS
+ .addr POS
+ .addr INFO
+ .addr IOCTL
+ .addr IRQ
+
+ ; Mouse driver flags
+ .byte MOUSE_FLAG_EARLY_IRQ
+
+ ; Callback table, set by the kernel before INSTALL is called
+CHIDE: jmp $0000 ; Hide the cursor
+CSHOW: jmp $0000 ; Show the cursor
+CMOVEX: jmp $0000 ; Move the cursor to X coord
+CMOVEY: jmp $0000 ; Move the cursor to Y coord
+
+; ------------------------------------------------------------------------
+
+ .bss
+
+box: .tag MOUSE_BOX
+info: .tag MOUSE_INFO
+slot: .res 1
+visible:.res 1
+
+; ------------------------------------------------------------------------
+
+ .rodata
+
+offsets:.byte $05 ; Pascal 1.0 ID byte
+ .byte $07 ; Pascal 1.0 ID byte
+ .byte $0B ; Pascal 1.1 generic signature byte
+ .byte $0C ; Device signature byte
+
+values: .byte $38 ; Fixed
+ .byte $18 ; Fixed
+ .byte $01 ; Fixed
+ .byte $20 ; X-Y pointing device type 0
+
+size = * - values
+
+inibox: .word 0 ; MinX
+ .word 0 ; MinY
+ .word 279 ; MaxX
+ .word 191 ; MaxY
+
+; ------------------------------------------------------------------------
+
+ .data
+
+firmware:
+ ; Lookup and patch firmware address lobyte
+lookup: ldy $FF00,x ; Patched at runtime
+ sty jump+1 ; Modify code below
+
+ ; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse:
+ ; "Enter all mouse routines (...) with the X register set to $Cn
+ ; and Y register set to $n0, where n = the slot number."
+xparam: ldx #$FF ; Patched at runtime
+yparam: ldy #$FF ; Patched at runtime
+
+jump: jmp $FFFF ; Patched at runtime
+
+; ------------------------------------------------------------------------
+
+ .code
+
+; INSTALL: Is called after the driver is loaded into memory. If possible,
+; check if the hardware is present. Must return an MOUSE_ERR_xx code in A/X.
+INSTALL:
+ lda #<$C000
+ sta ptr1
+ lda #>$C000
+ sta ptr1+1
+
+ ; Search for AppleMouse II firmware in slots 1 - 7
+next: inc ptr1+1
+ lda ptr1+1
+ cmp #>$C800
+ bcc :+
+
+ ; Mouse firmware not found
+ lda #<MOUSE_ERR_NO_DEVICE
+ ldx #>MOUSE_ERR_NO_DEVICE
+ rts
+
+ ; Check Pascal 1.1 Firmware Protocol ID bytes
+: ldx #size - 1
+: ldy offsets,x
+ lda values,x
+ cmp (ptr1),y
+ bne next
+ dex
+ bpl :-
+
+ ; Get and patch firmware address hibyte
+ lda ptr1+1
+ sta lookup+2
+ sta xparam+1
+ sta jump+2
+
+ ; Disable interrupts now because setting the slot number makes
+ ; the IRQ handler (maybe called due to some non-mouse IRQ) try
+ ; calling the firmware which isn't correctly set up yet
+ sei
+
+ ; Convert to and save slot number
+ and #$0F
+ sta slot
+
+ ; Convert to and patch I/O register index
+ asl
+ asl
+ asl
+ asl
+ sta yparam+1
+
+ ; The AppleMouse II Card needs the ROM switched in
+ ; to be able to detect an Apple //e and use RDVBL
+ bit $C082
+
+ ; Reset mouse hardware
+ ldx #INITMOUSE
+ jsr firmware
+
+ ; Switch in LC bank 2 for R/O
+ bit $C080
+
+ ; Turn mouse on
+ lda #%00000001
+ ldx #SETMOUSE
+ jsr firmware
+
+ ; Set initial mouse clamps
+ lda #<inibox
+ ldx #>inibox
+ jsr SETBOX
+
+ ; Set initial mouse position
+ ldx slot
+ lda #<(279 / 2)
+ sta pos1_lo,x
+ lda #>(279 / 2)
+ sta pos1_hi,x
+ lda #<(191 / 2)
+ sta pos2_lo,x
+ lda #>(191 / 2)
+ sta pos2_hi,x
+ ldx #POSMOUSE
+ jsr firmware
+
+ ; Update cursor
+ jsr update
+
+ ; Turn VBL interrupt on
+ lda #%00001001
+ ldx #SETMOUSE
+common: jsr firmware
+
+ ; Enable interrupts and return success
+ cli
+ lda #<MOUSE_ERR_OK
+ ldx #>MOUSE_ERR_OK
+ rts
+
+; UNINSTALL: Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+UNINSTALL:
+ ; Hide cursor
+ sei
+ jsr CHIDE
+
+ ; Turn mouse off
+ lda #%00000000
+ ldx #SETMOUSE
+ bne common ; Branch always
+
+; SETBOX: Set the mouse bounding box. The parameters are passed as they come
+; from the C program, that is, a pointer to a mouse_box struct in A/X.
+; No checks are done if the mouse is currently inside the box, this is the job
+; of the caller. It is not necessary to validate the parameters, trust the
+; caller and save some code here. No return code required.
+SETBOX:
+ sta ptr1
+ stx ptr1+1
+
+ ; Set x clamps
+ ldx #$00
+ ldy #MOUSE_BOX::MINX
+ jsr :+
+
+ ; Set y clamps
+ ldx #$01
+ ldy #MOUSE_BOX::MINY
+
+ ; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse:
+ ; "Disable interrupts before placing position information in the
+ ; screen holes."
+: sei
+
+ ; Set low clamp
+ lda (ptr1),y
+ sta box,y
+ sta pos1_lo
+ iny
+ lda (ptr1),y
+ sta box,y
+ sta pos1_hi
+
+ ; Skip one word
+ iny
+ iny
+
+ ; Set high clamp
+ iny
+ lda (ptr1),y
+ sta box,y
+ sta pos2_lo
+ iny
+ lda (ptr1),y
+ sta box,y
+ sta pos2_hi
+
+ txa
+ ldx #CLAMPMOUSE
+ bne common ; Branch always
+
+; GETBOX: Return the mouse bounding box. The parameters are passed as they
+; come from the C program, that is, a pointer to a mouse_box struct in A/X.
+GETBOX:
+ sta ptr1
+ stx ptr1+1
+
+ ldy #.sizeof(MOUSE_BOX)-1
+: lda box,y
+ sta (ptr1),y
+ dey
+ bpl :-
+ rts
+
+; MOVE: Move the mouse to a new position. The position is passed as it comes
+; from the C program, that is: x on the stack and y in A/X. The C wrapper will
+; remove the parameter from the stack on return.
+; No checks are done if the new position is valid (within the bounding box or
+; the screen). No return code required.
+MOVE:
+ ldy slot
+ sei
+
+ ; Set y
+ sta pos2_lo,y
+ txa
+ sta pos2_hi,y
+
+ tya
+ tax
+ ldy #$00 ; Start at top of stack
+
+ ; Set x
+ lda (sp),y
+ iny
+ sta pos1_lo,x
+ lda (sp),y
+ sta pos1_hi,x
+
+ ; Update cursor
+ jsr update
+
+ ldx #POSMOUSE
+ bne common ; Branch always
+
+; HIDE: Is called to hide the mouse cursor. The mouse kernel manages a
+; counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently visible and should get hidden. For most drivers,
+; no special action is required besides hiding the mouse cursor.
+; No return code required.
+HIDE:
+ dec visible
+ sei
+ jsr CHIDE
+ cli
+ rts
+
+; SHOW: Is called to show the mouse cursor. The mouse kernel manages a
+; counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently hidden and should become visible. For most drivers,
+; no special action is required besides enabling the mouse cursor.
+; No return code required.
+SHOW:
+ inc visible
+ rts
+
+; BUTTONS: Return the button mask in A/X.
+BUTTONS:
+ lda info + MOUSE_INFO::BUTTONS
+ ldx #$00
+ rts
+
+; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
+; No return code required.
+POS:
+ ldy #.sizeof(MOUSE_POS)-1
+ bne copy ; Branch always
+
+; INFO: Returns mouse position and current button mask in the MOUSE_INFO
+; struct pointed to by ptr1. No return code required.
+INFO:
+ ldy #.sizeof(MOUSE_INFO)-1
+copy: sei
+: lda info,y
+ sta (ptr1),y
+ dey
+ bpl :-
+ cli
+ rts
+
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an MOUSE_ERR_xx code in A/X.
+IOCTL:
+ lda #<MOUSE_ERR_INV_IOCTL
+ ldx #>MOUSE_ERR_INV_IOCTL
+ rts
+
+; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
+; registers are already saved, no parameters are passed, but the carry flag
+; is clear on entry. The routine must return with carry set if the interrupt
+; was handled, otherwise with carry clear.
+IRQ:
+ ; Check for installed mouse
+ lda slot
+ beq done
+
+ ; Check for mouse interrupt
+ ldx #SERVEMOUSE
+ jsr firmware
+ bcc :+
+ clc ; Interrupt not handled
+done: rts
+
+: ldx #READMOUSE
+ jsr firmware
+
+ ; Get status
+ ldy slot
+ lda status,y
+ tax ; Save status
+
+ ; Extract button down values
+ asl ; C = Button 0 is currently down
+ and #%00100000 ; !Z = Button 1 is currently down
+
+ ; Set button mask
+ beq :+
+ lda #MOUSE_BTN_RIGHT
+: bcc :+
+ ora #MOUSE_BTN_LEFT
+: sta info + MOUSE_INFO::BUTTONS
+
+ ; Check for mouse movement
+ txa ; Restore status
+ and #%00100000 ; X or Y changed since last READMOUSE
+ beq :+
+
+ ; Remove the cursor at the old position
+update: jsr CHIDE
+
+ ; Get and set the new X position
+ ldy slot
+ lda pos1_lo,y
+ ldx pos1_hi,y
+ sta info + MOUSE_POS::XCOORD
+ stx info + MOUSE_POS::XCOORD+1
+ jsr CMOVEX
+
+ ; Get and set the new Y position
+ ldy slot
+ lda pos2_lo,y
+ ldx pos2_hi,y
+ sta info + MOUSE_POS::YCOORD
+ stx info + MOUSE_POS::YCOORD+1
+ jsr CMOVEY
+
+ ; Check for visibility
+: lda visible
+ beq :+
+
+ ; Draw the cursor at the new position
+ jsr CSHOW
+: sec ; Interrupt handled
+ rts
--- /dev/null
+;
+; Serial driver for the Apple II Super Serial Card.
+;
+; Oliver Schmidt, 21.04.2005
+;
+; The driver is based on the cc65 rs232 module, which in turn is based on
+; Craig Bruce device driver for the Switftlink/Turbo-232.
+;
+; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
+;
+; This software is Public Domain. It is in Buddy assembler format.
+;
+; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
+; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
+; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
+; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
+;
+; The code assumes that the kernal + I/O are in context. On the C128, call
+; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
+; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
+; interrupt handling assumes that the 65816 is in 6502-emulation mode.
+;
+
+ .include "zeropage.inc"
+ .include "ser-kernel.inc"
+ .include "ser-error.inc"
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ .segment "JUMPTABLE"
+
+ ; Driver signature
+ .byte $73, $65, $72 ; "ser"
+ .byte SER_API_VERSION ; Serial API version number
+
+ ; Jump table.
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr OPEN
+ .addr CLOSE
+ .addr GET
+ .addr PUT
+ .addr STATUS
+ .addr IOCTL
+ .addr IRQ
+
+;----------------------------------------------------------------------------
+; I/O definitions
+
+ACIA = $C088
+ACIA_DATA = ACIA+0 ; Data register
+ACIA_STATUS = ACIA+1 ; Status register
+ACIA_CMD = ACIA+2 ; Command register
+ACIA_CTRL = ACIA+3 ; Control register
+
+;----------------------------------------------------------------------------
+; Global variables
+
+ .bss
+
+RecvHead: .res 1 ; Head of receive buffer
+RecvTail: .res 1 ; Tail of receive buffer
+RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
+SendHead: .res 1 ; Head of send buffer
+SendTail: .res 1 ; Tail of send buffer
+SendFreeCnt: .res 1 ; Number of bytes in send buffer
+
+Stopped: .res 1 ; Flow-stopped flag
+RtsOff: .res 1 ;
+
+RecvBuf: .res 256 ; Receive buffers: 256 bytes
+SendBuf: .res 256 ; Send buffers: 256 bytes
+
+Index: .res 1 ; I/O register index
+
+ .data
+
+Slot: .byte $02 ; Default to SSC in slot 2
+
+ .rodata
+
+ ; Tables used to translate RS232 params into register values
+BaudTable: ; bit7 = 1 means setting is invalid
+ .byte $FF ; SER_BAUD_45_5
+ .byte $01 ; SER_BAUD_50
+ .byte $02 ; SER_BAUD_75
+ .byte $03 ; SER_BAUD_110
+ .byte $04 ; SER_BAUD_134_5
+ .byte $05 ; SER_BAUD_150
+ .byte $06 ; SER_BAUD_300
+ .byte $07 ; SER_BAUD_600
+ .byte $08 ; SER_BAUD_1200
+ .byte $09 ; SER_BAUD_1800
+ .byte $0A ; SER_BAUD_2400
+ .byte $0B ; SER_BAUD_3600
+ .byte $0C ; SER_BAUD_4800
+ .byte $0D ; SER_BAUD_7200
+ .byte $0E ; SER_BAUD_9600
+ .byte $0F ; SER_BAUD_19200
+ .byte $FF ; SER_BAUD_38400
+ .byte $FF ; SER_BAUD_57600
+ .byte $FF ; SER_BAUD_115200
+ .byte $FF ; SER_BAUD_230400
+BitTable:
+ .byte $60 ; SER_BITS_5
+ .byte $40 ; SER_BITS_6
+ .byte $20 ; SER_BITS_7
+ .byte $00 ; SER_BITS_8
+StopTable:
+ .byte $00 ; SER_STOP_1
+ .byte $80 ; SER_STOP_2
+ParityTable:
+ .byte $00 ; SER_PAR_NONE
+ .byte $20 ; SER_PAR_ODD
+ .byte $60 ; SER_PAR_EVEN
+ .byte $A0 ; SER_PAR_MARK
+ .byte $E0 ; SER_PAR_SPACE
+IdOfsTable:
+ .byte $05 ; Pascal 1.0 ID byte
+ .byte $07 ; Pascal 1.0 ID byte
+ .byte $0B ; Pascal 1.1 generic signature byte
+ .byte $0C ; Device signature byte
+IdValTable:
+ .byte $38 ; Fixed
+ .byte $18 ; Fixed
+ .byte $01 ; Fixed
+ .byte $31 ; Serial or parallel I/O card type 1
+
+IdTableLen = * - IdValTable
+
+ .code
+
+;----------------------------------------------------------------------------
+; INSTALL: Is called after the driver is loaded into memory. If possible,
+; check if the hardware is present. Must return an SER_ERR_xx code in a/x.
+;
+; Since we don't have to manage the IRQ vector on the Apple II, this is
+; actually the same as:
+;
+; UNINSTALL: Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+;
+; and:
+;
+; CLOSE: Close the port and disable interrupts. Called without parameters.
+; Must return an SER_ERR_xx code in a/x.
+
+INSTALL:
+UNINSTALL:
+CLOSE:
+ ldx Index ; Check for open port
+ beq :+
+
+ ; Deactivate DTR and disable 6551 interrupts
+ lda #%00001010
+ sta ACIA_CMD,x
+
+ ; Done, return an error code
+: lda #<SER_ERR_OK
+ tax ; A is zero
+ stx Index ; Mark port as closed
+ rts
+
+;----------------------------------------------------------------------------
+; OPEN: A pointer to a ser_params structure is passed in ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+OPEN:
+ ldx #<$C000
+ stx ptr2
+ lda #>$C000
+ ora Slot
+ sta ptr2+1
+
+ ; Check Pascal 1.1 Firmware Protocol ID bytes
+: ldy IdOfsTable,x
+ lda IdValTable,x
+ cmp (ptr2),y
+ bne NoDevice
+ inx
+ cpx #IdTableLen
+ bcc :-
+
+ ; Convert slot to I/O register index
+ lda Slot
+ asl
+ asl
+ asl
+ asl
+ tax
+
+ ; Check if the handshake setting is valid
+ ldy #SER_PARAMS::HANDSHAKE ; Handshake
+ lda (ptr1),y
+ cmp #SER_HS_HW ; This is all we support
+ bne InvParam
+
+ ; Initialize buffers
+ ldy #$00
+ sty Stopped
+ sty RecvHead
+ sty RecvTail
+ sty SendHead
+ sty SendTail
+ dey ; Y = 255
+ sty RecvFreeCnt
+ sty SendFreeCnt
+
+ ; Set the value for the control register, which contains stop bits,
+ ; word length and the baud rate.
+ ldy #SER_PARAMS::BAUDRATE
+ lda (ptr1),y ; Baudrate index
+ tay
+ lda BaudTable,y ; Get 6551 value
+ bmi InvBaud ; Branch if rate not supported
+ sta tmp1
+
+ ldy #SER_PARAMS::DATABITS ; Databits
+ lda (ptr1),y
+ tay
+ lda BitTable,y
+ ora tmp1
+ sta tmp1
+
+ ldy #SER_PARAMS::STOPBITS ; Stopbits
+ lda (ptr1),y
+ tay
+ lda StopTable,y
+ ora tmp1
+ ora #%00010000 ; Receiver clock source = baudrate
+ sta ACIA_CTRL,x
+
+ ; Set the value for the command register. We remember the base value
+ ; in RtsOff, since we will have to manipulate ACIA_CMD often.
+ ldy #SER_PARAMS::PARITY ; Parity
+ lda (ptr1),y
+ tay
+ lda ParityTable,y
+ ora #%00000001 ; DTR active
+ sta RtsOff
+ ora #%00001000 ; Enable receive interrupts
+ sta ACIA_CMD,x
+
+ ; Done
+ stx Index ; Mark port as open
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+ ; Device (hardware) not found
+NoDevice:lda #<SER_ERR_NO_DEVICE
+ ldx #>SER_ERR_NO_DEVICE
+ rts
+
+ ; Invalid parameter
+InvParam:lda #<SER_ERR_INIT_FAILED
+ ldx #>SER_ERR_INIT_FAILED
+ rts
+
+ ; Baud rate not available
+InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
+ ldx #>SER_ERR_BAUD_UNAVAIL
+ rts
+
+;----------------------------------------------------------------------------
+; GET: Will fetch a character from the receive buffer and store it into the
+; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; returned.
+
+GET:
+ ldx Index
+ ldy SendFreeCnt ; Send data if necessary
+ iny ; Y == $FF?
+ beq :+
+ lda #$00 ; TryHard = false
+ jsr TryToSend
+
+ ; Check for buffer empty
+: lda RecvFreeCnt ; (25)
+ cmp #$FF
+ bne :+
+ lda #<SER_ERR_NO_DATA
+ ldx #>SER_ERR_NO_DATA
+ rts
+
+ ; Check for flow stopped & enough free: release flow control
+: ldy Stopped ; (34)
+ beq :+
+ cmp #63
+ bcc :+
+ lda #$00
+ sta Stopped
+ lda RtsOff
+ ora #%00001000
+ sta ACIA_CMD,x
+
+ ; Get byte from buffer
+: ldy RecvHead ; (41)
+ lda RecvBuf,y
+ inc RecvHead
+ inc RecvFreeCnt
+ ldx #$00 ; (59)
+ sta (ptr1,x)
+ txa ; Return code = 0
+ rts
+
+;----------------------------------------------------------------------------
+; PUT: Output character in A.
+; Must return an SER_ERR_xx code in a/x.
+
+PUT:
+ ldx Index
+
+ ; Try to send
+ ldy SendFreeCnt
+ iny ; Y = $FF?
+ beq :+
+ pha
+ lda #$00 ; TryHard = false
+ jsr TryToSend
+ pla
+
+ ; Put byte into send buffer & send
+: ldy SendFreeCnt
+ bne :+
+ lda #<SER_ERR_OVERFLOW
+ ldx #>SER_ERR_OVERFLOW
+ rts
+
+: ldy SendTail
+ sta SendBuf,y
+ inc SendTail
+ dec SendFreeCnt
+ lda #$FF ; TryHard = true
+ jsr TryToSend
+ lda #<SER_ERR_OK
+ tax
+ rts
+
+;----------------------------------------------------------------------------
+; STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+STATUS:
+ ldx Index
+ lda ACIA_STATUS,x
+ ldx #$00
+ sta (ptr1,x)
+ txa ; SER_ERR_OK
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an SER_ERR_xx code in a/x.
+
+IOCTL:
+ ; Check data msb and code to be 0
+ ora ptr1+1
+ bne :+
+
+ ; Check data lsb to be [1..7]
+ ldx ptr1
+ beq :+
+ cpx #7+1
+ bcs :+
+
+ stx Slot
+ tax ; SER_ERR_OK
+ rts
+
+: lda #<SER_ERR_INV_IOCTL
+ ldx #>SER_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
+; registers are already saved, no parameters are passed, but the carry flag
+; is clear on entry. The routine must return with carry set if the interrupt
+; was handled, otherwise with carry clear.
+
+IRQ:
+ ldx Index ; Check for open port
+ beq Done
+ lda ACIA_STATUS,x ; Check ACIA status for receive interrupt
+ and #$08
+ beq Done ; Jump if no ACIA interrupt
+ lda ACIA_DATA,x ; Get byte from ACIA
+ ldy RecvFreeCnt ; Check if we have free space left
+ beq Flow ; Jump if no space in receive buffer
+ ldy RecvTail ; Load buffer pointer
+ sta RecvBuf,y ; Store received byte in buffer
+ inc RecvTail ; Increment buffer pointer
+ dec RecvFreeCnt ; Decrement free space counter
+ ldy RecvFreeCnt ; Check for buffer space low
+ cpy #33
+ bcc Flow ; Assert flow control if buffer space low
+ rts ; Interrupt handled (carry already set)
+
+ ; Assert flow control if buffer space too low
+Flow: lda RtsOff
+ sta ACIA_CMD,x
+ sta Stopped
+ sec ; Interrupt handled
+Done: rts
+
+;----------------------------------------------------------------------------
+; Try to send a byte. Internal routine. A = TryHard
+
+TryToSend:
+ sta tmp1 ; Remember tryHard flag
+Again: lda SendFreeCnt
+ cmp #$FF
+ beq Quit ; Bail out
+
+ ; Check for flow stopped
+ lda Stopped
+ bne Quit ; Bail out
+
+ ; Check that ACIA is ready to send
+ lda ACIA_STATUS,x
+ and #$10
+ bne Send
+ bit tmp1 ; Keep trying if must try hard
+ bmi Again
+Quit: rts
+
+ ; Send byte and try again
+Send: ldy SendHead
+ lda SendBuf,y
+ sta ACIA_DATA,x
+ inc SendHead
+ inc SendFreeCnt
+ jmp Again
--- /dev/null
+;
+; Graphics driver for the 280x192x8 mode on the Apple II
+;
+; Stefan Haubenthal <polluks@sdf.lonestar.org>
+; Oliver Schmidt <ol.sc@web.de>
+;
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+ .include "apple2.inc"
+
+; ------------------------------------------------------------------------
+
+; 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
+
+; ------------------------------------------------------------------------
+
+ .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
+ .word 280 ; X resolution
+ .word 192 ; Y resolution
+ .byte 8 ; Number of drawing colors
+pages: .byte 2 ; Number of screens available
+ .byte 7 ; System font X size
+ .byte 8 ; System font Y size
+ .word $00EA ; Aspect ratio (based on 4/3 display)
+ .byte 0 ; TGI driver flags
+
+; Next comes the jump table. With the exception of IRQ, 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 TEXTSTYLE
+ .addr OUTTEXT
+ .addr 0 ; IRQ entry is unused
+
+; ------------------------------------------------------------------------
+
+ .bss
+
+; Absolute variables used in the code
+
+ERROR: .res 1 ; Error code
+
+; ------------------------------------------------------------------------
+
+ .rodata
+
+; Constants and tables
+
+DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
+
+FONT:
+ ; Beagle Bros Shape Mechanic font F.ASCII.SMALL
+ ; modified to exactly reproduce the text glyphs
+ .incbin "a2.hi.fnt"
+
+; ------------------------------------------------------------------------
+
+ .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:
+ .ifdef __APPLE2ENH__
+ ; No page switching if 80 column store is enabled
+ bit RD80COL
+ bpl :+
+ lda #$01
+ sta pages
+: .endif
+
+ ; 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
+
+; 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 MIXCLR
+ bit HIRES
+ bit TXTCLR
+
+ ; Beagle Bros Shape Mechanic fonts don't
+ ; scale well so use fixed scaling factor
+ lda #$01
+ sta SCALE
+
+ ; 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:
+ ; Switch into text mode
+ bit TXTSET
+ bit LOWSCR
+
+ .ifdef __APPLE2ENH__
+ ; Limit SET80COL-HISCR to text
+ bit LORES
+ .endif
+
+ ; Reset the text window top
+ lda #$00
+ sta WNDTOP
+ rts
+
+; GETERROR: Return the error code in A and clear it.
+GETERROR:
+ lda ERROR
+ ldx #TGI_ERR_OK
+ stx ERROR
+ rts
+
+; CONTROL: Platform/driver specific entry point.
+; Must set an error code: YES
+CONTROL:
+ ; Check data msb and code to be 0
+ ora ptr1+1
+ bne err
+
+ ; Check data lsb to be [0..1]
+ lda ptr1
+ cmp #1+1
+ bcs err
+
+ ; Set text window top
+ tax
+ beq :+
+ lda #20
+: sta WNDTOP
+
+ ; Switch 4 lines of text
+ .assert MIXCLR + 1 = MIXSET, error
+ lda MIXCLR,x ; No BIT absolute,X available
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ beq :+ ; Branch always
+
+ ; Done, set the error code
+err: lda #TGI_ERR_INV_ARG
+: sta 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
+
+; 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
+
+; 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
+
+; 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:
+ cmp #TGI_TEXT_VERTICAL
+ bne :+
+ lda #48
+: 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
+ lda X1
+ ldy X1+1
+ ldx ROT
+ php ; Save Z flag
+ beq :+ ; Not horizontal
+ sec
+ sbc #$07 ; Adjust X
+ bcs :+
+ dey
+: tax
+ lda Y1
+ plp ; Restore Z flag
+ bne :+ ; Not vertical
+ sec
+ sbc #$07 ; Adjust Y
+: jsr HPOSN
+ clc
+ lda FONT+2*99 ; "connection char"
+ adc #<FONT
+ sta ptr4
+ lda FONT+2*99+1 ; "connection char"
+ adc #>FONT
+ sta ptr4+1
+ ldy #$00
+: lda (ptr3),y
+ beq :+
+ sty tmp1 ; Save string index
+ sec
+ sbc #$1F ; No control chars
+ asl ; Offset * 2
+ tay
+ clc
+ lda FONT,y
+ adc #<FONT
+ tax
+ lda FONT+1,y
+ adc #>FONT
+ tay
+ lda ROT
+ jsr DRAW ; Draw char from string
+ ldx ptr4
+ ldy ptr4+1
+ lda ROT
+ jsr DRAW ; Draw "connection char"
+ ldy tmp1 ; Restore string index
+ iny
+ bne :- ; Branch always
+: bit $C080 ; Switch in LC bank 2 for R/O
+ 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>
+;
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+ .include "apple2.inc"
+
+; ------------------------------------------------------------------------
+
+; Zero page stuff
+
+H2 := $2C
+COLOR := $30
+
+; ROM entry points
+
+TEXT := $F399
+PLOT := $F800
+HLINE := $F819
+CLRSC2 := $F838
+SETCOL := $F864
+SCRN := $F871
+SETGR := $FB40
+HOME := $FC58
+
+; Used for passing parameters to the driver
+
+X1 := ptr1
+Y1 := ptr2
+X2 := ptr3
+Y2 := ptr4
+
+; ------------------------------------------------------------------------
+
+ .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
+ .word 40 ; X resolution
+ .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
+ .word $0198 ; Aspect ratio (based on 4/3 display)
+ .byte 0 ; TGI driver flags
+
+; Next comes the jump table. With the exception of IRQ, 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 TEXTSTYLE
+ .addr OUTTEXT
+ .addr 0 ; IRQ entry is unused
+
+; ------------------------------------------------------------------------
+
+ .bss
+
+ERROR: .res 1 ; Error code
+MIX: .res 1 ; 4 lines of text
+
+; ------------------------------------------------------------------------
+
+ .rodata
+
+DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
+ .byte $08, $09, $0A, $0B, $0C, $0D, $0E, $0F
+
+TGI2COL: .byte $00, $0C, $03, $0F, $01, $09, $06, $02
+ .byte $04, $05, $07, $08, $0A, $0B, $0D, $0E
+
+COL2TGI: .byte $00, $04, $07, $02, $08, $09, $06, $0A
+ .byte $0B, $05, $0C, $0D, $01, $0E, $0F, $03
+
+MAXY: .byte 47, 39
+
+; ------------------------------------------------------------------------
+
+ .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
+ sta MIX
+
+ ; 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
+ lda COLOR ; Save current drawing color
+ pha
+ ldx MIX
+ ldy MAXY,x ; Max Y depends on 4 lines of text
+ jsr CLRSC2
+ pla
+ sta COLOR ; Restore current drawing color
+ 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
+ tax
+ lda TGI2COL,x
+ 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:
+ ; Check data msb and code to be 0
+ ora ptr1+1
+ bne err
+
+ ; Check data lsb to be [0..1]
+ lda ptr1
+ cmp #1+1
+ bcs err
+ bit $C082 ; Switch in ROM
+
+ ; Switch 4 lines of text
+ tax
+ .assert MIXCLR + 1 = MIXSET, error
+ lda MIXCLR,x ; No BIT absolute,X available
+
+ ; Save current switch setting
+ txa
+ sta MIX
+ bne text
+
+ ; Clear 8 lines of graphics
+ lda COLOR ; Save current drawing color
+ pha
+ lda #39 ; Rightmost column
+ sta H2
+ ldx #40 ; First line
+: txa
+ ldy #$00 ; Leftmost column
+ sty COLOR ; Black
+ jsr HLINE ; Preserves X
+ inx
+ cpx #47+1 ; Last line
+ bcc :-
+ pla
+ sta COLOR ; Restore current drawing color
+ bcs :+ ; Branch always
+
+ ; Clear 4 lines of text
+text: jsr HOME
+: bit $C080 ; Switch in LC bank 2 for R/O
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ beq :+ ; Branch always
+
+ ; Done, set the error code
+err: lda #TGI_ERR_INV_ARG
+: sta ERROR
+ rts
+
+; 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
+
+; 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
+ tax
+ lda COL2TGI,x
+ ldx #$00
+ 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:
+ bit $C082 ; Switch in ROM
+ lda X2
+ sta H2
+ inc Y2
+ ldx Y1
+: txa
+ ldy X1
+ jsr HLINE ; Preserves X
+ inx
+ cpx Y2
+ bcc :-
+ bit $C080 ; Switch in LC bank 2 for R/O
+ rts
+
+; ------------------------------------------------------------------------
+
+.include "../../tgi/tgidrv_line.inc"
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = apple2enh
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../apple2 -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I ../apple2 -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: ../apple2/%.c
- @$(CC) -o $(notdir $(*).s) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: ../apple2/%.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-extra/%.o: ../apple2/extra/%.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-mou.o: %.mou
- @$(CO) -o $(*)-mou.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-mou.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS= closedir.o \
- opendir.o \
- readdir.o \
- rewinddir.o
-
-S_OBJS= _scrsize.o \
- break.o \
- cclear.o \
- cgetc.o \
- chline.o \
- close.o \
- clrscr.o \
- color.o \
- cout.o \
- cputc.o \
- crt0.o \
- ctype.o \
- curdevice.o \
- cvline.o \
- devicedir.o \
- dioclose.o \
- diocommon.o \
- dioopen.o \
- dioread.o \
- diosectcount.o \
- diosectsize.o \
- diowrite.o \
- dosdetect.o \
- exec.o \
- exehdr.o \
- filedes.o \
- filename.o \
- get_ostype.o \
- getdevice.o \
- gotoxy.o \
- gotoy.o \
- home.o \
- initcwd.o \
- iobuf.o \
- irq.o \
- isdevice.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- mainargs.o \
- mcbdefault.o \
- mli.o \
- mouse_stat_stddrv.o \
- mouse_stddrv.o \
- open.o \
- oserrlist.o \
- oserror.o \
- randomize.o \
- rdkey.o \
- read.o \
- reboot.o \
- revers.o \
- rwcommon.o \
- syschdir.o \
- sysmkdir.o \
- sysremove.o \
- sysrename.o \
- sysrmdir.o \
- systime.o \
- sysuname.o \
- textframe.o \
- tgi_colors.o \
- tgi_stat_stddrv.o \
- tgi_stddrv.o \
- toascii.o \
- videomode.o \
- vtabz.o \
- wherex.o \
- wherey.o \
- write.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(MOUS:.mou=-mou.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-S_EXTRA_OBJS= \
- extra/iobuf-0800.o
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS = apple2-auxmem.emd
-
-JOYS = apple2-stdjoy.joy
-
-MOUS = apple2-stdmou.mou
-
-SERS = apple2-ssc.ser
-
-TGIS = apple2-280-192-8.tgi apple2-40-48-16.tgi
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS) $(S_EXTRA_OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS) $(S_EXTRA_OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(MOUS:.mou=.o) $(MOUS:.mou=-mou.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
+++ /dev/null
-#
-# makefile for CC65 Atari runtime library
-#
-# NUMDRVS - number of supported drives (max. 16)
-# 4 bytes for each device are statically allocated
-# LINEBUF - support line buffered reads from E: (the number specifies
-# the length of the buffer)
-# UCASE_FILENAME - all filenames get uppercased
-# DEFAULT_DEVICE - if the string passed to the uppercase function doesn't
-# include a device (":" at position 2 or 3), provide "Dn:"
-# as a default disk device
-# n is the value of DEFAULT_DEVICE, unless DYNAMIC_DD is
-# also set, in which case it's overridden by a runtime
-# check (on SpartaDOS only)
-# needs UCASE_FILENAME to be defined, otherwise no effect
-# DYNAMIC_DD - determine default disk device at runtime (SpartaDOS only)
-# needs DEFAULT_DEVICE to be defined, otherwise no effect
-
-ATARIDEFS = -DNUMDRVS=4 -DUCASE_FILENAME=1 -DDEFAULT_DEVICE=1 -DLINEBUF=80
-ATARIDEFS += -DDYNAMIC_DD=1
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = atari
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $(ATARIDEFS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $(ATARIDEFS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o atari_tgi_common.inc
- @$(LD) -o $@ -t module $< ../runtime/zeropage.o
-
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- break.o \
- cclear.o \
- cgetc.o \
- chline.o \
- clock.o \
- close.o \
- clrscr.o \
- color.o \
- cputc.o \
- crt0.o \
- ctype.o \
- cvline.o \
- dio_cts.o \
- dio_stc.o \
- diopncls.o \
- dioqsize.o \
- dioread.o \
- diowrite.o \
- diowritev.o \
- do_oserr.o \
- dosdetect.o \
- fdtable.o \
- fdtab.o \
- fdtoiocb.o \
- getargs.o \
- getdefdev.o \
- getfd.o \
- gotox.o \
- gotoy.o \
- gotoxy.o \
- graphics.o \
- initcwd.o \
- inviocb.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- lseek.o \
- mul40.o \
- open.o \
- oserrlist.o \
- oserror.o \
- ostype.o \
- posixdirent.o \
- randomize.o \
- read.o \
- revers.o \
- rwcommon.o \
- savevec.o \
- scroll.o \
- setcolor.o \
- siocall.o \
- syschdir.o \
- sysmkdir.o \
- sysremove.o \
- sysrmdir.o \
- systime.o \
- sysuname.o \
- tgi_colors.o \
- tgi_stat_stddrv.o \
- tgi_stddrv.o \
- toascii.o \
- tvtype.o \
- ucase_fn.o \
- wherex.o \
- wherey.o \
- write.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(TGIS:.tgi=-tgi.o)
-
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS = atari-130xe.emd
-
-JOYS = atari-stdjoy.joy atari-multijoy.joy
-
-TGIS = atari-3.tgi atari-4.tgi atari-5.tgi atari-6.tgi atari-7.tgi atari-8.tgi \
- atari-9.tgi atari-10.tgi atari-11.tgi atari-14.tgi atari-15.tgi atari-8p2.tgi \
- atari-9p2.tgi atari-10p2.tgi atari-15p2.tgi
-
-#--------------------------------------------------------------------------
-# Targets
-
-all: $(OBJS) $(EMDS) $(JOYS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(TGIS)
--- /dev/null
+# NUMDRVS - number of supported drives (max. 16)
+# 4 bytes for each device are statically allocated
+# LINEBUF - support line buffered reads from E: (the number specifies
+# the length of the buffer)
+# UCASE_FILENAME - all filenames get uppercased
+# DEFAULT_DEVICE - if the string passed to the uppercase function doesn't
+# include a device (":" at position 2 or 3), provide "Dn:"
+# as a default disk device
+# n is the value of DEFAULT_DEVICE, unless DYNAMIC_DD is
+# also set, in which case it's overridden by a runtime
+# check (on SpartaDOS only)
+# needs UCASE_FILENAME to be defined, otherwise no effect
+# DYNAMIC_DD - determine default disk device at runtime (SpartaDOS only)
+# needs DEFAULT_DEVICE to be defined, otherwise no effect
+
+CFLAGS += -Wa -DNUMDRVS=4,-DLINEBUF=80,-DUCASE_FILENAME=1,-DDEFAULT_DEVICE=1,-DDYNAMIC_DD=1
+++ /dev/null
-;
-; Graphics driver for the 80x192x9 (CIO mode 10, ANTIC mode F, GTIA mode $80) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 10
-; X resolution
- x_res = 80
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 9
-; Pixels per byte
- ppb = 2
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $0330 ; based on 4/3 display
-; Free memory needed
- mem_needed = 7147
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11110000, %00001111
- masks: ; Color masks
- .byte $00, $11, $22, $33, $44, $55, $66, $77, $88
- bar_table: ; Mask table for BAR
- .byte %11111111, %00001111, %00000000
- default_palette:
- .byte $00, $0E, $32, $96, $68, $C4, $74, $EE, $4A
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- sta PCOLR0,y
- dey
- bpl loop
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 80x192x9 (CIO mode 10, ANTIC mode F, GTIA mode $80) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 10
-; X resolution
- x_res = 80
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 9
-; Pixels per byte
- ppb = 2
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $0330 ; based on 4/3 display
-; Free memory needed
- mem_needed = 15339
-; Number of screen pages
- pages = 2
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11110000, %00001111
- masks: ; Color masks
- .byte $00, $11, $22, $33, $44, $55, $66, $77, $88
- bar_table: ; Mask table for BAR
- .byte %11111111, %00001111, %00000000
- default_palette:
- .byte $00, $0E, $32, $96, $68, $C4, $74, $EE, $4A
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- sta PCOLR0,y
- dey
- bpl loop
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 80x192x16h (CIO mode 11, ANTIC mode F, GTIA mode $C0) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 11
-; X resolution
- x_res = 80
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 16
-; Pixels per byte
- ppb = 2
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $0330 ; based on 4/3 display
-; Free memory needed
- mem_needed = 7147
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11110000, %00001111
- masks: ; Color masks
- .byte $00, $11, $22, $33, $44, $55, $66, $77, $88, $99, $aa, $bb, $cc, $dd, $ee, $ff
- bar_table: ; Mask table for BAR
- .byte %11111111, %00001111, %00000000
- default_palette:
- .byte $00, $10, $20, $30, $40, $50, $60, $70, $80, $90, $A0, $B0, $C0, $D0, $E0, $F0
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; No palettes
- lda #TGI_ERR_INV_FUNC
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Extended memory driver for the Atari 130XE memory standard
-; Shawn Jefferson, 2012-08-11
-;
-; Banking Register $D301:
-; Bit 7: Self-Test on/off
-; Bit 6: Unused
-; Bit 5: Antic sees bank
-; Bit 4: CPU sees bank
-; Bit 3: bank control
-; Bit 2: bank control
-; Bit 1: BASIC on/off
-; Bit 0: OS RAM on/off
-;
-; Masks: %11100011 $E3 Bank 0
-; %11100111 $E7 Bank 1
-; %11101011 $EB Bank 2
-; %11101111 $EF Bank 3
-; %11111111 $FF Off
-;
-; Based on the Extended memory driver for the Apple II auxiliary memory
-; by
-; Stefan Haubenthal, 2003-12-12
-; Ullrich von Bassewitz, 2002-12-02
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word DEINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-BANK = $4000 ; bank window
-STACK = $0100 ; stack location
-PAGES = 256 ; 4 x 16k banks
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-.rodata
-banks: .byte $E3,$E7,$EB,$EF ; 130XE banks for cpu banking
-
-stacktest: sei
- ldy banks
- sty $D301
- tax ; A is set by caller
- inx
- stx $4000 ; change $4000
- ldy #$FF ; STACK+13
- sty $D301
- cmp $4000 ; changed?
- beq @1
- sec ; error
- bcs @2
-@1: clc
-@2: sta $4000 ; restore
- cli
- rts
-stacktest_end:
-
-stackcopy: sei ; disable interrupts
-@1: dex ; pre-decrement (full page x=0)
- ldy #$FF ; this will be replaced STACK+3
- sty $D301 ; set bank
- lda $FF00,x ; address to copy from STACK+8,+9
- ldy #$FF ; this will be replaced STACK+11
- sty $D301
- sta $FF00,x ; address to copy to STACK+16,+17
- cpx #0
- bne @1
- ldy #$FF ; portb_save STACK+23
- sty $D301
- cli ; enable interrupts
- rts
-stackcopy_end:
-
-stackcopy_byte: sei
- ldy #$FF ; STACK+2
- sty $D301
- lda $FFFF ; STACK+7 +8
- ldy #$FF ; STACK+10
- sty $D301
- sta $FFFF ; STACK+15 +16
- ldy #$FF ; STACK+18
- sty $D301
- cli
- rts
-stackcopy_byte_end:
-
-
-.data
-curpage: .byte $FF ; Current page number in bank (invalid)
-curbank: .byte $FF ; Current bank number
-
-.bss
-window: .res 256 ; Memory "window"
-portb_save: .res 1 ; portb state
-
-.code
-
-install_transfer:
- ldx #stackcopy_end - stackcopy - 1
-@1: lda stackcopy,x
- sta STACK,x
- dex
- bpl @1
- rts
-
-install_byte_transfer:
- ldx #stackcopy_byte_end - stackcopy_byte - 1
-@2: lda stackcopy_byte,x
- sta STACK,x
- dex
- bpl @2
- rts
-
-install_test:
- ldx #stacktest_end - stacktest - 1
-@3: lda stacktest,x
- sta STACK,x
- dex
- bpl @3
- rts
-
-setpage:
- tax ; save page
- and #$C0 ; mask out bank
- clc
- ror
- ror ; divide by 64
- ror ; 64 pages in each bank
- ror
- ror
- ror
- sta curbank ; Remember the new bank
- txa ; bring back page
- and #$3F ; mask out page
- sta curpage ; curpage in bank
- rts
-
-
-; ------------------------------------------------------------------------
-; 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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- lda $D301 ; save state of portb
- sta portb_save
- tay
-
- jsr install_test ; doesn't touch Y
- sty STACK+13
-
- lda $4000 ; test for extended memory
- jsr STACK
- bcs @1
- lda #EM_ERR_OK
- rts
-@1: lda #EM_ERR_NO_DEVICE
- rts
-
-; ------------------------------------------------------------------------
-; DEINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-DEINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda #<PAGES
- ldx #>PAGES
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: jsr setpage ; extract the bank/page
- add #>BANK ; $4000 + page (carry is cleared)
- sta ptr1+1
- ;ldy #$00
- ;sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
-; Transfer one page
-
- jsr install_transfer ; Transfer one page
-
- ldx curbank
- lda banks,x
- sta STACK+3 ; set bank to copy from
-; lda ptr1
-; sta STACK+8
- lda ptr1+1
- sta STACK+9 ; set copy from address
- lda portb_save
- sta STACK+11 ; set portb restore
- sta STACK+23 ; set final portb restore
- lda ptr2
- sta STACK+16
- lda ptr2+1
- sta STACK+17 ; set copy to address
-
- ldx #0 ; full page copy
- jsr STACK ; do the copy!
-
-; Return the memory window
-
- lda #<window
- ldx #>window ; Return the window address
-
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: ;sta curpage ; Remember the page
- jsr setpage ; extract bank/page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage ; Get the current page
- cmp #$FF
- beq commit_done ; Jump if no page mapped
-
- clc
- add #>BANK
- sta ptr2+1
- ;ldy #$00
- ;sty ptr2
-
- lda #<window
- sta ptr1
- lda #>window
- sta ptr1+1
-
-; Transfer one page/all bytes
-
- jsr install_transfer ; Transfer one page
-
- lda portb_save
- sta STACK+3 ; set bank to copy from
- sta STACK+23 ; set final portb restore
- lda ptr1
- sta STACK+8
- lda ptr1+1
- sta STACK+9 ; set copy from address
- ldx curbank
- lda banks,x
- sta STACK+11 ; set bank to copy to
- ;lda ptr2
- ;sta STACK+16
- lda ptr2+1
- sta STACK+17 ; set copy to address
-
- ldx #0 ; full page copy
- jsr STACK ; do the copy!
-
-commit_done:
- rts
-
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-COPYFROM:
- sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- jsr install_byte_transfer ; install the stack copy routine
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta STACK+7 ; offset goes into BANK low
-
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- sta tmp1 ; save page for later
- ;add #>BANK
- ;sta STACK+8 ; BANK + page goes into BANK high
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta STACK+15 ; buffer goes into dest low
- iny
- lda (ptr3),y
- sta STACK+16 ; buffer goes into dest high
-
- ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- sta ptr4
- iny
- lda (ptr3),y ; Get number of pages
- sta ptr4+1
-
- lda tmp1 ; extract bank/page
- jsr setpage ; sets curbank/curpage
- lda curpage
- add #>BANK ; add to BANK address
- sta STACK+8 ; current page in bank
- ldx curbank
- lda banks,x
- sta STACK+2 ; set bank in stack
- lda portb_save
- sta STACK+10 ; set bank restore in stack
- sta STACK+18 ; set final restore too
-
-copyfrom_copy:
- lda ptr4 ; check if count is zero
- bne @4
- lda ptr4+1
- beq done
-
-@4: jsr STACK ; copy one byte
-
- sec
- lda ptr4
- sub #1
- sta ptr4
- bcs @1
- lda ptr4+1
- beq @1
- sub #1
- sta ptr4+1
-
-@1: inc STACK+7 ; increment address in BANK
- bne @2
- inc STACK+8
- lda STACK+8
- cmp #$80 ; we stepped outside bank
- bne @2
-
- inc curbank ; get next bank
- ldx curbank
- lda banks,x
- sta STACK+2 ; set new bank
- lda #$40 ; set address back to $4000
- sta STACK+8
-
-@2: inc STACK+15 ; increment buffer address
- bne @3
- inc STACK+16
-
-@3: jmp copyfrom_copy ; copy another byte
-
-done:
- rts
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- jsr install_byte_transfer ; install the stack copy routine
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta STACK+15 ; offset goes into BANK low
-
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- sta tmp1 ; save page for later
- ;add #>BANK
- ;sta STACK+16 ; BANK + page goes into BANK high
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta STACK+7 ; buffer goes into dest low
- iny
- lda (ptr3),y
- sta STACK+8 ; buffer goes into dest high
-
- ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- sta ptr4
- iny
- lda (ptr3),y ; Get number of pages
- sta ptr4+1
-
- lda tmp1 ; extract bank/page
- jsr setpage ; sets curbank/curpage
- lda curpage
- add #>BANK ; add to BANK address
- sta STACK+16 ; current page in bank
- ldx curbank
- lda banks,x
- sta STACK+10 ; set bank in stack
- lda portb_save
- sta STACK+2 ; set bank restore in stack
- sta STACK+18 ; set final restore too
-
-copyto_copy:
- lda ptr4 ; check if count is zero
- bne @4
- lda ptr4+1
- beq done
-
-@4: jsr STACK ; copy one byte
-
- sec
- lda ptr4
- sub #1
- sta ptr4
- bcs @1
- lda ptr4+1
- beq @1
- sub #1
- sta ptr4+1
-
-@1: inc STACK+15 ; increment address in BANK
- bne @2
- inc STACK+16
- lda STACK+16
- cmp #$80 ; we stepped outside bank
- bne @2
-
- inc curbank ; get next bank
- ldx curbank
- lda banks,x
- sta STACK+10 ; set new bank
- lda #$40 ; set address back to $4000
- sta STACK+16
-
-@2: inc STACK+7 ; increment buffer address
- bne @3
- inc STACK+8
-
-@3: jmp copyto_copy ; copy another byte
-
+++ /dev/null
-;
-; Graphics driver for the 160x192x2 (CIO mode 14, ANTIC mode C) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 14
-; X resolution
- x_res = 160
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 2
-; Pixels per byte
- ppb = 8
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $0198 ; based on 4/3 display
-; Free memory needed
- mem_needed = 3305
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
- masks: ; Color masks
- .byte %00000000, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
- default_palette:
- .byte $00, $0E
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR4
- lda palette + 1
- sta COLOR0
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 160x192x2 (CIO mode 15, ANTIC mode E) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 15
-; X resolution
- x_res = 160
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 4
-; Pixels per byte
- ppb = 4
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $0198 ; based on 4/3 display
-; Free memory needed
- mem_needed = 7147
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11000000, %00110000, %00001100, %00000011
- masks: ; Color masks
- .byte %00000000, %01010101, %10101010, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %00111111, %00001111, %00000011, %00000000
- default_palette:
- .byte $00, $0E, $32, $96
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR4
- lda palette + 1
- sta COLOR0
- lda palette + 2
- sta COLOR1
- lda palette + 3
- sta COLOR2
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 160x192x2 (CIO mode 15, ANTIC mode E) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 15
-; X resolution
- x_res = 160
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 4
-; Pixels per byte
- ppb = 4
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $0198 ; based on 4/3 display
-; Free memory needed
- mem_needed = 15339
-; Number of screen pages
- pages = 2
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11000000, %00110000, %00001100, %00000011
- masks: ; Color masks
- .byte %00000000, %01010101, %10101010, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %00111111, %00001111, %00000011, %00000000
- default_palette:
- .byte $00, $0E, $32, $96
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR4
- lda palette + 1
- sta COLOR0
- lda palette + 2
- sta COLOR1
- lda palette + 3
- sta COLOR2
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 40x24x4 (CIO mode 3, ANTIC mode 8) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 3
-; X resolution
- x_res = 40
-; Y resolution
- y_res = 24
-; Number of colors
- colors = 4
-; Pixels per byte
- ppb = 4
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $00CC ; based on 4/3 display
-; Free memory needed
- mem_needed = 1
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11000000, %00110000, %00001100, %00000011
- masks: ; Color masks
- .byte %00000000, %01010101, %10101010, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %00111111, %00001111, %00000011, %00000000
- default_palette:
- .byte $00, $0E, $32, $96
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR4
- lda palette + 1
- sta COLOR0
- lda palette + 2
- sta COLOR1
- lda palette + 3
- sta COLOR2
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 80x48x2 (CIO mode 4, ANTIC mode 9) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 4
-; X resolution
- x_res = 80
-; Y resolution
- y_res = 48
-; Number of colors
- colors = 2
-; Pixels per byte
- ppb = 8
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $00CC ; based on 4/3 display
-; Free memory needed
- mem_needed = 1
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
- masks: ; Color masks
- .byte %00000000, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
- default_palette:
- .byte $00, $0E
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR4
- lda palette + 1
- sta COLOR0
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 80x48x4 (CIO mode 5, ANTIC mode A) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 5
-; X resolution
- x_res = 80
-; Y resolution
- y_res = 48
-; Number of colors
- colors = 4
-; Pixels per byte
- ppb = 4
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $00CC ; based on 4/3 display
-; Free memory needed
- mem_needed = 185
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11000000, %00110000, %00001100, %00000011
- masks: ; Color masks
- .byte %00000000, %01010101, %10101010, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %00111111, %00001111, %00000011, %00000000
- default_palette:
- .byte $00, $0E, $32, $96
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR4
- lda palette + 1
- sta COLOR0
- lda palette + 2
- sta COLOR1
- lda palette + 3
- sta COLOR2
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 160x96x2 (CIO mode 6, ANTIC mode B) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 6
-; X resolution
- x_res = 160
-; Y resolution
- y_res = 96
-; Number of colors
- colors = 2
-; Pixels per byte
- ppb = 8
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $00CC ; based on 4/3 display
-; Free memory needed
- mem_needed = 1193
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
- masks: ; Color masks
- .byte %00000000, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
- default_palette:
- .byte $00, $0E
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR4
- lda palette + 1
- sta COLOR0
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 160x96x4 (CIO mode 7, ANTIC mode D) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 7
-; X resolution
- x_res = 160
-; Y resolution
- y_res = 96
-; Number of colors
- colors = 4
-; Pixels per byte
- ppb = 4
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $00CC ; based on 4/3 display
-; Free memory needed
- mem_needed = 3209
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11000000, %00110000, %00001100, %00000011
- masks: ; Color masks
- .byte %00000000, %01010101, %10101010, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %00111111, %00001111, %00000011, %00000000
- default_palette:
- .byte $00, $0E, $32, $96
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR4
- lda palette + 1
- sta COLOR0
- lda palette + 2
- sta COLOR1
- lda palette + 3
- sta COLOR2
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 320x192x2 (CIO mode 8, ANTIC mode F) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 8
-; X resolution
- x_res = 320
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 2
-; Pixels per byte
- ppb = 8
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $00CC ; based on 4/3 display
-; Free memory needed
- mem_needed = 7147
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
- masks: ; Color masks
- .byte %00000000, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
- default_palette:
- .byte $00, $0E
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR2
- lda palette + 1
- sta COLOR1
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 320x192x2 (CIO mode 8, ANTIC mode F) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 8
-; X resolution
- x_res = 320
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 2
-; Pixels per byte
- ppb = 8
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $00CC ; based on 4/3 display
-; Free memory needed
- mem_needed = 15339
-; Number of screen pages
- pages = 2
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
- masks: ; Color masks
- .byte %00000000, %11111111
- bar_table: ; Mask table for BAR
- .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
- default_palette:
- .byte $00, $0E
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Copy the palette
- ldy #colors - 1
-loop: lda (ptr1),y
- sta palette,y
- dey
- bpl loop
-
- ; Get the color entries from the palette
- lda palette
- sta COLOR2
- lda palette + 1
- sta COLOR1
-
- ; Done, reset the error code
- lda #TGI_ERR_OK
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 80x192x16b (CIO mode 9, ANTIC mode F, GTIA mode $40) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 9
-; X resolution
- x_res = 80
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 16
-; Pixels per byte
- ppb = 2
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $0330 ; based on 4/3 display
-; Free memory needed
- mem_needed = 7147
-; Number of screen pages
- pages = 1
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11110000, %00001111
- masks: ; Color masks
- .byte $00, $11, $22, $33, $44, $55, $66, $77, $88, $99, $aa, $bb, $cc, $dd, $ee, $ff
- bar_table: ; Mask table for BAR
- .byte %11111111, %00001111, %00000000
- default_palette:
- .byte $00, $0F, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $0B, $0C, $0D, $0E
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; No palettes
- lda #TGI_ERR_INV_FUNC
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; Graphics driver for the 80x192x16b (CIO mode 9, ANTIC mode F, GTIA mode $40) on the Atari.
-;
-; Fatih Aygun (2009)
-;
-
- .include "atari.inc"
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .macpack generic
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Constants and tables
- ;
- ; ----------------------------------------------------------------------
-
-; Graphics mode
- grmode = 9
-; X resolution
- x_res = 80
-; Y resolution
- y_res = 192
-; Number of colors
- colors = 16
-; Pixels per byte
- ppb = 2
-; Screen memory size in bytes
- scrsize = x_res * y_res / ppb
-; Pixel aspect ratio
- aspect = $0330 ; based on 4/3 display
-; Free memory needed
- mem_needed = 15339
-; Number of screen pages
- pages = 2
-
-.rodata
- mask_table: ; Mask table to set pixels
- .byte %11110000, %00001111
- masks: ; Color masks
- .byte $00, $11, $22, $33, $44, $55, $66, $77, $88, $99, $aa, $bb, $cc, $dd, $ee, $ff
- bar_table: ; Mask table for BAR
- .byte %11111111, %00001111, %00000000
- default_palette:
- .byte $00, $0F, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $0B, $0C, $0D, $0E
-
-.code
-
-; ******************************************************************************
-
-.proc SETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETPALETTE: Set the palette (in ptr1)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; No palettes
- lda #TGI_ERR_INV_FUNC
- sta error
- rts
-.endproc
-
-.include "atari_tgi_common.inc"
+++ /dev/null
-;
-; MultiJoy joystick driver for the Atari. May be used multiple times when linked
-; to the statically application.
-;
-; Ullrich von Bassewitz, 2002-12-21
-; Stefan Haubenthal, 2009-04-10
-; Using code from Carsten Strotmann and help from Christian Groessler
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "atari.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $02 ; JOY_UP
- .byte $04 ; JOY_DOWN
- .byte $08 ; JOY_LEFT
- .byte $10 ; JOY_RIGHT
- .byte $01 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 not available
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READJOY
- .addr 0 ; IRQ entry not used
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 8 ; Number of joysticks we support
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-
-.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 #$30
- sta PACTL
- lda #$F0
- sta PORTA
- lda #$34
- sta PACTL
- lda #JOY_ERR_OK
- ldx #0
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; 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 #0
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READJOY:
- asl a
- asl a
- asl a
- asl a
- sta PORTA
-
-; Read joystick
-
- lda PORTA ; get position
- and #%00001111
- asl a
- ora TRIG0 ; add button information
- eor #%00011111
- ldx #0 ; fix X
- rts
+++ /dev/null
-;
-; Standard joystick driver for the Atari. May be used multiple times when linked
-; to the statically application.
-;
-; Ullrich von Bassewitz, 2002-12-21
-; Using the readjoy code from Christian Groessler
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "atari.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 not available
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READJOY
- .addr 0 ; IRQ entry not used
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 4 ; Number of joysticks we support
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-
-.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 #0
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; 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 $fcd8
- cpx #$a2
- beq _400800
- lsr a ; XL and newer machines only have 2 ports
-_400800:
- ldx #0
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READJOY:
- and #3 ; fix joystick number
- tax ; Joystick number (0-3) into X
-
-; Read joystick
-
- lda STRIG0,x ; get button
- asl a
- asl a
- asl a
- asl a
- ora STICK0,x ; add position information
- eor #$1F
- ldx #0 ; fix X
- rts
+++ /dev/null
-;
-; Generic Atari graphics driver
-;
-
-.macpack longbranch
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Header. Includes jump table and constants.
- ;
- ; ----------------------------------------------------------------------
-
-.segment "JUMPTABLE"
-
-; Header
-
- .byte $74, $67, $69 ; "tgi"
- .byte TGI_API_VERSION ; TGI API version number
- .word x_res ; X resolution
- .word y_res ; Y resolution
- .byte colors ; Number of drawing colors
- .byte pages ; Number of screens available
- .byte 8 ; System font X size
- .byte 8 ; System font Y size
- .word aspect ; Aspect ratio
- .byte 0 ; TGI driver flags
-
-; Function table
-
- .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 TEXTSTYLE
- .addr OUTTEXT
- .addr 0 ; IRQ entry is unused
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Parameters
- ;
- ; ----------------------------------------------------------------------
-
- x1 := ptr1
- y1 := ptr2
- x2 := ptr3
- y2 := ptr4
- radius := tmp1
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Global variables
- ;
- ; ----------------------------------------------------------------------
-
- sptr := regsave + 2
-
-.bss
- error:
- .res 1 ; Error code
-
-.if ::grmode = 9 || ::grmode = 11
- palette = default_palette
-.else
- palette:
- .res colors ; The current palette
-.endif
-
- mask:
- .res 1 ; Current pixel mask
- griocb:
- .res 1 ; IOCB channel number for graphics
-
-.if pages = 2
- p0scr:
- .res 1 ; High byte of screen address for screen page 0
- p0dls:
- .res 1 ; High byte of display list address for screen page 0
- ; Page 1's addresses are 8K higher
-.endif
-
-.data
- mag_x:
- .byte 1 ; Horizontal text scaling factor
- mag_y:
- .byte 1 ; Vertical text scaling factor
- mag_x8:
- .word 8 ; Horizontal text scaling factor * 8
- mag_y8:
- .word 8 ; Vertical text scaling factor * 8
- text_dir:
- .byte 0 ; Text direction,
-
-.code
-
-; ******************************************************************************
-
-.macro put_pixel
-
- ; ----------------------------------------------------------------------
- ;
- ; Put a pixel at (sptr),y using x as the bit mask offset
- ;
- ; ----------------------------------------------------------------------
-
- lda (sptr),y
- eor mask
- and mask_table,x
- eor (sptr),y
- sta (sptr),y
-.endmacro
-
-; ******************************************************************************
-
-.rodata
-screen_device:
- .byte "S:",$9B ; Device code for screen
-screen_device_length := * - screen_device
-
-.code
-
-.proc INIT
-
- ; ----------------------------------------------------------------------
- ;
- ; INIT: Switch to graphics mode
- ;
- ; ----------------------------------------------------------------------
-
-
-.code
- ; Initialize drawing color
-
-.if ::ppb = 8
- ldx #$FF
-.elseif ::ppb = 4
- ldx #$55
-.elseif ::ppb = 2
- ldx #$11
-.endif
-
- stx mask
-
- ; Find a free IOCB
- lda #$70
-search: tax
- ldy ICHID,x
- cpy #$FF
- beq found
- sub #$10
- bcs search
-
- ; Not enough resources available (free IOCB or memory)
- ; enter with C cleared!
-nores: lda #TGI_ERR_NO_RES
- bcc exit
-
-found: ; Check if enough RAM is available
- lda #0
- sub #<mem_needed
- tay
- lda RAMTOP
- sbc #>mem_needed
- cmp APPMHI + 1
- bcc nores
- bne switch
- cpy APPMHI
- bcc nores ; not enough memory
-
- ; Switch into graphics mode
-switch: lda #OPEN
- sta ICCOM,x
- lda #OPNIN | OPNOT
- sta ICAX1,x
- lda #::grmode
- sta ICAX2,x
- lda #<screen_device
- sta ICBAL,x
- lda #>screen_device
- sta ICBAH,x
- lda #<screen_device_length
- sta ICBLL,x
- lda #>screen_device_length
- sta ICBLH,x
- jsr CIOV
-
-.if ::pages = 2
- ; Reserve 8K of high memory
- lda RAMTOP
- sub #32
- sta RAMTOP
- ; Close and reopen graphics
- lda #CLOSE
- sta ICCOM,x
- jsr CIOV
- ; Reopen graphics
- lda #OPEN
- sta ICCOM,x
- lda #OPNIN | OPNOT
- sta ICAX1,x
- lda #::grmode
- sta ICAX2,x
- lda #<screen_device
- sta ICBAL,x
- lda #>screen_device
- sta ICBAH,x
- lda #<screen_device_length
- sta ICBLL,x
- lda #>screen_device_length
- sta ICBLH,x
- jsr CIOV
- ; Save screen pointers
- lda SAVMSC + 1
- sta p0scr
- lda SDLSTH
- sta p0dls
-.endif ; ::pages = 2
-
- stx griocb
-
- ; Reset the error code and return
- lda #TGI_ERR_OK
-exit: sta error
- rts
-.endproc
-
-; ******************************************************************************
-
-.proc DONE
-
- ; ----------------------------------------------------------------------
- ;
- ; DONE: Switch back to text mode
- ;
- ; ----------------------------------------------------------------------
-
-.code
-
-.if ::pages = 2
- ; Free 8K of high memory
- lda RAMTOP
- add #32
- sta RAMTOP
-.endif
-
- ; Clear griocb
- lda #$FF
- ldx griocb
- sta griocb
-
- ; Close the S: device
- lda #CLOSE
- sta ICCOM,x
- jsr CIOV
-
- ; Reopen it in Graphics 0
- lda #OPEN
- sta ICCOM,x
- lda #OPNIN | OPNOT
- sta ICAX1,x
- lda #0
- sta ICAX2,x
- lda #<screen_device
- sta ICBAL,x
- lda #>screen_device
- sta ICBAH,x
- lda #<screen_device_length
- sta ICBLL,x
- lda #>screen_device_length
- sta ICBLH,x
- jsr CIOV
-
- ; Now close it again; we don't need it anymore :)
- lda #CLOSE
- sta ICCOM,x
- jmp CIOV
-.endproc
-
-; ******************************************************************************
-
-.proc GETERROR
-
- ; ----------------------------------------------------------------------
- ;
- ; GETERROR: Return the error code in A and clear it
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ldx #TGI_ERR_OK
- lda error
- stx error
- rts
-.endproc
-
-; ******************************************************************************
-
-.proc CLEAR
-
- ; ----------------------------------------------------------------------
- ;
- ; CLEAR: Clear the screen
- ;
- ; ----------------------------------------------------------------------
-
-.code
- ; Load the screen address in sptr
- lda SAVMSC
- sta sptr
- lda SAVMSC + 1
- sta sptr + 1
-
- ; Fill with zero
- lda #0
- tay
-
-.if >::scrsize > 0
- ; Clear full pages if any
- ldx #>::scrsize
-loop1: sta (sptr),y
- iny
- bne loop1
- inc sptr + 1
- dex
- bne loop1
-.endif
-
-.if <::scrsize > 0
- ; Clear the rest, if any
-loop2: sta (sptr),y
- iny
- cpy #<::scrsize
- bne loop2
-.endif
-
- rts
-.endproc
-
-; ******************************************************************************
-
-.proc GETPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; GETPALETTE: Return the current palette in A/X
- ;
- ; ----------------------------------------------------------------------
-
-.code
- lda #<palette
- ldx #>palette
- rts
-.endproc
-
-; ******************************************************************************
-
-.proc GETDEFPALETTE
-
- ; ----------------------------------------------------------------------
- ;
- ; GETDEFPALETTE: Return the default palette in A/X
- ;
- ; ----------------------------------------------------------------------
-
-.code
- lda #<default_palette
- ldx #>default_palette
- rts
-.endproc
-
-; ******************************************************************************
-
-.proc SETCOLOR
-
- ; ----------------------------------------------------------------------
- ;
- ; SETCOLOR: Set the drawing color (in A)
- ;
- ; ----------------------------------------------------------------------
-
-.code
- tax
-
-.if ::grmode = 9
- ; Map colors like this: 0 -> 0, 1 -> 15, 2 -> 1, 3 -> 2 etc.
- beq cont
- cpx #1
- bne map
- ldx #16
-map: dex
-cont:
-.endif
-
- lda masks,x
- sta mask
- rts
-.endproc
-
-; ******************************************************************************
-
-.proc CALC
-
- ; ----------------------------------------------------------------------
- ;
- ; CALC: Calculate the screen address
- ; in
- ; x1 (ptr1) x coordinate
- ; y1 (ptr2) y coordinate
- ; out
- ; sptr + y screen address
- ; x bit mask index
- ;
- ; ----------------------------------------------------------------------
-
-.bss
- temp: .res 1
-.code
- ; calculate line offset
- lda y1 + 1
- sta temp
- lda y1
-
-.if ::x_res / ::ppb = 40
- yrep = 3
-.elseif ::x_res / ::ppb = 20
- yrep = 2
-.elseif ::x_res / ::ppb = 10
- yrep = 1
-.endif
-
-.repeat yrep
- asl a
- rol temp
-.endrepeat
-
- sta sptr
- ldx temp
- stx sptr + 1
-
-.repeat 2
- asl a
- rol temp
-.endrepeat
-
- add sptr
- sta sptr
- lda temp
- adc sptr + 1
- sta sptr + 1
-
- ; calculate bit mask offset
- lda x1
- and #ppb - 1
- tax
-
- ; calculate row offset
- lda x1 + 1
- sta temp
- lda x1
-
-.if ::ppb = 8
- xrep = 3
-.elseif ::ppb = 4
- xrep = 2
-.elseif ::ppb = 2
- xrep = 1
-.endif
-
-.repeat xrep
- lsr temp
- ror a
-.endrepeat
-
- tay
-
- ; sptr += SAVMSC
- lda SAVMSC
- add sptr
- sta sptr
- lda SAVMSC + 1
- adc sptr + 1
- sta sptr + 1
-
- ; We're done!
- rts
-.endproc
-
-; ******************************************************************************
-
-.proc SETPIXEL
-
- ; ----------------------------------------------------------------------
- ;
- ; Draw one pixel at x1, y1
- ;
- ; ----------------------------------------------------------------------
-
-.code
- jsr CALC
- put_pixel
- rts
-.endproc
-
-; ******************************************************************************
-
-.proc GETPIXEL
-
- ; ----------------------------------------------------------------------
- ;
- ; GETPIXEL: Read the color value of a pixel and return it in A/X
- ;
- ; ----------------------------------------------------------------------
-
-.code
- jsr CALC
- lda (sptr),y
- and mask_table,x
-
-.if ::ppb = 8
- beq zero
- lda #1
-zero: ldx #0
- rts
-.elseif ::ppb = 4
-loop: cpx #3
- beq done4
- lsr a
- lsr a
- inx
- bne loop
-done4: and #$03
- ldx #0
- rts
-.elseif ::ppb = 2
- dex
- bne shift
- and #$0F
- jmp exit
-shift: lsr a
- lsr a
- lsr a
- lsr a
-
-exit:
-
-.if ::grmode = 9
- ; Mode 9 mapping
- ; Map colors like this: 0 -> 0, 15 -> 1, 2 -> 3, 3 -> 4 etc.
- beq done9
- cmp #15
- bne map9
- lda #0
-map9: add #1
-done9:
-.endif
-
-.if ::grmode = 10
- ; Mode 10 mapping
- ; Map out of range colors like this:
- ; 9 -> 8
- ; 10 -> 8
- ; 11 -> 8
- ; 12 -> 0
- ; 13 -> 1
- ; 14 -> 2
- ; 15 -> 3
- cmp #9
- bcc done10
- sub #12
- bcs done10
- lda #8
-done10:
-.endif ; ::grmode = 10
-
- ; Done!
- ldx #0
- rts
-.endif ; ::ppb = 2
-
-.endproc
-
-; ******************************************************************************
-
-.proc LINE
-
- ; ----------------------------------------------------------------------
- ;
- ; LINE: Draw a line from x1,y1 to x2,y2
- ;
- ; ----------------------------------------------------------------------
-
-.ifdef USE_CIO_LINE
-
- ; position ptr1, ptr2
- lda x1
- sta OLDCOL
- lda x1 + 1
- sta OLDCOL + 1
- lda y1
- sta OLDROW
- ; plot
- jsr SETPIXEL
- ; position ptr3,ptr4
- lda x2
- sta COLCRS
- lda x2 + 1
- sta COLCRS + 1
- lda y2
- sta ROWCRS
- ; drawto
- ldx griocb
- lda #DRAWLN
- sta ICCOM,x
- lda mask
-
-.if ::grmode = 10
- and #$0f
-.else
- and #colors - 1
-.endif
-
- sta ATACHR
- jmp CIOV
-
-.else ; USE_CIO_LINE
-
-; locals
-
- dx := sreg
- dy := y1
- dx2 := x2
- dy2 := y2
- iy := tmp1
- err := tmp3
-
-.code
- ; dx = x2 - x1
- lda x2
- sub x1
- sta dx
- lda x2 + 1
- sbc x1 + 1
- sta dx + 1
- ; if dx is positive, no problem
- bcs dx_positive
-
- ; if dx is negative, swap x1,y1 with x2,y2
- lda x1 ; x1 <-> x2, low byte
- ldx x2
- sta x2
- stx x1
- lda x1 + 1 ; x1 <-> x2, high byte
- ldx x2 + 1
- sta x2 + 1
- stx x1 + 1
- lda y1 ; y1 <-> y2, low byte
- ldx y2
- sta y2
- stx y1
- lda y1 + 1 ; y1 <-> y2, high byte
- ldx y2 + 1
- sta y2 + 1
- stx y1 + 1
- ; Calculate again
- jmp LINE
-
-dx_positive:
- ; Calculate coords
- jsr CALC
-
- ; dy = y2 - y1
- lda y2
- sub y1
- sta dy
- lda y2 + 1
- sbc y1 + 1
- sta dy + 1
-
- ; if dy is negative
- bcs dy_positive
- ; dy = -dy
- lda #0
- sub dy
- sta dy
- lda #0
- sbc dy + 1
- sta dy + 1
- ; iy = -row_size
- lda #<(65536 - x_res / ppb)
- sta iy
- lda #>(65536 - x_res / ppb)
- sta iy + 1
- bne skip_iy_1 ; always
-
-dy_positive:
- ; iy = row_size
- lda #<(x_res / ppb)
- sta iy
- lda #>(x_res / ppb)
- sta iy + 1
-skip_iy_1:
-
- ; dx2 = dx * 2
- lda dx
- asl a
- sta dx2
- lda dx + 1
- rol a
- sta dx2 + 1
-
- ; dy2 = dy * 2
- lda dy
- asl a
- sta dy2
- lda dy + 1
- rol a
- sta dy2 + 1
-
- ; if dx >= dy
- lda dx
- cmp dy
- lda dx + 1
- sbc dy + 1
- bcc dy_major
-
- ; dx is the major axis
-
- ; err = dy2 - dx
- lda dy2
- sub dx
- sta err
- lda dy2 + 1
- sbc dx + 1
- sta err + 1
-
- .scope
-loop: ; main loop
- put_pixel
- ; if err >= 0
- lda err + 1
- bmi err_neg
- ; err -= dx2
- lda err
- sub dx2
- sta err
- lda err + 1
- sbc dx2 + 1
- sta err + 1
- ; move_vertical (iy)
- lda sptr
- add iy
- sta sptr
- lda sptr + 1
- adc iy + 1
- sta sptr + 1
-err_neg:
- ; err += dy2
- lda err
- add dy2
- sta err
- lda err + 1
- adc dy2 + 1
- sta err + 1
- ; move_right
- inx
- cpx #ppb
- bne end_move
- ldx #0
- iny
- bne end_move
- inc sptr + 1
-end_move:
- ; loop while dx-- >= 0
- lda dx
- ora dx + 1
- beq exit
- dec dx
- lda dx
- cmp #$FF
- bne loop
- dec dx + 1
- jmp loop
-exit: rts
- .endscope
-
-dy_major:
- ; dy is the major axis
-
- ; err = dx2 - dy;
- lda dx2
- sub dy
- sta err
- lda dx2 + 1
- sbc dy + 1
- sta err + 1
-
- .scope
-loop: ; main loop
- put_pixel
- ; if err >= 0
- lda err + 1
- bmi end_move
- ; err -= dy2
- lda err
- sub dy2
- sta err
- lda err + 1
- sbc dy2 + 1
- sta err + 1
- ; move_right
- inx
- cpx #ppb
- bne end_move
- ldx #0
- iny
- bne end_move
- inc sptr + 1
-end_move:
- ; err += dx2
- lda err
- add dx2
- sta err
- lda err + 1
- adc dx2 + 1
- sta err + 1
- ; move_vertical(iy)
- lda sptr
- add iy
- sta sptr
- lda sptr + 1
- adc iy + 1
- sta sptr + 1
- ; loop while dy-- >= 0
- lda dy
- ora dy + 1
- beq exit
- dec dy
- lda dy
- cmp #$FF
- bne loop
- dec dy + 1
- jmp loop
-exit: rts
- .endscope
-.endif ; USE_CIO_LINE
-.endproc
-
-; ******************************************************************************
-
-.proc clipped_bar
-
- ; ----------------------------------------------------------------------
- ;
- ; Clip and draw bar, this function will disappear when text clipping
- ; will be done int the TGI kernel
- ;
- ; ----------------------------------------------------------------------
-
-.code
- lda y1 + 1
- bne off
- lda y1
- cmp #y_res
- bcs off
-
- lda x1 + 1
-
-.if >(::x_res - 1) > 0
- cmp #>x_res
- bcc check2
-.endif
-
- bne off
- lda x1
- cmp #<x_res
- bcc check2
-off: rts
-
-check2: lda y2 + 1
- bne off
- lda y2
- cmp #y_res
- bcs off
-
- lda x2 + 1
-
-.if >(::x_res - 1) > 0
- cmp #>x_res
- bcc BAR
-.endif
-
- bne off
- lda x2
- cmp #<x_res
- bcs off
-.endproc
-
-; ******************************************************************************
-
-.proc BAR
-
- ; ----------------------------------------------------------------------
- ;
- ; BAR: Draw a filled rectangle with the corners at x1,y1,x2,y2
- ;
- ; ----------------------------------------------------------------------
-
-; locals
- lmem := sreg
-.bss
- lmask: .res 1
- rmask: .res 1
- dy: .res 1
- dx: .res 1
- fmask: .res 1
-.code
- ; dy = y2 - y1 + 1
- lda y2
- sub y1
- sta dy
- inc dy
- ; Calculate upper left corner
- jsr CALC
- ; Save the values
- tya
- add sptr
- sta lmem
- lda sptr + 1
- adc #0
- sta lmem + 1
- lda bar_table,x
- sta lmask
- ; Calculate upper right corner
- lda x2
- sta x1
-
-.if >(::x_res - 1) > 0
- lda x2 + 1
- sta x1 + 1
-.endif
-
- jsr CALC
- ; Save the values
- tya
- add sptr
- sta sptr
- bcc skips
- inc sptr + 1
-skips: inx
- lda bar_table,x
- eor #$FF
- sta rmask
- ; Calculate memory difference between x1 and x2
- lda sptr
- sub lmem
- sta dx
-loop: ; Main loop
- ldy #0
- ldx dx
- beq same
- ; Left
- lda (lmem),y
- eor mask
- and lmask
- eor (lmem),y
- sta (lmem),y
- iny
- ; Between
- lda mask
- jmp next
-btwn: sta (lmem),y
- iny
-next: dex
- bne btwn
- ; Right
- lda (lmem),y
- eor mask
- and rmask
- eor (lmem),y
- sta (lmem),y
- jmp cont
-same: ; Same byte
- lda lmask
- and rmask
- sta fmask
- lda (lmem),y
- eor mask
- and fmask
- eor (lmem),y
- sta (lmem),y
-cont: ; Go to next row
- lda lmem
- add #<(x_res / ppb)
- sta lmem
- bcc skipm
- inc lmem + 1
-skipm: ; Loop while --dy > 0
- dec dy
- bne loop
-
- rts
-
-.endproc
-
-; ******************************************************************************
-
-.proc TEXTSTYLE
-
- ; ----------------------------------------------------------------------
- ;
- ; TEXTSTYLE: Set text style. Scale factors in X and Y and direction in A
- ;
- ; ----------------------------------------------------------------------
-
-.code
- stx mag_x
- sty mag_y
- ; Save text direction in bit 8 so that we can use BIT instruction later
- lsr a
- ror a
- sta text_dir
- ; Save 8 * scaling factors
- lda #0
- sta mag_x8 + 1
- sta mag_y8 + 1
- ; Save 8 * mag_x
- txa
-
- .repeat 3
- asl a
- rol mag_x8 + 1
- .endrepeat
-
- sta mag_x8
- ; Save 8 * mag_y
- tya
-
- .repeat 3
- asl a
- rol mag_y8 + 1
- .endrepeat
-
- sta mag_y8
- ; Done!
- rts
-.endproc
-
-; ******************************************************************************
-
-.proc OUTTEXT
-
- ; ----------------------------------------------------------------------
- ;
- ; OUTTEXT: Draw text at x1, y1. String is in ptr3
- ;
- ; ----------------------------------------------------------------------
-
-; locals
- string := tmp1
- cols := tmp3
- pixels := tmp4
- font := regsave
-.rodata
- ataint: .byte 64,0,32,96
-.bss
- rows: .res 1
-
-.if >(::x_res - 1) > 0
- oldx1: .res 2
- oldx2: .res 2
-.else
- oldx1: .res 1
- oldx2: .res 1
-.endif
-
- oldy1: .res 1
- oldy2: .res 1
- inv: .res 1
-
-.code
- ; Don't draw zero sized characters
- lda mag_x
- ora mag_y
- bne not0
- rts
-
-not0: ; Save string address, ptr3 is needed by BAR
- lda ptr3
- sta string
- lda ptr3 + 1
- sta string + 1
-
- bit text_dir
- bmi vert
-
- ; Calculate x2
- lda mag_x
- sub #1
- add x1
- sta x2
-
-.if >(::x_res - 1) > 0
- lda x1 + 1
- adc #0
- sta x2 + 1
-.else
- lda #0
- sta x2 + 1
-.endif
-
- ; Calculate y2 and adjust y1
- dec y1
- lda y1
- sta y2
- sub mag_y
- add #1
- sta y1
- lda #0
- sta y2 + 1
-
- jmp while
-
- ; Calculate for vertical text
-vert: lda x1
- sub #1
- sta x2
- lda x1 + 1
- sbc #0
- sta x2 + 1
- lda x1
- sub mag_y
- sta x1
- lda x1 + 1
- sbc #0
- sta x1 + 1
-
- lda mag_x
- sub #1
- add y1
- sta y2
- lda #0
- sta y2 + 1
- jmp while
-
- ; Main loop
-loop: inc string
- bne skiph
- inc string + 1
-skiph: ; Save coords
- bit text_dir
- bmi scvert
-
- ldx y1
- stx oldy1
- ldx y2
- stx oldy2
- jmp draw
-
-scvert: ldx x1
- stx oldx1
- ldx x2
- stx oldx2
-
-.if >(::x_res - 1) > 0
- ldx x1 + 1
- stx oldx1 + 1
- ldx x2 + 1
- stx oldx2 + 1
-.endif
-
- ; Draw one character
- ; Convert to ANTIC code
-draw: tay
- rol a
- rol a
- rol a
- rol a
- and #3
- tax
- tya
- and #$9f
- ora ataint,x
- ; Save and clear inverse video bit
- sta inv
- and #$7F
- ; Calculate font data address
- sta font
- lda #0
- sta font + 1
-
- .repeat 3
- asl font
- rol a
- .endrepeat
-
- adc CHBAS
- sta font + 1
- ; Save old coords
- bit text_dir
- bpl hor
- lda y1
- sta oldy1
- lda y2
- sta oldy2
- jmp cont
-hor: lda x1
- sta oldx1
- lda x2
- sta oldx2
-
-.if >(::x_res - 1) > 0
- lda x1 + 1
- sta oldx1 + 1
- lda x2 + 1
- sta oldx2 + 1
-.endif
-
- ; Get glyph pixels
-cont: ldy #7
- ; Put one row of the glyph
-putrow: sty rows
- lda (font),y
- bit inv
- bpl noinv
- eor #$FF
-noinv: sta pixels
- lda #7
- sta cols
- ; Put one column of the row
-putcol: asl pixels
- bcc next_col
- lda x1
- pha
- lda x1 + 1
- pha
- jsr clipped_bar
- pla
- sta x1 + 1
- pla
- sta x1
-next_col:
- ; Go to next column
- ; increase x coords
- bit text_dir
- bmi vertinc
-
- lda mag_x
- add x1
- sta x1
- bcc L1
- inc x1 + 1
-L1: lda mag_x
- add x2
- sta x2
- bcc L2
- inc x2 + 1
- jmp L2
-
-vertinc:
- lda y1
- sub mag_x
- sta y1
- lda y2
- sub mag_x
- sta y2
-L2:
- dec cols
- bpl putcol
-next_row:
- ; Go to next row
- bit text_dir
- bmi verty
-
- lda y1
- sub mag_y
- sta y1
- bcs L3
- dec y1 + 1
-L3: lda y2
- sub mag_y
- sta y2
- bcs L6
- dec y2 + 1
-L4: jmp L6
-
-verty: lda x1
- sub mag_y
- sta x1
- bcs L5
- dec x1 + 1
-L5: lda x2
- sub mag_y
- sta x2
- bcs L6
- dec x2 + 1
-L6:
- ; Restore old values
- bit text_dir
- bpl reshor
- lda oldy1
- sta y1
- lda oldy2
- sta y2
- jmp nextrow
-reshor: lda oldx1
- sta x1
- lda oldx2
- sta x2
-
-.if >(::x_res - 1) > 0
- lda oldx1 + 1
- sta x1 + 1
- lda oldx2 + 1
- sta x2 + 1
-.endif
-
- ; Next row
-nextrow:
- ldy rows
- dey
- jpl putrow
-
- ; Restore coords
- bit text_dir
- bmi resvert
-
- ldx oldy1
- stx y1
- ldx oldy2
- stx y2
- ldx #0
- stx y1 + 1
- stx y2 + 1
-
- lda mag_x8
- add x1
- sta x1
- lda mag_x8 + 1
- adc x1 + 1
- sta x1 + 1
- lda mag_x8
- add x2
- sta x2
- lda mag_x8 + 1
- adc x2 + 1
- sta x2 + 1
-
- jmp while
-
-resvert:
- ldx oldx1
- stx x1
- ldx oldx2
- stx x2
-
-.if >(::x_res - 1) > 0
- ldx oldx1 + 1
- stx x1 + 1
- ldx oldx2 + 1
- stx x2 + 1
-.endif
-
- lda y1
- sub mag_x8
- sta y1
- lda y1 +1
- sbc mag_x8 + 1
- sta y1 + 1
- lda y2
- sub mag_x8
- sta y2
- lda y2 +1
- sbc mag_x8 + 1
- sta y2 + 1
-
- ; End of loop
-while: ldy #0
- lda (string),y
- jne loop ; Check for null character
- rts
-
-.endproc
-
-.if pages = 2
-; ******************************************************************************
-
-.proc SETVIEWPAGE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETVIEWPAGE, page in A
- ;
- ; ----------------------------------------------------------------------
-
-.code
- tax
- beq cont
- lda #32
-
-cont: add p0dls
- cmp SDLSTH
- beq done ; We're already in the desired page
-
- ldx RTCLOK + 2
- sta SDLSTH
-
- ; Wait until next VBLANK
-wait: cpx RTCLOK + 2
- beq wait
-
- ; Done
-done: rts
-.endproc
-
-; ******************************************************************************
-
-.proc SETDRAWPAGE
-
- ; ----------------------------------------------------------------------
- ;
- ; SETDRAWPAGE, page in A
- ;
- ; ----------------------------------------------------------------------
-
-.code
- tax
- beq cont
- lda #32
-cont: add p0scr
- sta SAVMSC + 1
- rts
-.endproc
-.endif
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Unimplemented functions that require an error code
- ;
- ; ----------------------------------------------------------------------
-
-CONTROL:
- lda #TGI_ERR_INV_FUNC
- sta error
- ; fall through
-
-; ******************************************************************************
-
- ; ----------------------------------------------------------------------
- ;
- ; Unimplemented functions that don't require an error code
- ;
- ; ----------------------------------------------------------------------
-
-INSTALL:
-UNINSTALL:
-
-.if pages = 1
-SETVIEWPAGE:
-SETDRAWPAGE:
-.endif
-
- rts
--- /dev/null
+;
+; Extended memory driver for the Atari 130XE memory standard
+; Shawn Jefferson, 2012-08-11
+;
+; Banking Register $D301:
+; Bit 7: Self-Test on/off
+; Bit 6: Unused
+; Bit 5: Antic sees bank
+; Bit 4: CPU sees bank
+; Bit 3: bank control
+; Bit 2: bank control
+; Bit 1: BASIC on/off
+; Bit 0: OS RAM on/off
+;
+; Masks: %11100011 $E3 Bank 0
+; %11100111 $E7 Bank 1
+; %11101011 $EB Bank 2
+; %11101111 $EF Bank 3
+; %11111111 $FF Off
+;
+; Based on the Extended memory driver for the Apple II auxiliary memory
+; by
+; Stefan Haubenthal, 2003-12-12
+; Ullrich von Bassewitz, 2002-12-02
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word DEINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BANK = $4000 ; bank window
+STACK = $0100 ; stack location
+PAGES = 256 ; 4 x 16k banks
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+.rodata
+banks: .byte $E3,$E7,$EB,$EF ; 130XE banks for cpu banking
+
+stacktest: sei
+ ldy banks
+ sty $D301
+ tax ; A is set by caller
+ inx
+ stx $4000 ; change $4000
+ ldy #$FF ; STACK+13
+ sty $D301
+ cmp $4000 ; changed?
+ beq @1
+ sec ; error
+ bcs @2
+@1: clc
+@2: sta $4000 ; restore
+ cli
+ rts
+stacktest_end:
+
+stackcopy: sei ; disable interrupts
+@1: dex ; pre-decrement (full page x=0)
+ ldy #$FF ; this will be replaced STACK+3
+ sty $D301 ; set bank
+ lda $FF00,x ; address to copy from STACK+8,+9
+ ldy #$FF ; this will be replaced STACK+11
+ sty $D301
+ sta $FF00,x ; address to copy to STACK+16,+17
+ cpx #0
+ bne @1
+ ldy #$FF ; portb_save STACK+23
+ sty $D301
+ cli ; enable interrupts
+ rts
+stackcopy_end:
+
+stackcopy_byte: sei
+ ldy #$FF ; STACK+2
+ sty $D301
+ lda $FFFF ; STACK+7 +8
+ ldy #$FF ; STACK+10
+ sty $D301
+ sta $FFFF ; STACK+15 +16
+ ldy #$FF ; STACK+18
+ sty $D301
+ cli
+ rts
+stackcopy_byte_end:
+
+
+.data
+curpage: .byte $FF ; Current page number in bank (invalid)
+curbank: .byte $FF ; Current bank number
+
+.bss
+window: .res 256 ; Memory "window"
+portb_save: .res 1 ; portb state
+
+.code
+
+install_transfer:
+ ldx #stackcopy_end - stackcopy - 1
+@1: lda stackcopy,x
+ sta STACK,x
+ dex
+ bpl @1
+ rts
+
+install_byte_transfer:
+ ldx #stackcopy_byte_end - stackcopy_byte - 1
+@2: lda stackcopy_byte,x
+ sta STACK,x
+ dex
+ bpl @2
+ rts
+
+install_test:
+ ldx #stacktest_end - stacktest - 1
+@3: lda stacktest,x
+ sta STACK,x
+ dex
+ bpl @3
+ rts
+
+setpage:
+ tax ; save page
+ and #$C0 ; mask out bank
+ clc
+ ror
+ ror ; divide by 64
+ ror ; 64 pages in each bank
+ ror
+ ror
+ ror
+ sta curbank ; Remember the new bank
+ txa ; bring back page
+ and #$3F ; mask out page
+ sta curpage ; curpage in bank
+ rts
+
+
+; ------------------------------------------------------------------------
+; 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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ lda $D301 ; save state of portb
+ sta portb_save
+ tay
+
+ jsr install_test ; doesn't touch Y
+ sty STACK+13
+
+ lda $4000 ; test for extended memory
+ jsr STACK
+ bcs @1
+ lda #EM_ERR_OK
+ rts
+@1: lda #EM_ERR_NO_DEVICE
+ rts
+
+; ------------------------------------------------------------------------
+; DEINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+DEINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda #<PAGES
+ ldx #>PAGES
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: jsr setpage ; extract the bank/page
+ add #>BANK ; $4000 + page (carry is cleared)
+ sta ptr1+1
+ ;ldy #$00
+ ;sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+; Transfer one page
+
+ jsr install_transfer ; Transfer one page
+
+ ldx curbank
+ lda banks,x
+ sta STACK+3 ; set bank to copy from
+; lda ptr1
+; sta STACK+8
+ lda ptr1+1
+ sta STACK+9 ; set copy from address
+ lda portb_save
+ sta STACK+11 ; set portb restore
+ sta STACK+23 ; set final portb restore
+ lda ptr2
+ sta STACK+16
+ lda ptr2+1
+ sta STACK+17 ; set copy to address
+
+ ldx #0 ; full page copy
+ jsr STACK ; do the copy!
+
+; Return the memory window
+
+ lda #<window
+ ldx #>window ; Return the window address
+
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: ;sta curpage ; Remember the page
+ jsr setpage ; extract bank/page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage ; Get the current page
+ cmp #$FF
+ beq commit_done ; Jump if no page mapped
+
+ clc
+ add #>BANK
+ sta ptr2+1
+ ;ldy #$00
+ ;sty ptr2
+
+ lda #<window
+ sta ptr1
+ lda #>window
+ sta ptr1+1
+
+; Transfer one page/all bytes
+
+ jsr install_transfer ; Transfer one page
+
+ lda portb_save
+ sta STACK+3 ; set bank to copy from
+ sta STACK+23 ; set final portb restore
+ lda ptr1
+ sta STACK+8
+ lda ptr1+1
+ sta STACK+9 ; set copy from address
+ ldx curbank
+ lda banks,x
+ sta STACK+11 ; set bank to copy to
+ ;lda ptr2
+ ;sta STACK+16
+ lda ptr2+1
+ sta STACK+17 ; set copy to address
+
+ ldx #0 ; full page copy
+ jsr STACK ; do the copy!
+
+commit_done:
+ rts
+
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+COPYFROM:
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ jsr install_byte_transfer ; install the stack copy routine
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta STACK+7 ; offset goes into BANK low
+
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ sta tmp1 ; save page for later
+ ;add #>BANK
+ ;sta STACK+8 ; BANK + page goes into BANK high
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta STACK+15 ; buffer goes into dest low
+ iny
+ lda (ptr3),y
+ sta STACK+16 ; buffer goes into dest high
+
+ ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ sta ptr4
+ iny
+ lda (ptr3),y ; Get number of pages
+ sta ptr4+1
+
+ lda tmp1 ; extract bank/page
+ jsr setpage ; sets curbank/curpage
+ lda curpage
+ add #>BANK ; add to BANK address
+ sta STACK+8 ; current page in bank
+ ldx curbank
+ lda banks,x
+ sta STACK+2 ; set bank in stack
+ lda portb_save
+ sta STACK+10 ; set bank restore in stack
+ sta STACK+18 ; set final restore too
+
+copyfrom_copy:
+ lda ptr4 ; check if count is zero
+ bne @4
+ lda ptr4+1
+ beq done
+
+@4: jsr STACK ; copy one byte
+
+ sec
+ lda ptr4
+ sub #1
+ sta ptr4
+ bcs @1
+ lda ptr4+1
+ beq @1
+ sub #1
+ sta ptr4+1
+
+@1: inc STACK+7 ; increment address in BANK
+ bne @2
+ inc STACK+8
+ lda STACK+8
+ cmp #$80 ; we stepped outside bank
+ bne @2
+
+ inc curbank ; get next bank
+ ldx curbank
+ lda banks,x
+ sta STACK+2 ; set new bank
+ lda #$40 ; set address back to $4000
+ sta STACK+8
+
+@2: inc STACK+15 ; increment buffer address
+ bne @3
+ inc STACK+16
+
+@3: jmp copyfrom_copy ; copy another byte
+
+done:
+ rts
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ jsr install_byte_transfer ; install the stack copy routine
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta STACK+15 ; offset goes into BANK low
+
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ sta tmp1 ; save page for later
+ ;add #>BANK
+ ;sta STACK+16 ; BANK + page goes into BANK high
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta STACK+7 ; buffer goes into dest low
+ iny
+ lda (ptr3),y
+ sta STACK+8 ; buffer goes into dest high
+
+ ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ sta ptr4
+ iny
+ lda (ptr3),y ; Get number of pages
+ sta ptr4+1
+
+ lda tmp1 ; extract bank/page
+ jsr setpage ; sets curbank/curpage
+ lda curpage
+ add #>BANK ; add to BANK address
+ sta STACK+16 ; current page in bank
+ ldx curbank
+ lda banks,x
+ sta STACK+10 ; set bank in stack
+ lda portb_save
+ sta STACK+2 ; set bank restore in stack
+ sta STACK+18 ; set final restore too
+
+copyto_copy:
+ lda ptr4 ; check if count is zero
+ bne @4
+ lda ptr4+1
+ beq done
+
+@4: jsr STACK ; copy one byte
+
+ sec
+ lda ptr4
+ sub #1
+ sta ptr4
+ bcs @1
+ lda ptr4+1
+ beq @1
+ sub #1
+ sta ptr4+1
+
+@1: inc STACK+15 ; increment address in BANK
+ bne @2
+ inc STACK+16
+ lda STACK+16
+ cmp #$80 ; we stepped outside bank
+ bne @2
+
+ inc curbank ; get next bank
+ ldx curbank
+ lda banks,x
+ sta STACK+10 ; set new bank
+ lda #$40 ; set address back to $4000
+ sta STACK+16
+
+@2: inc STACK+7 ; increment buffer address
+ bne @3
+ inc STACK+8
+
+@3: jmp copyto_copy ; copy another byte
+
--- /dev/null
+;
+; MultiJoy joystick driver for the Atari. May be used multiple times when linked
+; to the statically application.
+;
+; Ullrich von Bassewitz, 2002-12-21
+; Stefan Haubenthal, 2009-04-10
+; Using code from Carsten Strotmann and help from Christian Groessler
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "atari.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $02 ; JOY_UP
+ .byte $04 ; JOY_DOWN
+ .byte $08 ; JOY_LEFT
+ .byte $10 ; JOY_RIGHT
+ .byte $01 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 not available
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READJOY
+ .addr 0 ; IRQ entry not used
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 8 ; Number of joysticks we support
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+
+.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 #$30
+ sta PACTL
+ lda #$F0
+ sta PORTA
+ lda #$34
+ sta PACTL
+ lda #JOY_ERR_OK
+ ldx #0
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; 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 #0
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READJOY:
+ asl a
+ asl a
+ asl a
+ asl a
+ sta PORTA
+
+; Read joystick
+
+ lda PORTA ; get position
+ and #%00001111
+ asl a
+ ora TRIG0 ; add button information
+ eor #%00011111
+ ldx #0 ; fix X
+ rts
--- /dev/null
+;
+; Standard joystick driver for the Atari. May be used multiple times when linked
+; to the statically application.
+;
+; Ullrich von Bassewitz, 2002-12-21
+; Using the readjoy code from Christian Groessler
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "atari.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 not available
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READJOY
+ .addr 0 ; IRQ entry not used
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 4 ; Number of joysticks we support
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+
+.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 #0
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; 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 $fcd8
+ cpx #$a2
+ beq _400800
+ lsr a ; XL and newer machines only have 2 ports
+_400800:
+ ldx #0
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READJOY:
+ and #3 ; fix joystick number
+ tax ; Joystick number (0-3) into X
+
+; Read joystick
+
+ lda STRIG0,x ; get button
+ asl a
+ asl a
+ asl a
+ asl a
+ ora STICK0,x ; add position information
+ eor #$1F
+ ldx #0 ; fix X
+ rts
--- /dev/null
+;
+; Graphics driver for the 80x192x9 (CIO mode 10, ANTIC mode F, GTIA mode $80) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 10
+; X resolution
+ x_res = 80
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 9
+; Pixels per byte
+ ppb = 2
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $0330 ; based on 4/3 display
+; Free memory needed
+ mem_needed = 7147
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11110000, %00001111
+ masks: ; Color masks
+ .byte $00, $11, $22, $33, $44, $55, $66, $77, $88
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00001111, %00000000
+ default_palette:
+ .byte $00, $0E, $32, $96, $68, $C4, $74, $EE, $4A
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ sta PCOLR0,y
+ dey
+ bpl loop
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 80x192x16h (CIO mode 11, ANTIC mode F, GTIA mode $C0) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 11
+; X resolution
+ x_res = 80
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 16
+; Pixels per byte
+ ppb = 2
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $0330 ; based on 4/3 display
+; Free memory needed
+ mem_needed = 7147
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11110000, %00001111
+ masks: ; Color masks
+ .byte $00, $11, $22, $33, $44, $55, $66, $77, $88, $99, $aa, $bb, $cc, $dd, $ee, $ff
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00001111, %00000000
+ default_palette:
+ .byte $00, $10, $20, $30, $40, $50, $60, $70, $80, $90, $A0, $B0, $C0, $D0, $E0, $F0
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; No palettes
+ lda #TGI_ERR_INV_FUNC
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 160x192x2 (CIO mode 14, ANTIC mode C) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 14
+; X resolution
+ x_res = 160
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 2
+; Pixels per byte
+ ppb = 8
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $0198 ; based on 4/3 display
+; Free memory needed
+ mem_needed = 3305
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
+ masks: ; Color masks
+ .byte %00000000, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
+ default_palette:
+ .byte $00, $0E
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR4
+ lda palette + 1
+ sta COLOR0
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 160x192x2 (CIO mode 15, ANTIC mode E) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 15
+; X resolution
+ x_res = 160
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 4
+; Pixels per byte
+ ppb = 4
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $0198 ; based on 4/3 display
+; Free memory needed
+ mem_needed = 7147
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11000000, %00110000, %00001100, %00000011
+ masks: ; Color masks
+ .byte %00000000, %01010101, %10101010, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00111111, %00001111, %00000011, %00000000
+ default_palette:
+ .byte $00, $0E, $32, $96
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR4
+ lda palette + 1
+ sta COLOR0
+ lda palette + 2
+ sta COLOR1
+ lda palette + 3
+ sta COLOR2
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 40x24x4 (CIO mode 3, ANTIC mode 8) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 3
+; X resolution
+ x_res = 40
+; Y resolution
+ y_res = 24
+; Number of colors
+ colors = 4
+; Pixels per byte
+ ppb = 4
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $00CC ; based on 4/3 display
+; Free memory needed
+ mem_needed = 1
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11000000, %00110000, %00001100, %00000011
+ masks: ; Color masks
+ .byte %00000000, %01010101, %10101010, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00111111, %00001111, %00000011, %00000000
+ default_palette:
+ .byte $00, $0E, $32, $96
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR4
+ lda palette + 1
+ sta COLOR0
+ lda palette + 2
+ sta COLOR1
+ lda palette + 3
+ sta COLOR2
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 80x48x2 (CIO mode 4, ANTIC mode 9) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 4
+; X resolution
+ x_res = 80
+; Y resolution
+ y_res = 48
+; Number of colors
+ colors = 2
+; Pixels per byte
+ ppb = 8
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $00CC ; based on 4/3 display
+; Free memory needed
+ mem_needed = 1
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
+ masks: ; Color masks
+ .byte %00000000, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
+ default_palette:
+ .byte $00, $0E
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR4
+ lda palette + 1
+ sta COLOR0
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 80x48x4 (CIO mode 5, ANTIC mode A) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 5
+; X resolution
+ x_res = 80
+; Y resolution
+ y_res = 48
+; Number of colors
+ colors = 4
+; Pixels per byte
+ ppb = 4
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $00CC ; based on 4/3 display
+; Free memory needed
+ mem_needed = 185
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11000000, %00110000, %00001100, %00000011
+ masks: ; Color masks
+ .byte %00000000, %01010101, %10101010, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00111111, %00001111, %00000011, %00000000
+ default_palette:
+ .byte $00, $0E, $32, $96
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR4
+ lda palette + 1
+ sta COLOR0
+ lda palette + 2
+ sta COLOR1
+ lda palette + 3
+ sta COLOR2
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 160x96x2 (CIO mode 6, ANTIC mode B) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 6
+; X resolution
+ x_res = 160
+; Y resolution
+ y_res = 96
+; Number of colors
+ colors = 2
+; Pixels per byte
+ ppb = 8
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $00CC ; based on 4/3 display
+; Free memory needed
+ mem_needed = 1193
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
+ masks: ; Color masks
+ .byte %00000000, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
+ default_palette:
+ .byte $00, $0E
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR4
+ lda palette + 1
+ sta COLOR0
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 160x96x4 (CIO mode 7, ANTIC mode D) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 7
+; X resolution
+ x_res = 160
+; Y resolution
+ y_res = 96
+; Number of colors
+ colors = 4
+; Pixels per byte
+ ppb = 4
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $00CC ; based on 4/3 display
+; Free memory needed
+ mem_needed = 3209
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11000000, %00110000, %00001100, %00000011
+ masks: ; Color masks
+ .byte %00000000, %01010101, %10101010, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00111111, %00001111, %00000011, %00000000
+ default_palette:
+ .byte $00, $0E, $32, $96
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR4
+ lda palette + 1
+ sta COLOR0
+ lda palette + 2
+ sta COLOR1
+ lda palette + 3
+ sta COLOR2
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 320x192x2 (CIO mode 8, ANTIC mode F) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 8
+; X resolution
+ x_res = 320
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 2
+; Pixels per byte
+ ppb = 8
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $00CC ; based on 4/3 display
+; Free memory needed
+ mem_needed = 7147
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
+ masks: ; Color masks
+ .byte %00000000, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
+ default_palette:
+ .byte $00, $0E
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR2
+ lda palette + 1
+ sta COLOR1
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 80x192x16b (CIO mode 9, ANTIC mode F, GTIA mode $40) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 9
+; X resolution
+ x_res = 80
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 16
+; Pixels per byte
+ ppb = 2
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $0330 ; based on 4/3 display
+; Free memory needed
+ mem_needed = 7147
+; Number of screen pages
+ pages = 1
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11110000, %00001111
+ masks: ; Color masks
+ .byte $00, $11, $22, $33, $44, $55, $66, $77, $88, $99, $aa, $bb, $cc, $dd, $ee, $ff
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00001111, %00000000
+ default_palette:
+ .byte $00, $0F, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $0B, $0C, $0D, $0E
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; No palettes
+ lda #TGI_ERR_INV_FUNC
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Generic Atari graphics driver
+;
+
+.macpack longbranch
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Header. Includes jump table and constants.
+ ;
+ ; ----------------------------------------------------------------------
+
+.segment "JUMPTABLE"
+
+; Header
+
+ .byte $74, $67, $69 ; "tgi"
+ .byte TGI_API_VERSION ; TGI API version number
+ .word x_res ; X resolution
+ .word y_res ; Y resolution
+ .byte colors ; Number of drawing colors
+ .byte pages ; Number of screens available
+ .byte 8 ; System font X size
+ .byte 8 ; System font Y size
+ .word aspect ; Aspect ratio
+ .byte 0 ; TGI driver flags
+
+; Function table
+
+ .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 TEXTSTYLE
+ .addr OUTTEXT
+ .addr 0 ; IRQ entry is unused
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Parameters
+ ;
+ ; ----------------------------------------------------------------------
+
+ x1 := ptr1
+ y1 := ptr2
+ x2 := ptr3
+ y2 := ptr4
+ radius := tmp1
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Global variables
+ ;
+ ; ----------------------------------------------------------------------
+
+ sptr := regsave + 2
+
+.bss
+ error:
+ .res 1 ; Error code
+
+.if ::grmode = 9 || ::grmode = 11
+ palette = default_palette
+.else
+ palette:
+ .res colors ; The current palette
+.endif
+
+ mask:
+ .res 1 ; Current pixel mask
+ griocb:
+ .res 1 ; IOCB channel number for graphics
+
+.if pages = 2
+ p0scr:
+ .res 1 ; High byte of screen address for screen page 0
+ p0dls:
+ .res 1 ; High byte of display list address for screen page 0
+ ; Page 1's addresses are 8K higher
+.endif
+
+.data
+ mag_x:
+ .byte 1 ; Horizontal text scaling factor
+ mag_y:
+ .byte 1 ; Vertical text scaling factor
+ mag_x8:
+ .word 8 ; Horizontal text scaling factor * 8
+ mag_y8:
+ .word 8 ; Vertical text scaling factor * 8
+ text_dir:
+ .byte 0 ; Text direction,
+
+.code
+
+; ******************************************************************************
+
+.macro put_pixel
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Put a pixel at (sptr),y using x as the bit mask offset
+ ;
+ ; ----------------------------------------------------------------------
+
+ lda (sptr),y
+ eor mask
+ and mask_table,x
+ eor (sptr),y
+ sta (sptr),y
+.endmacro
+
+; ******************************************************************************
+
+.rodata
+screen_device:
+ .byte "S:",$9B ; Device code for screen
+screen_device_length := * - screen_device
+
+.code
+
+.proc INIT
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; INIT: Switch to graphics mode
+ ;
+ ; ----------------------------------------------------------------------
+
+
+.code
+ ; Initialize drawing color
+
+.if ::ppb = 8
+ ldx #$FF
+.elseif ::ppb = 4
+ ldx #$55
+.elseif ::ppb = 2
+ ldx #$11
+.endif
+
+ stx mask
+
+ ; Find a free IOCB
+ lda #$70
+search: tax
+ ldy ICHID,x
+ cpy #$FF
+ beq found
+ sub #$10
+ bcs search
+
+ ; Not enough resources available (free IOCB or memory)
+ ; enter with C cleared!
+nores: lda #TGI_ERR_NO_RES
+ bcc exit
+
+found: ; Check if enough RAM is available
+ lda #0
+ sub #<mem_needed
+ tay
+ lda RAMTOP
+ sbc #>mem_needed
+ cmp APPMHI + 1
+ bcc nores
+ bne switch
+ cpy APPMHI
+ bcc nores ; not enough memory
+
+ ; Switch into graphics mode
+switch: lda #OPEN
+ sta ICCOM,x
+ lda #OPNIN | OPNOT
+ sta ICAX1,x
+ lda #::grmode
+ sta ICAX2,x
+ lda #<screen_device
+ sta ICBAL,x
+ lda #>screen_device
+ sta ICBAH,x
+ lda #<screen_device_length
+ sta ICBLL,x
+ lda #>screen_device_length
+ sta ICBLH,x
+ jsr CIOV
+
+.if ::pages = 2
+ ; Reserve 8K of high memory
+ lda RAMTOP
+ sub #32
+ sta RAMTOP
+ ; Close and reopen graphics
+ lda #CLOSE
+ sta ICCOM,x
+ jsr CIOV
+ ; Reopen graphics
+ lda #OPEN
+ sta ICCOM,x
+ lda #OPNIN | OPNOT
+ sta ICAX1,x
+ lda #::grmode
+ sta ICAX2,x
+ lda #<screen_device
+ sta ICBAL,x
+ lda #>screen_device
+ sta ICBAH,x
+ lda #<screen_device_length
+ sta ICBLL,x
+ lda #>screen_device_length
+ sta ICBLH,x
+ jsr CIOV
+ ; Save screen pointers
+ lda SAVMSC + 1
+ sta p0scr
+ lda SDLSTH
+ sta p0dls
+.endif ; ::pages = 2
+
+ stx griocb
+
+ ; Reset the error code and return
+ lda #TGI_ERR_OK
+exit: sta error
+ rts
+.endproc
+
+; ******************************************************************************
+
+.proc DONE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; DONE: Switch back to text mode
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+
+.if ::pages = 2
+ ; Free 8K of high memory
+ lda RAMTOP
+ add #32
+ sta RAMTOP
+.endif
+
+ ; Clear griocb
+ lda #$FF
+ ldx griocb
+ sta griocb
+
+ ; Close the S: device
+ lda #CLOSE
+ sta ICCOM,x
+ jsr CIOV
+
+ ; Reopen it in Graphics 0
+ lda #OPEN
+ sta ICCOM,x
+ lda #OPNIN | OPNOT
+ sta ICAX1,x
+ lda #0
+ sta ICAX2,x
+ lda #<screen_device
+ sta ICBAL,x
+ lda #>screen_device
+ sta ICBAH,x
+ lda #<screen_device_length
+ sta ICBLL,x
+ lda #>screen_device_length
+ sta ICBLH,x
+ jsr CIOV
+
+ ; Now close it again; we don't need it anymore :)
+ lda #CLOSE
+ sta ICCOM,x
+ jmp CIOV
+.endproc
+
+; ******************************************************************************
+
+.proc GETERROR
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; GETERROR: Return the error code in A and clear it
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ldx #TGI_ERR_OK
+ lda error
+ stx error
+ rts
+.endproc
+
+; ******************************************************************************
+
+.proc CLEAR
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; CLEAR: Clear the screen
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Load the screen address in sptr
+ lda SAVMSC
+ sta sptr
+ lda SAVMSC + 1
+ sta sptr + 1
+
+ ; Fill with zero
+ lda #0
+ tay
+
+.if >::scrsize > 0
+ ; Clear full pages if any
+ ldx #>::scrsize
+loop1: sta (sptr),y
+ iny
+ bne loop1
+ inc sptr + 1
+ dex
+ bne loop1
+.endif
+
+.if <::scrsize > 0
+ ; Clear the rest, if any
+loop2: sta (sptr),y
+ iny
+ cpy #<::scrsize
+ bne loop2
+.endif
+
+ rts
+.endproc
+
+; ******************************************************************************
+
+.proc GETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; GETPALETTE: Return the current palette in A/X
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ lda #<palette
+ ldx #>palette
+ rts
+.endproc
+
+; ******************************************************************************
+
+.proc GETDEFPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; GETDEFPALETTE: Return the default palette in A/X
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ lda #<default_palette
+ ldx #>default_palette
+ rts
+.endproc
+
+; ******************************************************************************
+
+.proc SETCOLOR
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETCOLOR: Set the drawing color (in A)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ tax
+
+.if ::grmode = 9
+ ; Map colors like this: 0 -> 0, 1 -> 15, 2 -> 1, 3 -> 2 etc.
+ beq cont
+ cpx #1
+ bne map
+ ldx #16
+map: dex
+cont:
+.endif
+
+ lda masks,x
+ sta mask
+ rts
+.endproc
+
+; ******************************************************************************
+
+.proc CALC
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; CALC: Calculate the screen address
+ ; in
+ ; x1 (ptr1) x coordinate
+ ; y1 (ptr2) y coordinate
+ ; out
+ ; sptr + y screen address
+ ; x bit mask index
+ ;
+ ; ----------------------------------------------------------------------
+
+.bss
+ temp: .res 1
+.code
+ ; calculate line offset
+ lda y1 + 1
+ sta temp
+ lda y1
+
+.if ::x_res / ::ppb = 40
+ yrep = 3
+.elseif ::x_res / ::ppb = 20
+ yrep = 2
+.elseif ::x_res / ::ppb = 10
+ yrep = 1
+.endif
+
+.repeat yrep
+ asl a
+ rol temp
+.endrepeat
+
+ sta sptr
+ ldx temp
+ stx sptr + 1
+
+.repeat 2
+ asl a
+ rol temp
+.endrepeat
+
+ add sptr
+ sta sptr
+ lda temp
+ adc sptr + 1
+ sta sptr + 1
+
+ ; calculate bit mask offset
+ lda x1
+ and #ppb - 1
+ tax
+
+ ; calculate row offset
+ lda x1 + 1
+ sta temp
+ lda x1
+
+.if ::ppb = 8
+ xrep = 3
+.elseif ::ppb = 4
+ xrep = 2
+.elseif ::ppb = 2
+ xrep = 1
+.endif
+
+.repeat xrep
+ lsr temp
+ ror a
+.endrepeat
+
+ tay
+
+ ; sptr += SAVMSC
+ lda SAVMSC
+ add sptr
+ sta sptr
+ lda SAVMSC + 1
+ adc sptr + 1
+ sta sptr + 1
+
+ ; We're done!
+ rts
+.endproc
+
+; ******************************************************************************
+
+.proc SETPIXEL
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Draw one pixel at x1, y1
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ jsr CALC
+ put_pixel
+ rts
+.endproc
+
+; ******************************************************************************
+
+.proc GETPIXEL
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; GETPIXEL: Read the color value of a pixel and return it in A/X
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ jsr CALC
+ lda (sptr),y
+ and mask_table,x
+
+.if ::ppb = 8
+ beq zero
+ lda #1
+zero: ldx #0
+ rts
+.elseif ::ppb = 4
+loop: cpx #3
+ beq done4
+ lsr a
+ lsr a
+ inx
+ bne loop
+done4: and #$03
+ ldx #0
+ rts
+.elseif ::ppb = 2
+ dex
+ bne shift
+ and #$0F
+ jmp exit
+shift: lsr a
+ lsr a
+ lsr a
+ lsr a
+
+exit:
+
+.if ::grmode = 9
+ ; Mode 9 mapping
+ ; Map colors like this: 0 -> 0, 15 -> 1, 2 -> 3, 3 -> 4 etc.
+ beq done9
+ cmp #15
+ bne map9
+ lda #0
+map9: add #1
+done9:
+.endif
+
+.if ::grmode = 10
+ ; Mode 10 mapping
+ ; Map out of range colors like this:
+ ; 9 -> 8
+ ; 10 -> 8
+ ; 11 -> 8
+ ; 12 -> 0
+ ; 13 -> 1
+ ; 14 -> 2
+ ; 15 -> 3
+ cmp #9
+ bcc done10
+ sub #12
+ bcs done10
+ lda #8
+done10:
+.endif ; ::grmode = 10
+
+ ; Done!
+ ldx #0
+ rts
+.endif ; ::ppb = 2
+
+.endproc
+
+; ******************************************************************************
+
+.proc LINE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; LINE: Draw a line from x1,y1 to x2,y2
+ ;
+ ; ----------------------------------------------------------------------
+
+.ifdef USE_CIO_LINE
+
+ ; position ptr1, ptr2
+ lda x1
+ sta OLDCOL
+ lda x1 + 1
+ sta OLDCOL + 1
+ lda y1
+ sta OLDROW
+ ; plot
+ jsr SETPIXEL
+ ; position ptr3,ptr4
+ lda x2
+ sta COLCRS
+ lda x2 + 1
+ sta COLCRS + 1
+ lda y2
+ sta ROWCRS
+ ; drawto
+ ldx griocb
+ lda #DRAWLN
+ sta ICCOM,x
+ lda mask
+
+.if ::grmode = 10
+ and #$0f
+.else
+ and #colors - 1
+.endif
+
+ sta ATACHR
+ jmp CIOV
+
+.else ; USE_CIO_LINE
+
+; locals
+
+ dx := sreg
+ dy := y1
+ dx2 := x2
+ dy2 := y2
+ iy := tmp1
+ err := tmp3
+
+.code
+ ; dx = x2 - x1
+ lda x2
+ sub x1
+ sta dx
+ lda x2 + 1
+ sbc x1 + 1
+ sta dx + 1
+ ; if dx is positive, no problem
+ bcs dx_positive
+
+ ; if dx is negative, swap x1,y1 with x2,y2
+ lda x1 ; x1 <-> x2, low byte
+ ldx x2
+ sta x2
+ stx x1
+ lda x1 + 1 ; x1 <-> x2, high byte
+ ldx x2 + 1
+ sta x2 + 1
+ stx x1 + 1
+ lda y1 ; y1 <-> y2, low byte
+ ldx y2
+ sta y2
+ stx y1
+ lda y1 + 1 ; y1 <-> y2, high byte
+ ldx y2 + 1
+ sta y2 + 1
+ stx y1 + 1
+ ; Calculate again
+ jmp LINE
+
+dx_positive:
+ ; Calculate coords
+ jsr CALC
+
+ ; dy = y2 - y1
+ lda y2
+ sub y1
+ sta dy
+ lda y2 + 1
+ sbc y1 + 1
+ sta dy + 1
+
+ ; if dy is negative
+ bcs dy_positive
+ ; dy = -dy
+ lda #0
+ sub dy
+ sta dy
+ lda #0
+ sbc dy + 1
+ sta dy + 1
+ ; iy = -row_size
+ lda #<(65536 - x_res / ppb)
+ sta iy
+ lda #>(65536 - x_res / ppb)
+ sta iy + 1
+ bne skip_iy_1 ; always
+
+dy_positive:
+ ; iy = row_size
+ lda #<(x_res / ppb)
+ sta iy
+ lda #>(x_res / ppb)
+ sta iy + 1
+skip_iy_1:
+
+ ; dx2 = dx * 2
+ lda dx
+ asl a
+ sta dx2
+ lda dx + 1
+ rol a
+ sta dx2 + 1
+
+ ; dy2 = dy * 2
+ lda dy
+ asl a
+ sta dy2
+ lda dy + 1
+ rol a
+ sta dy2 + 1
+
+ ; if dx >= dy
+ lda dx
+ cmp dy
+ lda dx + 1
+ sbc dy + 1
+ bcc dy_major
+
+ ; dx is the major axis
+
+ ; err = dy2 - dx
+ lda dy2
+ sub dx
+ sta err
+ lda dy2 + 1
+ sbc dx + 1
+ sta err + 1
+
+ .scope
+loop: ; main loop
+ put_pixel
+ ; if err >= 0
+ lda err + 1
+ bmi err_neg
+ ; err -= dx2
+ lda err
+ sub dx2
+ sta err
+ lda err + 1
+ sbc dx2 + 1
+ sta err + 1
+ ; move_vertical (iy)
+ lda sptr
+ add iy
+ sta sptr
+ lda sptr + 1
+ adc iy + 1
+ sta sptr + 1
+err_neg:
+ ; err += dy2
+ lda err
+ add dy2
+ sta err
+ lda err + 1
+ adc dy2 + 1
+ sta err + 1
+ ; move_right
+ inx
+ cpx #ppb
+ bne end_move
+ ldx #0
+ iny
+ bne end_move
+ inc sptr + 1
+end_move:
+ ; loop while dx-- >= 0
+ lda dx
+ ora dx + 1
+ beq exit
+ dec dx
+ lda dx
+ cmp #$FF
+ bne loop
+ dec dx + 1
+ jmp loop
+exit: rts
+ .endscope
+
+dy_major:
+ ; dy is the major axis
+
+ ; err = dx2 - dy;
+ lda dx2
+ sub dy
+ sta err
+ lda dx2 + 1
+ sbc dy + 1
+ sta err + 1
+
+ .scope
+loop: ; main loop
+ put_pixel
+ ; if err >= 0
+ lda err + 1
+ bmi end_move
+ ; err -= dy2
+ lda err
+ sub dy2
+ sta err
+ lda err + 1
+ sbc dy2 + 1
+ sta err + 1
+ ; move_right
+ inx
+ cpx #ppb
+ bne end_move
+ ldx #0
+ iny
+ bne end_move
+ inc sptr + 1
+end_move:
+ ; err += dx2
+ lda err
+ add dx2
+ sta err
+ lda err + 1
+ adc dx2 + 1
+ sta err + 1
+ ; move_vertical(iy)
+ lda sptr
+ add iy
+ sta sptr
+ lda sptr + 1
+ adc iy + 1
+ sta sptr + 1
+ ; loop while dy-- >= 0
+ lda dy
+ ora dy + 1
+ beq exit
+ dec dy
+ lda dy
+ cmp #$FF
+ bne loop
+ dec dy + 1
+ jmp loop
+exit: rts
+ .endscope
+.endif ; USE_CIO_LINE
+.endproc
+
+; ******************************************************************************
+
+.proc clipped_bar
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Clip and draw bar, this function will disappear when text clipping
+ ; will be done int the TGI kernel
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ lda y1 + 1
+ bne off
+ lda y1
+ cmp #y_res
+ bcs off
+
+ lda x1 + 1
+
+.if >(::x_res - 1) > 0
+ cmp #>x_res
+ bcc check2
+.endif
+
+ bne off
+ lda x1
+ cmp #<x_res
+ bcc check2
+off: rts
+
+check2: lda y2 + 1
+ bne off
+ lda y2
+ cmp #y_res
+ bcs off
+
+ lda x2 + 1
+
+.if >(::x_res - 1) > 0
+ cmp #>x_res
+ bcc BAR
+.endif
+
+ bne off
+ lda x2
+ cmp #<x_res
+ bcs off
+.endproc
+
+; ******************************************************************************
+
+.proc BAR
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; BAR: Draw a filled rectangle with the corners at x1,y1,x2,y2
+ ;
+ ; ----------------------------------------------------------------------
+
+; locals
+ lmem := sreg
+.bss
+ lmask: .res 1
+ rmask: .res 1
+ dy: .res 1
+ dx: .res 1
+ fmask: .res 1
+.code
+ ; dy = y2 - y1 + 1
+ lda y2
+ sub y1
+ sta dy
+ inc dy
+ ; Calculate upper left corner
+ jsr CALC
+ ; Save the values
+ tya
+ add sptr
+ sta lmem
+ lda sptr + 1
+ adc #0
+ sta lmem + 1
+ lda bar_table,x
+ sta lmask
+ ; Calculate upper right corner
+ lda x2
+ sta x1
+
+.if >(::x_res - 1) > 0
+ lda x2 + 1
+ sta x1 + 1
+.endif
+
+ jsr CALC
+ ; Save the values
+ tya
+ add sptr
+ sta sptr
+ bcc skips
+ inc sptr + 1
+skips: inx
+ lda bar_table,x
+ eor #$FF
+ sta rmask
+ ; Calculate memory difference between x1 and x2
+ lda sptr
+ sub lmem
+ sta dx
+loop: ; Main loop
+ ldy #0
+ ldx dx
+ beq same
+ ; Left
+ lda (lmem),y
+ eor mask
+ and lmask
+ eor (lmem),y
+ sta (lmem),y
+ iny
+ ; Between
+ lda mask
+ jmp next
+btwn: sta (lmem),y
+ iny
+next: dex
+ bne btwn
+ ; Right
+ lda (lmem),y
+ eor mask
+ and rmask
+ eor (lmem),y
+ sta (lmem),y
+ jmp cont
+same: ; Same byte
+ lda lmask
+ and rmask
+ sta fmask
+ lda (lmem),y
+ eor mask
+ and fmask
+ eor (lmem),y
+ sta (lmem),y
+cont: ; Go to next row
+ lda lmem
+ add #<(x_res / ppb)
+ sta lmem
+ bcc skipm
+ inc lmem + 1
+skipm: ; Loop while --dy > 0
+ dec dy
+ bne loop
+
+ rts
+
+.endproc
+
+; ******************************************************************************
+
+.proc TEXTSTYLE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; TEXTSTYLE: Set text style. Scale factors in X and Y and direction in A
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ stx mag_x
+ sty mag_y
+ ; Save text direction in bit 8 so that we can use BIT instruction later
+ lsr a
+ ror a
+ sta text_dir
+ ; Save 8 * scaling factors
+ lda #0
+ sta mag_x8 + 1
+ sta mag_y8 + 1
+ ; Save 8 * mag_x
+ txa
+
+ .repeat 3
+ asl a
+ rol mag_x8 + 1
+ .endrepeat
+
+ sta mag_x8
+ ; Save 8 * mag_y
+ tya
+
+ .repeat 3
+ asl a
+ rol mag_y8 + 1
+ .endrepeat
+
+ sta mag_y8
+ ; Done!
+ rts
+.endproc
+
+; ******************************************************************************
+
+.proc OUTTEXT
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; OUTTEXT: Draw text at x1, y1. String is in ptr3
+ ;
+ ; ----------------------------------------------------------------------
+
+; locals
+ string := tmp1
+ cols := tmp3
+ pixels := tmp4
+ font := regsave
+.rodata
+ ataint: .byte 64,0,32,96
+.bss
+ rows: .res 1
+
+.if >(::x_res - 1) > 0
+ oldx1: .res 2
+ oldx2: .res 2
+.else
+ oldx1: .res 1
+ oldx2: .res 1
+.endif
+
+ oldy1: .res 1
+ oldy2: .res 1
+ inv: .res 1
+
+.code
+ ; Don't draw zero sized characters
+ lda mag_x
+ ora mag_y
+ bne not0
+ rts
+
+not0: ; Save string address, ptr3 is needed by BAR
+ lda ptr3
+ sta string
+ lda ptr3 + 1
+ sta string + 1
+
+ bit text_dir
+ bmi vert
+
+ ; Calculate x2
+ lda mag_x
+ sub #1
+ add x1
+ sta x2
+
+.if >(::x_res - 1) > 0
+ lda x1 + 1
+ adc #0
+ sta x2 + 1
+.else
+ lda #0
+ sta x2 + 1
+.endif
+
+ ; Calculate y2 and adjust y1
+ dec y1
+ lda y1
+ sta y2
+ sub mag_y
+ add #1
+ sta y1
+ lda #0
+ sta y2 + 1
+
+ jmp while
+
+ ; Calculate for vertical text
+vert: lda x1
+ sub #1
+ sta x2
+ lda x1 + 1
+ sbc #0
+ sta x2 + 1
+ lda x1
+ sub mag_y
+ sta x1
+ lda x1 + 1
+ sbc #0
+ sta x1 + 1
+
+ lda mag_x
+ sub #1
+ add y1
+ sta y2
+ lda #0
+ sta y2 + 1
+ jmp while
+
+ ; Main loop
+loop: inc string
+ bne skiph
+ inc string + 1
+skiph: ; Save coords
+ bit text_dir
+ bmi scvert
+
+ ldx y1
+ stx oldy1
+ ldx y2
+ stx oldy2
+ jmp draw
+
+scvert: ldx x1
+ stx oldx1
+ ldx x2
+ stx oldx2
+
+.if >(::x_res - 1) > 0
+ ldx x1 + 1
+ stx oldx1 + 1
+ ldx x2 + 1
+ stx oldx2 + 1
+.endif
+
+ ; Draw one character
+ ; Convert to ANTIC code
+draw: tay
+ rol a
+ rol a
+ rol a
+ rol a
+ and #3
+ tax
+ tya
+ and #$9f
+ ora ataint,x
+ ; Save and clear inverse video bit
+ sta inv
+ and #$7F
+ ; Calculate font data address
+ sta font
+ lda #0
+ sta font + 1
+
+ .repeat 3
+ asl font
+ rol a
+ .endrepeat
+
+ adc CHBAS
+ sta font + 1
+ ; Save old coords
+ bit text_dir
+ bpl hor
+ lda y1
+ sta oldy1
+ lda y2
+ sta oldy2
+ jmp cont
+hor: lda x1
+ sta oldx1
+ lda x2
+ sta oldx2
+
+.if >(::x_res - 1) > 0
+ lda x1 + 1
+ sta oldx1 + 1
+ lda x2 + 1
+ sta oldx2 + 1
+.endif
+
+ ; Get glyph pixels
+cont: ldy #7
+ ; Put one row of the glyph
+putrow: sty rows
+ lda (font),y
+ bit inv
+ bpl noinv
+ eor #$FF
+noinv: sta pixels
+ lda #7
+ sta cols
+ ; Put one column of the row
+putcol: asl pixels
+ bcc next_col
+ lda x1
+ pha
+ lda x1 + 1
+ pha
+ jsr clipped_bar
+ pla
+ sta x1 + 1
+ pla
+ sta x1
+next_col:
+ ; Go to next column
+ ; increase x coords
+ bit text_dir
+ bmi vertinc
+
+ lda mag_x
+ add x1
+ sta x1
+ bcc L1
+ inc x1 + 1
+L1: lda mag_x
+ add x2
+ sta x2
+ bcc L2
+ inc x2 + 1
+ jmp L2
+
+vertinc:
+ lda y1
+ sub mag_x
+ sta y1
+ lda y2
+ sub mag_x
+ sta y2
+L2:
+ dec cols
+ bpl putcol
+next_row:
+ ; Go to next row
+ bit text_dir
+ bmi verty
+
+ lda y1
+ sub mag_y
+ sta y1
+ bcs L3
+ dec y1 + 1
+L3: lda y2
+ sub mag_y
+ sta y2
+ bcs L6
+ dec y2 + 1
+L4: jmp L6
+
+verty: lda x1
+ sub mag_y
+ sta x1
+ bcs L5
+ dec x1 + 1
+L5: lda x2
+ sub mag_y
+ sta x2
+ bcs L6
+ dec x2 + 1
+L6:
+ ; Restore old values
+ bit text_dir
+ bpl reshor
+ lda oldy1
+ sta y1
+ lda oldy2
+ sta y2
+ jmp nextrow
+reshor: lda oldx1
+ sta x1
+ lda oldx2
+ sta x2
+
+.if >(::x_res - 1) > 0
+ lda oldx1 + 1
+ sta x1 + 1
+ lda oldx2 + 1
+ sta x2 + 1
+.endif
+
+ ; Next row
+nextrow:
+ ldy rows
+ dey
+ jpl putrow
+
+ ; Restore coords
+ bit text_dir
+ bmi resvert
+
+ ldx oldy1
+ stx y1
+ ldx oldy2
+ stx y2
+ ldx #0
+ stx y1 + 1
+ stx y2 + 1
+
+ lda mag_x8
+ add x1
+ sta x1
+ lda mag_x8 + 1
+ adc x1 + 1
+ sta x1 + 1
+ lda mag_x8
+ add x2
+ sta x2
+ lda mag_x8 + 1
+ adc x2 + 1
+ sta x2 + 1
+
+ jmp while
+
+resvert:
+ ldx oldx1
+ stx x1
+ ldx oldx2
+ stx x2
+
+.if >(::x_res - 1) > 0
+ ldx oldx1 + 1
+ stx x1 + 1
+ ldx oldx2 + 1
+ stx x2 + 1
+.endif
+
+ lda y1
+ sub mag_x8
+ sta y1
+ lda y1 +1
+ sbc mag_x8 + 1
+ sta y1 + 1
+ lda y2
+ sub mag_x8
+ sta y2
+ lda y2 +1
+ sbc mag_x8 + 1
+ sta y2 + 1
+
+ ; End of loop
+while: ldy #0
+ lda (string),y
+ jne loop ; Check for null character
+ rts
+
+.endproc
+
+.if pages = 2
+; ******************************************************************************
+
+.proc SETVIEWPAGE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETVIEWPAGE, page in A
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ tax
+ beq cont
+ lda #32
+
+cont: add p0dls
+ cmp SDLSTH
+ beq done ; We're already in the desired page
+
+ ldx RTCLOK + 2
+ sta SDLSTH
+
+ ; Wait until next VBLANK
+wait: cpx RTCLOK + 2
+ beq wait
+
+ ; Done
+done: rts
+.endproc
+
+; ******************************************************************************
+
+.proc SETDRAWPAGE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETDRAWPAGE, page in A
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ tax
+ beq cont
+ lda #32
+cont: add p0scr
+ sta SAVMSC + 1
+ rts
+.endproc
+.endif
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Unimplemented functions that require an error code
+ ;
+ ; ----------------------------------------------------------------------
+
+CONTROL:
+ lda #TGI_ERR_INV_FUNC
+ sta error
+ ; fall through
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Unimplemented functions that don't require an error code
+ ;
+ ; ----------------------------------------------------------------------
+
+INSTALL:
+UNINSTALL:
+
+.if pages = 1
+SETVIEWPAGE:
+SETDRAWPAGE:
+.endif
+
+ rts
--- /dev/null
+;
+; Graphics driver for the 80x192x9 (CIO mode 10, ANTIC mode F, GTIA mode $80) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 10
+; X resolution
+ x_res = 80
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 9
+; Pixels per byte
+ ppb = 2
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $0330 ; based on 4/3 display
+; Free memory needed
+ mem_needed = 15339
+; Number of screen pages
+ pages = 2
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11110000, %00001111
+ masks: ; Color masks
+ .byte $00, $11, $22, $33, $44, $55, $66, $77, $88
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00001111, %00000000
+ default_palette:
+ .byte $00, $0E, $32, $96, $68, $C4, $74, $EE, $4A
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ sta PCOLR0,y
+ dey
+ bpl loop
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 160x192x2 (CIO mode 15, ANTIC mode E) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 15
+; X resolution
+ x_res = 160
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 4
+; Pixels per byte
+ ppb = 4
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $0198 ; based on 4/3 display
+; Free memory needed
+ mem_needed = 15339
+; Number of screen pages
+ pages = 2
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11000000, %00110000, %00001100, %00000011
+ masks: ; Color masks
+ .byte %00000000, %01010101, %10101010, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00111111, %00001111, %00000011, %00000000
+ default_palette:
+ .byte $00, $0E, $32, $96
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR4
+ lda palette + 1
+ sta COLOR0
+ lda palette + 2
+ sta COLOR1
+ lda palette + 3
+ sta COLOR2
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 320x192x2 (CIO mode 8, ANTIC mode F) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 8
+; X resolution
+ x_res = 320
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 2
+; Pixels per byte
+ ppb = 8
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $00CC ; based on 4/3 display
+; Free memory needed
+ mem_needed = 15339
+; Number of screen pages
+ pages = 2
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %10000000, %01000000, %00100000, %00010000, %00001000, %00000100, %00000010, %00000001
+ masks: ; Color masks
+ .byte %00000000, %11111111
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %01111111, %00111111, %00011111, %00001111, %00000111, %00000011, %00000001, %00000000
+ default_palette:
+ .byte $00, $0E
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; Copy the palette
+ ldy #colors - 1
+loop: lda (ptr1),y
+ sta palette,y
+ dey
+ bpl loop
+
+ ; Get the color entries from the palette
+ lda palette
+ sta COLOR2
+ lda palette + 1
+ sta COLOR1
+
+ ; Done, reset the error code
+ lda #TGI_ERR_OK
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
--- /dev/null
+;
+; Graphics driver for the 80x192x16b (CIO mode 9, ANTIC mode F, GTIA mode $40) on the Atari.
+;
+; Fatih Aygun (2009)
+;
+
+ .include "atari.inc"
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .macpack generic
+
+; ******************************************************************************
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; Constants and tables
+ ;
+ ; ----------------------------------------------------------------------
+
+; Graphics mode
+ grmode = 9
+; X resolution
+ x_res = 80
+; Y resolution
+ y_res = 192
+; Number of colors
+ colors = 16
+; Pixels per byte
+ ppb = 2
+; Screen memory size in bytes
+ scrsize = x_res * y_res / ppb
+; Pixel aspect ratio
+ aspect = $0330 ; based on 4/3 display
+; Free memory needed
+ mem_needed = 15339
+; Number of screen pages
+ pages = 2
+
+.rodata
+ mask_table: ; Mask table to set pixels
+ .byte %11110000, %00001111
+ masks: ; Color masks
+ .byte $00, $11, $22, $33, $44, $55, $66, $77, $88, $99, $aa, $bb, $cc, $dd, $ee, $ff
+ bar_table: ; Mask table for BAR
+ .byte %11111111, %00001111, %00000000
+ default_palette:
+ .byte $00, $0F, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $0B, $0C, $0D, $0E
+
+.code
+
+; ******************************************************************************
+
+.proc SETPALETTE
+
+ ; ----------------------------------------------------------------------
+ ;
+ ; SETPALETTE: Set the palette (in ptr1)
+ ;
+ ; ----------------------------------------------------------------------
+
+.code
+ ; No palettes
+ lda #TGI_ERR_INV_FUNC
+ sta error
+ rts
+.endproc
+
+.include "atari_tgi_common.inc"
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = atmos
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-mou.o: %.mou
- @$(CO) -o $(*)-mou.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-mou.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- atmos_load.o \
- atmos_save.o \
- cclear.o \
- cgetc.o \
- chline.o \
- clock.o \
- clrscr.o \
- color.o \
- cputc.o \
- crt0.o \
- ctype.o \
- cvline.o \
- gotox.o \
- gotoxy.o \
- gotoy.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- mainargs.o \
- oserrlist.o \
- oserror.o \
- revers.o \
- store_filename.o \
- systime.o \
- sysuname.o \
- tgi_colors.o \
- tgi_stat_stddrv.o \
- tgi_stddrv.o \
- toascii.o \
- wherex.o \
- wherey.o \
- write.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(MOUS:.mou=-mou.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS =
-
-JOYS = atmos-pase.joy
-
-MOUS =
-
-SERS = atmos-acia.ser
-
-TGIS = atmos-240-200-2.tgi atmos-228-200-3.tgi
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(MOUS:.mou=.o) $(MOUS:.mou=-mou.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
+++ /dev/null
-;
-; Graphics driver for the 228x200x3 palette mode on the Atmos
-;
-; Stefan Haubenthal <polluks@sdf.lonestar.org>
-; 2012-08-11, Greg King <greg.king5@verizon.net>
-;
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
- .include "atmos.inc"
-
- .macpack generic
-
-XSIZE = 6 ; System font width
-YSIZE = 8 ; System font height
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table and constants.
-
-.segment "JUMPTABLE"
-
-; The first part of the header is a structure that has a signature,
-; and defines the capabilities of the driver.
-
- .byte "tgi"
- .byte TGI_API_VERSION ; TGI API version number
- .word 228 ; x resolution
- .word 200 ; y resolution
- .byte 3 ; Number of drawing colors
- .byte 1 ; Number of screens available
- .byte XSIZE ; System font x size
- .byte YSIZE ; System font y size
- .word $011C ; Aspect ratio (based on 4/3 display)
- .byte 0 ; TGI driver flags
-
-; 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 TEXTSTYLE
- .addr OUTTEXT
- .addr 0 ; IRQ entry is unused
-
-; ------------------------------------------------------------------------
-; Data.
-
-; Variables mapped to the zero-page segment variables. These are
-; used for passing parameters to the driver.
-
-X1 := ptr1
-Y1 := ptr2
-X2 := ptr3
-Y2 := ptr4
-
-; Absolute variables used in the code
-
-.bss
-
-ERROR: .res 1 ; Error code
-MODE: .res 1 ; Graphics mode
-PALETTE: .res 2
-
-; Constants and table
-; BASIC 1.1 addresses
-PATTERN := $213
-PARAM1 := $2E1 ; & $2E2
-PARAM2 := $2E3 ; & $2E4
-PARAM3 := $2E5 ; & $2E6
-TEXT := $EC21
-HIRES := $EC33
-CURSET := $F0C8
-CURMOV := $F0FD
-DRAW := $F110
-CHAR := $F12D
-POINT := $F1C8
-PAPER := $F204
-INK := $F210
-
-.rodata
-
-; Default colors: black background, white foreground
-; (The third "color" actually flips a pixel
-; between the foreground and background colors.)
-;
-DEFPALETTE: .byte 0, 1
-
-.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 called only once. So, any code that is needed
-; to initialize variables and so on must go here. Setting palette and
-; clearing the screen are not needed because they are called by the graphics
-; kernel later.
-; The graphics kernel never will 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 HIRES
-
-; Done, reset the error code.
-
-; ------------------------------------------------------------------------
-; GETERROR: Return the error code in A, and clear it.
-
-GETERROR:
- ldx #TGI_ERR_OK
- lda ERROR
- stx ERROR
-
-; ------------------------------------------------------------------------
-; 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 probably is 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 never will 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
-
-; ------------------------------------------------------------------------
-; CONTROL: Platform-/driver-specific entry point.
-;
-; Must set an error code: YES
-;
-
-CONTROL:
- sta PATTERN
- lda #TGI_ERR_OK
- sta ERROR
- rts
-
-; ------------------------------------------------------------------------
-; CLEAR: Clears the screen.
-;
-; Must set an error code: NO
-;
-
-CLEAR := HIRES
-
-; ------------------------------------------------------------------------
-; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
-; The page number already is checked to be valid, by the graphics kernel.
-;
-; Must set an error code: NO (will be called only if page OK)
-;
-
-SETVIEWPAGE:
-
-; ------------------------------------------------------------------------
-; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
-; The page number already is checked to be valid, by the graphics kernel.
-;
-; Must set an error code: NO (will be called only if page OK)
-;
-
-SETDRAWPAGE:
- rts
-
-; ------------------------------------------------------------------------
-; SETCOLOR: Set the drawing color (in A). The new color already is checked
-; to be in a valid range (0..maxcolor-1).
-;
-; Must set an error code: NO (will be called only if color OK)
-;
-
-SETCOLOR:
- sta MODE
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- ldy #0
- jsr flipcolor
- sty PARAM1+1
- jsr PAPER
- ldy #1
- jsr flipcolor
- dey ; TGI_ERR_OK
- sty ERROR
- sty PARAM1+1
- jmp INK
-
-flipcolor:
- lda (ptr1),y
- sta PALETTE,y
- cmp #1
- beq @flip
- cmp #7
- bne @keep
-@flip: eor #1 ^ 7
-@keep: sta PARAM1
- 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:
- lda #<PALETTE
- ldx #>PALETTE
- rts
-
-; ------------------------------------------------------------------------
-; 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 co-ordinates 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:
- lda Y1
- sta PARAM2
- lda MODE
-mymode: sta PARAM3
- lda X1
- add #2 * XSIZE ; Skip screen attribute columns
- sta PARAM1
- lda #0
- sta PARAM1+1
- sta PARAM2+1
- sta PARAM3+1
- jmp CURSET
-
-; ------------------------------------------------------------------------
-; GETPIXEL: Read the color value of a pixel, and return it in A/X. The
-; co-ordinates passed to this function are never outside the visible screen
-; area, so there is no need for clipping inside this function.
-
-GETPIXEL:
- lda X1
- sta PARAM1
- lda Y1
- sta PARAM2
- lda #0
- sta PARAM1+1
- sta PARAM2+1
- jsr POINT
- lda PARAM1
- and #%00000001
- ldx #0
- 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:
- jsr SETPIXEL
- lda X2
- sub X1
- sta PARAM1
- lda X2+1
- sbc X1+1
- sta PARAM1+1
- lda Y2
- sub Y1
- sta PARAM2
- lda Y2+1
- sbc Y1+1
- sta PARAM2+1
- lda MODE
- sta PARAM3
- ldx #>0
- stx PARAM3+1
- jmp DRAW
-
-; ------------------------------------------------------------------------
-; 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 co-ordinates 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
-
-; ------------------------------------------------------------------------
-; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in the x
-; and y directions 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 its address in ptr3.
-;
-; Must set an error code: NO
-;
-
-OUTTEXT:
- lda Y1
- sub #(YSIZE - 1)
- sta PARAM2
- lda #3 ; (Move graphics cursor; don't draw)
- jsr mymode
-
- ldy #0
-@next: lda (ptr3),y
- beq @end
- sta PARAM1
- lda #0
- sta PARAM2
- sta PARAM1+1
- sta PARAM2+1
- sta PARAM3+1
- lda MODE
- sta PARAM3
- tya
- pha
- jsr CHAR
- lda #XSIZE
- sta PARAM1
- lda #0
- sta PARAM2
- sta PARAM1+1
- sta PARAM2+1
- sta PARAM3+1
- lda #3
- sta PARAM3
- jsr CURMOV
- pla
- tay
- iny
- bne @next
-@end: rts
+++ /dev/null
-;
-; Graphics driver for the 240x200x2 monochrome mode on the Atmos
-;
-; Stefan Haubenthal <polluks@sdf.lonestar.org>
-; 2012-08-11, Greg King <greg.king5@verizon.net>
-;
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
- .include "atmos.inc"
-
- .macpack generic
-
-XSIZE = 6 ; System font width
-YSIZE = 8 ; System font height
-
-; ------------------------------------------------------------------------
-; 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
- .word 240 ; X resolution
- .word 200 ; Y resolution
- .byte 2 ; Number of drawing colors
- .byte 1 ; Number of screens available
- .byte XSIZE ; System font X size
- .byte YSIZE ; System font Y size
- .word $011C ; Aspect ratio (based on 4/3 display)
- .byte 0 ; TGI driver flags
-
-; 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 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
-
-; Absolute variables used in the code
-
-.bss
-
-ERROR: .res 1 ; Error code
-MODE: .res 1 ; Graphics mode
-
-; Constants and tables
-PARAM1 = $2E1
-PARAM2 = $2E3
-PARAM3 = $2E5
-TEXT = $EC21
-HIRES = $EC33
-CURSET = $F0C8
-CURMOV = $F0FD
-DRAW = $F110
-CHAR = $F12D
-POINT = $F1C8
-PAPER = $F204
-INK = $F210
-
-.rodata
-
-DEFPALETTE: .byte 0, 1
-
-.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 HIRES
-
-; 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:
- sta $213
- lda #TGI_ERR_OK
- sta ERROR
- rts
-
-; ------------------------------------------------------------------------
-; CLEAR: Clears the screen.
-;
-; Must set an error code: NO
-;
-
-CLEAR = HIRES
-
-; ------------------------------------------------------------------------
-; 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:
- sta MODE
- rts
-
-; ------------------------------------------------------------------------
-; 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 ; This resolution has no palette
- 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
-;
-
-SETPIXEL:
- lda Y1
- sta PARAM2
- lda MODE
-mymode: sta PARAM3
- lda X1
- sta PARAM1
- lda #0
- sta PARAM1+1
- sta PARAM2+1
- sta PARAM3+1
- jmp CURSET
-
-; ------------------------------------------------------------------------
-; 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
- sta PARAM1
- lda Y1
- sta PARAM2
- lda #0
- sta PARAM1+1
- sta PARAM2+1
- jsr POINT
- lda PARAM1
- and #%00000001
- ldx #0
- 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:
- jsr SETPIXEL
- lda X2
- sub X1
- sta PARAM1
- lda X2+1
- sbc X1+1
- sta PARAM1+1
- lda Y2
- sub Y1
- sta PARAM2
- lda Y2+1
- sbc Y1+1
- sta PARAM2+1
- lda MODE
- sta PARAM3
- ldx #>0
- stx PARAM3+1
- jmp DRAW
-
-; ------------------------------------------------------------------------
-; 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
-
-; ------------------------------------------------------------------------
-; 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 Y1
- sub #(YSIZE - 1)
- sta PARAM2
- lda #3 ; (Move graphics cursor; don't draw)
- jsr mymode
-
- ldy #0
-@next: lda (ptr3),y
- beq @end
- sta PARAM1
- lda #0
- sta PARAM2
- sta PARAM1+1
- sta PARAM2+1
- sta PARAM3+1
- lda MODE
- sta PARAM3
- tya
- pha
- jsr CHAR
- lda #XSIZE
- sta PARAM1
- lda #0
- sta PARAM2
- sta PARAM1+1
- sta PARAM2+1
- sta PARAM3+1
- lda #3
- sta PARAM3
- jsr CURMOV
- pla
- tay
- iny
- bne @next
-@end: rts
+++ /dev/null
-;
-; Serial driver for the Telestrat integrated serial controller and the
-; Atmos with a serial add-on.
-;
-; Stefan Haubenthal, 2012-03-05
-;
-; The driver is based on the cc65 rs232 module, which in turn is based on
-; Craig Bruce device driver for the Switftlink/Turbo-232.
-;
-; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
-;
-; This software is Public Domain. It is in Buddy assembler format.
-;
-; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
-; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
-; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
-; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
-;
-; The code assumes that the kernal + I/O are in context. On the C128, call
-; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
-; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
-; interrupt handling assumes that the 65816 is in 6502-emulation mode.
-;
-
- .include "zeropage.inc"
- .include "ser-kernel.inc"
- .include "ser-error.inc"
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
- .segment "JUMPTABLE"
-
- ; Driver signature
- .byte $73, $65, $72 ; "ser"
- .byte SER_API_VERSION ; Serial API version number
-
- ; Jump table.
- .addr INSTALL
- .addr UNINSTALL
- .addr OPEN
- .addr CLOSE
- .addr GET
- .addr PUT
- .addr STATUS
- .addr IOCTL
- .addr IRQ
-
-;----------------------------------------------------------------------------
-; I/O definitions
-
-ACIA = $031C
-ACIA_DATA = ACIA+0 ; Data register
-ACIA_STATUS = ACIA+1 ; Status register
-ACIA_CMD = ACIA+2 ; Command register
-ACIA_CTRL = ACIA+3 ; Control register
-
-;----------------------------------------------------------------------------
-; Global variables
-
- .bss
-
-RecvHead: .res 1 ; Head of receive buffer
-RecvTail: .res 1 ; Tail of receive buffer
-RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
-SendHead: .res 1 ; Head of send buffer
-SendTail: .res 1 ; Tail of send buffer
-SendFreeCnt: .res 1 ; Number of bytes in send buffer
-
-Stopped: .res 1 ; Flow-stopped flag
-RtsOff: .res 1 ;
-
-RecvBuf: .res 256 ; Receive buffers: 256 bytes
-SendBuf: .res 256 ; Send buffers: 256 bytes
-
-Index: .res 1 ; I/O register index
-
- .rodata
-
- ; Tables used to translate RS232 params into register values
-BaudTable: ; bit7 = 1 means setting is invalid
- .byte $FF ; SER_BAUD_45_5
- .byte $01 ; SER_BAUD_50
- .byte $02 ; SER_BAUD_75
- .byte $03 ; SER_BAUD_110
- .byte $04 ; SER_BAUD_134_5
- .byte $05 ; SER_BAUD_150
- .byte $06 ; SER_BAUD_300
- .byte $07 ; SER_BAUD_600
- .byte $08 ; SER_BAUD_1200
- .byte $09 ; SER_BAUD_1800
- .byte $0A ; SER_BAUD_2400
- .byte $0B ; SER_BAUD_3600
- .byte $0C ; SER_BAUD_4800
- .byte $0D ; SER_BAUD_7200
- .byte $0E ; SER_BAUD_9600
- .byte $0F ; SER_BAUD_19200
- .byte $FF ; SER_BAUD_38400
- .byte $FF ; SER_BAUD_57600
- .byte $FF ; SER_BAUD_115200
- .byte $FF ; SER_BAUD_230400
-BitTable:
- .byte $60 ; SER_BITS_5
- .byte $40 ; SER_BITS_6
- .byte $20 ; SER_BITS_7
- .byte $00 ; SER_BITS_8
-StopTable:
- .byte $00 ; SER_STOP_1
- .byte $80 ; SER_STOP_2
-ParityTable:
- .byte $00 ; SER_PAR_NONE
- .byte $20 ; SER_PAR_ODD
- .byte $60 ; SER_PAR_EVEN
- .byte $A0 ; SER_PAR_MARK
- .byte $E0 ; SER_PAR_SPACE
-
- .code
-
-;----------------------------------------------------------------------------
-; INSTALL: Is called after the driver is loaded into memory. If possible,
-; check if the hardware is present. Must return an SER_ERR_xx code in a/x.
-;
-; Since we don't have to manage the IRQ vector on the Telestrat/Atmos, this is
-; actually the same as:
-;
-; UNINSTALL: Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-;
-; and:
-;
-; CLOSE: Close the port and disable interrupts. Called without parameters.
-; Must return an SER_ERR_xx code in a/x.
-
-INSTALL:
-UNINSTALL:
-CLOSE:
- ldx Index ; Check for open port
- beq :+
-
- ; Deactivate DTR and disable 6551 interrupts
- lda #%00001010
- sta ACIA_CMD,x
-
- ; Done, return an error code
-: lda #<SER_ERR_OK
- tax ; A is zero
- stx Index ; Mark port as closed
- rts
-
-;----------------------------------------------------------------------------
-; OPEN: A pointer to a ser_params structure is passed in ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-OPEN:
- ; Check if the handshake setting is valid
- ldy #SER_PARAMS::HANDSHAKE ; Handshake
- lda (ptr1),y
- cmp #SER_HS_HW ; This is all we support
- bne InvParam
-
- ; Initialize buffers
- ldy #$00
- sty Stopped
- sty RecvHead
- sty RecvTail
- sty SendHead
- sty SendTail
- dey ; Y = 255
- sty RecvFreeCnt
- sty SendFreeCnt
-
- ; Set the value for the control register, which contains stop bits,
- ; word length and the baud rate.
- ldy #SER_PARAMS::BAUDRATE
- lda (ptr1),y ; Baudrate index
- tay
- lda BaudTable,y ; Get 6551 value
- bmi InvBaud ; Branch if rate not supported
- sta tmp1
-
- ldy #SER_PARAMS::DATABITS ; Databits
- lda (ptr1),y
- tay
- lda BitTable,y
- ora tmp1
- sta tmp1
-
- ldy #SER_PARAMS::STOPBITS ; Stopbits
- lda (ptr1),y
- tay
- lda StopTable,y
- ora tmp1
- ora #%00010000 ; Receiver clock source = baudrate
- sta ACIA_CTRL
-
- ; Set the value for the command register. We remember the base value
- ; in RtsOff, since we will have to manipulate ACIA_CMD often.
- ldy #SER_PARAMS::PARITY ; Parity
- lda (ptr1),y
- tay
- lda ParityTable,y
- ora #%00000001 ; DTR active
- sta RtsOff
- ora #%00001000 ; Enable receive interrupts
- sta ACIA_CMD
-
- ; Done
- stx Index ; Mark port as open
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
- ; Invalid parameter
-InvParam:lda #<SER_ERR_INIT_FAILED
- ldx #>SER_ERR_INIT_FAILED
- rts
-
- ; Baud rate not available
-InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
- ldx #>SER_ERR_BAUD_UNAVAIL
- rts
-
-;----------------------------------------------------------------------------
-; GET: Will fetch a character from the receive buffer and store it into the
-; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
-; returned.
-
-GET:
- ldy SendFreeCnt ; Send data if necessary
- iny ; Y == $FF?
- beq :+
- lda #$00 ; TryHard = false
- jsr TryToSend
-
- ; Check for buffer empty
-: lda RecvFreeCnt ; (25)
- cmp #$FF
- bne :+
- lda #<SER_ERR_NO_DATA
- ldx #>SER_ERR_NO_DATA
- rts
-
- ; Check for flow stopped & enough free: release flow control
-: ldy Stopped ; (34)
- beq :+
- cmp #63
- bcc :+
- lda #$00
- sta Stopped
- lda RtsOff
- ora #%00001000
- sta ACIA_CMD
-
- ; Get byte from buffer
-: ldy RecvHead ; (41)
- lda RecvBuf,y
- inc RecvHead
- inc RecvFreeCnt
- ldx #$00 ; (59)
- sta (ptr1,x)
- txa ; Return code = 0
- rts
-
-;----------------------------------------------------------------------------
-; PUT: Output character in A.
-; Must return an SER_ERR_xx code in a/x.
-
-PUT:
- ; Try to send
- ldy SendFreeCnt
- iny ; Y = $FF?
- beq :+
- pha
- lda #$00 ; TryHard = false
- jsr TryToSend
- pla
-
- ; Put byte into send buffer & send
-: ldy SendFreeCnt
- bne :+
- lda #<SER_ERR_OVERFLOW
- ldx #>SER_ERR_OVERFLOW
- rts
-
-: ldy SendTail
- sta SendBuf,y
- inc SendTail
- dec SendFreeCnt
- lda #$FF ; TryHard = true
- jsr TryToSend
- lda #<SER_ERR_OK
- tax
- rts
-
-;----------------------------------------------------------------------------
-; STATUS: Return the status in the variable pointed to by ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-STATUS:
- lda ACIA_STATUS
- ldx #$00
- sta (ptr1,x)
- txa ; SER_ERR_OK
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an SER_ERR_xx code in a/x.
-
-IOCTL:
- lda #<SER_ERR_INV_IOCTL
- ldx #>SER_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
-; registers are already saved, no parameters are passed, but the carry flag
-; is clear on entry. The routine must return with carry set if the interrupt
-; was handled, otherwise with carry clear.
-
-IRQ:
- ldx Index ; Check for open port
- beq Done
- lda ACIA_STATUS,x ; Check ACIA status for receive interrupt
- and #$08
- beq Done ; Jump if no ACIA interrupt
- lda ACIA_DATA,x ; Get byte from ACIA
- ldy RecvFreeCnt ; Check if we have free space left
- beq Flow ; Jump if no space in receive buffer
- ldy RecvTail ; Load buffer pointer
- sta RecvBuf,y ; Store received byte in buffer
- inc RecvTail ; Increment buffer pointer
- dec RecvFreeCnt ; Decrement free space counter
- ldy RecvFreeCnt ; Check for buffer space low
- cpy #33
- bcc Flow ; Assert flow control if buffer space low
- rts ; Interrupt handled (carry already set)
-
- ; Assert flow control if buffer space too low
-Flow: lda RtsOff
- sta ACIA_CMD,x
- sta Stopped
- sec ; Interrupt handled
-Done: rts
-
-;----------------------------------------------------------------------------
-; Try to send a byte. Internal routine. A = TryHard
-
-TryToSend:
- sta tmp1 ; Remember tryHard flag
-Again: lda SendFreeCnt
- cmp #$FF
- beq Quit ; Bail out
-
- ; Check for flow stopped
- lda Stopped
- bne Quit ; Bail out
-
- ; Check that ACIA is ready to send
- lda ACIA_STATUS
- and #$10
- bne Send
- bit tmp1 ; Keep trying if must try hard
- bmi Again
-Quit: rts
-
- ; Send byte and try again
-Send: ldy SendHead
- lda SendBuf,y
- sta ACIA_DATA
- inc SendHead
- inc SendFreeCnt
- jmp Again
+++ /dev/null
-;
-; P.A.S.E. joystick driver for the Atmos
-; May be used multiple times when linked to the statically application.
-;
-; Stefan Haubenthal, 2009-12-21
-; Based on Ullrich von Bassewitz, 2002-12-20
-;
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
-; .include "atmos.inc"
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $10 ; JOY_UP
- .byte $08 ; JOY_DOWN
- .byte $01 ; JOY_LEFT
- .byte $02 ; JOY_RIGHT
- .byte $20 ; JOY_FIRE
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
-PRA = $0301
-DDRA = $0303
-PRA2 = $030F
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-temp1: .byte $00
-temp2: .byte $00
-
-.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 #0
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; 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 #0
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ:
- tay
-
- lda PRA
- pha
- lda DDRA
- pha
- lda #%11000000
- sta DDRA
- lda #%10000000
- sta PRA2
- lda PRA2
- sta temp1
- lda #%01000000
- sta PRA2
- lda PRA
- sta temp2
- pla
- sta DDRA
- pla
- sta PRA2
-
- ldx #0
- tya
- bne @L1
- lda temp1
- eor #$FF
- rts
-@L1: lda temp2
- eor #$FF
- rts
--- /dev/null
+;
+; P.A.S.E. joystick driver for the Atmos
+; May be used multiple times when linked to the statically application.
+;
+; Stefan Haubenthal, 2009-12-21
+; Based on Ullrich von Bassewitz, 2002-12-20
+;
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+; .include "atmos.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $10 ; JOY_UP
+ .byte $08 ; JOY_DOWN
+ .byte $01 ; JOY_LEFT
+ .byte $02 ; JOY_RIGHT
+ .byte $20 ; JOY_FIRE
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+PRA = $0301
+DDRA = $0303
+PRA2 = $030F
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+temp1: .byte $00
+temp2: .byte $00
+
+.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 #0
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; 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 #0
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ:
+ tay
+
+ lda PRA
+ pha
+ lda DDRA
+ pha
+ lda #%11000000
+ sta DDRA
+ lda #%10000000
+ sta PRA2
+ lda PRA2
+ sta temp1
+ lda #%01000000
+ sta PRA2
+ lda PRA
+ sta temp2
+ pla
+ sta DDRA
+ pla
+ sta PRA2
+
+ ldx #0
+ tya
+ bne @L1
+ lda temp1
+ eor #$FF
+ rts
+@L1: lda temp2
+ eor #$FF
+ rts
--- /dev/null
+;
+; Serial driver for the Telestrat integrated serial controller and the
+; Atmos with a serial add-on.
+;
+; Stefan Haubenthal, 2012-03-05
+;
+; The driver is based on the cc65 rs232 module, which in turn is based on
+; Craig Bruce device driver for the Switftlink/Turbo-232.
+;
+; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
+;
+; This software is Public Domain. It is in Buddy assembler format.
+;
+; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
+; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
+; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
+; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
+;
+; The code assumes that the kernal + I/O are in context. On the C128, call
+; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
+; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
+; interrupt handling assumes that the 65816 is in 6502-emulation mode.
+;
+
+ .include "zeropage.inc"
+ .include "ser-kernel.inc"
+ .include "ser-error.inc"
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ .segment "JUMPTABLE"
+
+ ; Driver signature
+ .byte $73, $65, $72 ; "ser"
+ .byte SER_API_VERSION ; Serial API version number
+
+ ; Jump table.
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr OPEN
+ .addr CLOSE
+ .addr GET
+ .addr PUT
+ .addr STATUS
+ .addr IOCTL
+ .addr IRQ
+
+;----------------------------------------------------------------------------
+; I/O definitions
+
+ACIA = $031C
+ACIA_DATA = ACIA+0 ; Data register
+ACIA_STATUS = ACIA+1 ; Status register
+ACIA_CMD = ACIA+2 ; Command register
+ACIA_CTRL = ACIA+3 ; Control register
+
+;----------------------------------------------------------------------------
+; Global variables
+
+ .bss
+
+RecvHead: .res 1 ; Head of receive buffer
+RecvTail: .res 1 ; Tail of receive buffer
+RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
+SendHead: .res 1 ; Head of send buffer
+SendTail: .res 1 ; Tail of send buffer
+SendFreeCnt: .res 1 ; Number of bytes in send buffer
+
+Stopped: .res 1 ; Flow-stopped flag
+RtsOff: .res 1 ;
+
+RecvBuf: .res 256 ; Receive buffers: 256 bytes
+SendBuf: .res 256 ; Send buffers: 256 bytes
+
+Index: .res 1 ; I/O register index
+
+ .rodata
+
+ ; Tables used to translate RS232 params into register values
+BaudTable: ; bit7 = 1 means setting is invalid
+ .byte $FF ; SER_BAUD_45_5
+ .byte $01 ; SER_BAUD_50
+ .byte $02 ; SER_BAUD_75
+ .byte $03 ; SER_BAUD_110
+ .byte $04 ; SER_BAUD_134_5
+ .byte $05 ; SER_BAUD_150
+ .byte $06 ; SER_BAUD_300
+ .byte $07 ; SER_BAUD_600
+ .byte $08 ; SER_BAUD_1200
+ .byte $09 ; SER_BAUD_1800
+ .byte $0A ; SER_BAUD_2400
+ .byte $0B ; SER_BAUD_3600
+ .byte $0C ; SER_BAUD_4800
+ .byte $0D ; SER_BAUD_7200
+ .byte $0E ; SER_BAUD_9600
+ .byte $0F ; SER_BAUD_19200
+ .byte $FF ; SER_BAUD_38400
+ .byte $FF ; SER_BAUD_57600
+ .byte $FF ; SER_BAUD_115200
+ .byte $FF ; SER_BAUD_230400
+BitTable:
+ .byte $60 ; SER_BITS_5
+ .byte $40 ; SER_BITS_6
+ .byte $20 ; SER_BITS_7
+ .byte $00 ; SER_BITS_8
+StopTable:
+ .byte $00 ; SER_STOP_1
+ .byte $80 ; SER_STOP_2
+ParityTable:
+ .byte $00 ; SER_PAR_NONE
+ .byte $20 ; SER_PAR_ODD
+ .byte $60 ; SER_PAR_EVEN
+ .byte $A0 ; SER_PAR_MARK
+ .byte $E0 ; SER_PAR_SPACE
+
+ .code
+
+;----------------------------------------------------------------------------
+; INSTALL: Is called after the driver is loaded into memory. If possible,
+; check if the hardware is present. Must return an SER_ERR_xx code in a/x.
+;
+; Since we don't have to manage the IRQ vector on the Telestrat/Atmos, this is
+; actually the same as:
+;
+; UNINSTALL: Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+;
+; and:
+;
+; CLOSE: Close the port and disable interrupts. Called without parameters.
+; Must return an SER_ERR_xx code in a/x.
+
+INSTALL:
+UNINSTALL:
+CLOSE:
+ ldx Index ; Check for open port
+ beq :+
+
+ ; Deactivate DTR and disable 6551 interrupts
+ lda #%00001010
+ sta ACIA_CMD,x
+
+ ; Done, return an error code
+: lda #<SER_ERR_OK
+ tax ; A is zero
+ stx Index ; Mark port as closed
+ rts
+
+;----------------------------------------------------------------------------
+; OPEN: A pointer to a ser_params structure is passed in ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+OPEN:
+ ; Check if the handshake setting is valid
+ ldy #SER_PARAMS::HANDSHAKE ; Handshake
+ lda (ptr1),y
+ cmp #SER_HS_HW ; This is all we support
+ bne InvParam
+
+ ; Initialize buffers
+ ldy #$00
+ sty Stopped
+ sty RecvHead
+ sty RecvTail
+ sty SendHead
+ sty SendTail
+ dey ; Y = 255
+ sty RecvFreeCnt
+ sty SendFreeCnt
+
+ ; Set the value for the control register, which contains stop bits,
+ ; word length and the baud rate.
+ ldy #SER_PARAMS::BAUDRATE
+ lda (ptr1),y ; Baudrate index
+ tay
+ lda BaudTable,y ; Get 6551 value
+ bmi InvBaud ; Branch if rate not supported
+ sta tmp1
+
+ ldy #SER_PARAMS::DATABITS ; Databits
+ lda (ptr1),y
+ tay
+ lda BitTable,y
+ ora tmp1
+ sta tmp1
+
+ ldy #SER_PARAMS::STOPBITS ; Stopbits
+ lda (ptr1),y
+ tay
+ lda StopTable,y
+ ora tmp1
+ ora #%00010000 ; Receiver clock source = baudrate
+ sta ACIA_CTRL
+
+ ; Set the value for the command register. We remember the base value
+ ; in RtsOff, since we will have to manipulate ACIA_CMD often.
+ ldy #SER_PARAMS::PARITY ; Parity
+ lda (ptr1),y
+ tay
+ lda ParityTable,y
+ ora #%00000001 ; DTR active
+ sta RtsOff
+ ora #%00001000 ; Enable receive interrupts
+ sta ACIA_CMD
+
+ ; Done
+ stx Index ; Mark port as open
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+ ; Invalid parameter
+InvParam:lda #<SER_ERR_INIT_FAILED
+ ldx #>SER_ERR_INIT_FAILED
+ rts
+
+ ; Baud rate not available
+InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
+ ldx #>SER_ERR_BAUD_UNAVAIL
+ rts
+
+;----------------------------------------------------------------------------
+; GET: Will fetch a character from the receive buffer and store it into the
+; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; returned.
+
+GET:
+ ldy SendFreeCnt ; Send data if necessary
+ iny ; Y == $FF?
+ beq :+
+ lda #$00 ; TryHard = false
+ jsr TryToSend
+
+ ; Check for buffer empty
+: lda RecvFreeCnt ; (25)
+ cmp #$FF
+ bne :+
+ lda #<SER_ERR_NO_DATA
+ ldx #>SER_ERR_NO_DATA
+ rts
+
+ ; Check for flow stopped & enough free: release flow control
+: ldy Stopped ; (34)
+ beq :+
+ cmp #63
+ bcc :+
+ lda #$00
+ sta Stopped
+ lda RtsOff
+ ora #%00001000
+ sta ACIA_CMD
+
+ ; Get byte from buffer
+: ldy RecvHead ; (41)
+ lda RecvBuf,y
+ inc RecvHead
+ inc RecvFreeCnt
+ ldx #$00 ; (59)
+ sta (ptr1,x)
+ txa ; Return code = 0
+ rts
+
+;----------------------------------------------------------------------------
+; PUT: Output character in A.
+; Must return an SER_ERR_xx code in a/x.
+
+PUT:
+ ; Try to send
+ ldy SendFreeCnt
+ iny ; Y = $FF?
+ beq :+
+ pha
+ lda #$00 ; TryHard = false
+ jsr TryToSend
+ pla
+
+ ; Put byte into send buffer & send
+: ldy SendFreeCnt
+ bne :+
+ lda #<SER_ERR_OVERFLOW
+ ldx #>SER_ERR_OVERFLOW
+ rts
+
+: ldy SendTail
+ sta SendBuf,y
+ inc SendTail
+ dec SendFreeCnt
+ lda #$FF ; TryHard = true
+ jsr TryToSend
+ lda #<SER_ERR_OK
+ tax
+ rts
+
+;----------------------------------------------------------------------------
+; STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+STATUS:
+ lda ACIA_STATUS
+ ldx #$00
+ sta (ptr1,x)
+ txa ; SER_ERR_OK
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an SER_ERR_xx code in a/x.
+
+IOCTL:
+ lda #<SER_ERR_INV_IOCTL
+ ldx #>SER_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
+; registers are already saved, no parameters are passed, but the carry flag
+; is clear on entry. The routine must return with carry set if the interrupt
+; was handled, otherwise with carry clear.
+
+IRQ:
+ ldx Index ; Check for open port
+ beq Done
+ lda ACIA_STATUS,x ; Check ACIA status for receive interrupt
+ and #$08
+ beq Done ; Jump if no ACIA interrupt
+ lda ACIA_DATA,x ; Get byte from ACIA
+ ldy RecvFreeCnt ; Check if we have free space left
+ beq Flow ; Jump if no space in receive buffer
+ ldy RecvTail ; Load buffer pointer
+ sta RecvBuf,y ; Store received byte in buffer
+ inc RecvTail ; Increment buffer pointer
+ dec RecvFreeCnt ; Decrement free space counter
+ ldy RecvFreeCnt ; Check for buffer space low
+ cpy #33
+ bcc Flow ; Assert flow control if buffer space low
+ rts ; Interrupt handled (carry already set)
+
+ ; Assert flow control if buffer space too low
+Flow: lda RtsOff
+ sta ACIA_CMD,x
+ sta Stopped
+ sec ; Interrupt handled
+Done: rts
+
+;----------------------------------------------------------------------------
+; Try to send a byte. Internal routine. A = TryHard
+
+TryToSend:
+ sta tmp1 ; Remember tryHard flag
+Again: lda SendFreeCnt
+ cmp #$FF
+ beq Quit ; Bail out
+
+ ; Check for flow stopped
+ lda Stopped
+ bne Quit ; Bail out
+
+ ; Check that ACIA is ready to send
+ lda ACIA_STATUS
+ and #$10
+ bne Send
+ bit tmp1 ; Keep trying if must try hard
+ bmi Again
+Quit: rts
+
+ ; Send byte and try again
+Send: ldy SendHead
+ lda SendBuf,y
+ sta ACIA_DATA
+ inc SendHead
+ inc SendFreeCnt
+ jmp Again
--- /dev/null
+;
+; Graphics driver for the 228x200x3 palette mode on the Atmos
+;
+; Stefan Haubenthal <polluks@sdf.lonestar.org>
+; 2012-08-11, Greg King <greg.king5@verizon.net>
+;
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+ .include "atmos.inc"
+
+ .macpack generic
+
+XSIZE = 6 ; System font width
+YSIZE = 8 ; System font height
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table and constants.
+
+.segment "JUMPTABLE"
+
+; The first part of the header is a structure that has a signature,
+; and defines the capabilities of the driver.
+
+ .byte "tgi"
+ .byte TGI_API_VERSION ; TGI API version number
+ .word 228 ; x resolution
+ .word 200 ; y resolution
+ .byte 3 ; Number of drawing colors
+ .byte 1 ; Number of screens available
+ .byte XSIZE ; System font x size
+ .byte YSIZE ; System font y size
+ .word $011C ; Aspect ratio (based on 4/3 display)
+ .byte 0 ; TGI driver flags
+
+; 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 TEXTSTYLE
+ .addr OUTTEXT
+ .addr 0 ; IRQ entry is unused
+
+; ------------------------------------------------------------------------
+; Data.
+
+; Variables mapped to the zero-page segment variables. These are
+; used for passing parameters to the driver.
+
+X1 := ptr1
+Y1 := ptr2
+X2 := ptr3
+Y2 := ptr4
+
+; Absolute variables used in the code
+
+.bss
+
+ERROR: .res 1 ; Error code
+MODE: .res 1 ; Graphics mode
+PALETTE: .res 2
+
+; Constants and table
+; BASIC 1.1 addresses
+PATTERN := $213
+PARAM1 := $2E1 ; & $2E2
+PARAM2 := $2E3 ; & $2E4
+PARAM3 := $2E5 ; & $2E6
+TEXT := $EC21
+HIRES := $EC33
+CURSET := $F0C8
+CURMOV := $F0FD
+DRAW := $F110
+CHAR := $F12D
+POINT := $F1C8
+PAPER := $F204
+INK := $F210
+
+.rodata
+
+; Default colors: black background, white foreground
+; (The third "color" actually flips a pixel
+; between the foreground and background colors.)
+;
+DEFPALETTE: .byte 0, 1
+
+.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 called only once. So, any code that is needed
+; to initialize variables and so on must go here. Setting palette and
+; clearing the screen are not needed because they are called by the graphics
+; kernel later.
+; The graphics kernel never will 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 HIRES
+
+; Done, reset the error code.
+
+; ------------------------------------------------------------------------
+; GETERROR: Return the error code in A, and clear it.
+
+GETERROR:
+ ldx #TGI_ERR_OK
+ lda ERROR
+ stx ERROR
+
+; ------------------------------------------------------------------------
+; 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 probably is 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 never will 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
+
+; ------------------------------------------------------------------------
+; CONTROL: Platform-/driver-specific entry point.
+;
+; Must set an error code: YES
+;
+
+CONTROL:
+ sta PATTERN
+ lda #TGI_ERR_OK
+ sta ERROR
+ rts
+
+; ------------------------------------------------------------------------
+; CLEAR: Clears the screen.
+;
+; Must set an error code: NO
+;
+
+CLEAR := HIRES
+
+; ------------------------------------------------------------------------
+; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
+; The page number already is checked to be valid, by the graphics kernel.
+;
+; Must set an error code: NO (will be called only if page OK)
+;
+
+SETVIEWPAGE:
+
+; ------------------------------------------------------------------------
+; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
+; The page number already is checked to be valid, by the graphics kernel.
+;
+; Must set an error code: NO (will be called only if page OK)
+;
+
+SETDRAWPAGE:
+ rts
+
+; ------------------------------------------------------------------------
+; SETCOLOR: Set the drawing color (in A). The new color already is checked
+; to be in a valid range (0..maxcolor-1).
+;
+; Must set an error code: NO (will be called only if color OK)
+;
+
+SETCOLOR:
+ sta MODE
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ ldy #0
+ jsr flipcolor
+ sty PARAM1+1
+ jsr PAPER
+ ldy #1
+ jsr flipcolor
+ dey ; TGI_ERR_OK
+ sty ERROR
+ sty PARAM1+1
+ jmp INK
+
+flipcolor:
+ lda (ptr1),y
+ sta PALETTE,y
+ cmp #1
+ beq @flip
+ cmp #7
+ bne @keep
+@flip: eor #1 ^ 7
+@keep: sta PARAM1
+ 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:
+ lda #<PALETTE
+ ldx #>PALETTE
+ rts
+
+; ------------------------------------------------------------------------
+; 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 co-ordinates 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:
+ lda Y1
+ sta PARAM2
+ lda MODE
+mymode: sta PARAM3
+ lda X1
+ add #2 * XSIZE ; Skip screen attribute columns
+ sta PARAM1
+ lda #0
+ sta PARAM1+1
+ sta PARAM2+1
+ sta PARAM3+1
+ jmp CURSET
+
+; ------------------------------------------------------------------------
+; GETPIXEL: Read the color value of a pixel, and return it in A/X. The
+; co-ordinates passed to this function are never outside the visible screen
+; area, so there is no need for clipping inside this function.
+
+GETPIXEL:
+ lda X1
+ sta PARAM1
+ lda Y1
+ sta PARAM2
+ lda #0
+ sta PARAM1+1
+ sta PARAM2+1
+ jsr POINT
+ lda PARAM1
+ and #%00000001
+ ldx #0
+ 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:
+ jsr SETPIXEL
+ lda X2
+ sub X1
+ sta PARAM1
+ lda X2+1
+ sbc X1+1
+ sta PARAM1+1
+ lda Y2
+ sub Y1
+ sta PARAM2
+ lda Y2+1
+ sbc Y1+1
+ sta PARAM2+1
+ lda MODE
+ sta PARAM3
+ ldx #>0
+ stx PARAM3+1
+ jmp DRAW
+
+; ------------------------------------------------------------------------
+; 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 co-ordinates 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
+
+; ------------------------------------------------------------------------
+; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in the x
+; and y directions 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 its address in ptr3.
+;
+; Must set an error code: NO
+;
+
+OUTTEXT:
+ lda Y1
+ sub #(YSIZE - 1)
+ sta PARAM2
+ lda #3 ; (Move graphics cursor; don't draw)
+ jsr mymode
+
+ ldy #0
+@next: lda (ptr3),y
+ beq @end
+ sta PARAM1
+ lda #0
+ sta PARAM2
+ sta PARAM1+1
+ sta PARAM2+1
+ sta PARAM3+1
+ lda MODE
+ sta PARAM3
+ tya
+ pha
+ jsr CHAR
+ lda #XSIZE
+ sta PARAM1
+ lda #0
+ sta PARAM2
+ sta PARAM1+1
+ sta PARAM2+1
+ sta PARAM3+1
+ lda #3
+ sta PARAM3
+ jsr CURMOV
+ pla
+ tay
+ iny
+ bne @next
+@end: rts
--- /dev/null
+;
+; Graphics driver for the 240x200x2 monochrome mode on the Atmos
+;
+; Stefan Haubenthal <polluks@sdf.lonestar.org>
+; 2012-08-11, Greg King <greg.king5@verizon.net>
+;
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+ .include "atmos.inc"
+
+ .macpack generic
+
+XSIZE = 6 ; System font width
+YSIZE = 8 ; System font height
+
+; ------------------------------------------------------------------------
+; 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
+ .word 240 ; X resolution
+ .word 200 ; Y resolution
+ .byte 2 ; Number of drawing colors
+ .byte 1 ; Number of screens available
+ .byte XSIZE ; System font X size
+ .byte YSIZE ; System font Y size
+ .word $011C ; Aspect ratio (based on 4/3 display)
+ .byte 0 ; TGI driver flags
+
+; 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 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
+
+; Absolute variables used in the code
+
+.bss
+
+ERROR: .res 1 ; Error code
+MODE: .res 1 ; Graphics mode
+
+; Constants and tables
+PARAM1 = $2E1
+PARAM2 = $2E3
+PARAM3 = $2E5
+TEXT = $EC21
+HIRES = $EC33
+CURSET = $F0C8
+CURMOV = $F0FD
+DRAW = $F110
+CHAR = $F12D
+POINT = $F1C8
+PAPER = $F204
+INK = $F210
+
+.rodata
+
+DEFPALETTE: .byte 0, 1
+
+.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 HIRES
+
+; 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:
+ sta $213
+ lda #TGI_ERR_OK
+ sta ERROR
+ rts
+
+; ------------------------------------------------------------------------
+; CLEAR: Clears the screen.
+;
+; Must set an error code: NO
+;
+
+CLEAR = HIRES
+
+; ------------------------------------------------------------------------
+; 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:
+ sta MODE
+ rts
+
+; ------------------------------------------------------------------------
+; 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 ; This resolution has no palette
+ 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
+;
+
+SETPIXEL:
+ lda Y1
+ sta PARAM2
+ lda MODE
+mymode: sta PARAM3
+ lda X1
+ sta PARAM1
+ lda #0
+ sta PARAM1+1
+ sta PARAM2+1
+ sta PARAM3+1
+ jmp CURSET
+
+; ------------------------------------------------------------------------
+; 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
+ sta PARAM1
+ lda Y1
+ sta PARAM2
+ lda #0
+ sta PARAM1+1
+ sta PARAM2+1
+ jsr POINT
+ lda PARAM1
+ and #%00000001
+ ldx #0
+ 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:
+ jsr SETPIXEL
+ lda X2
+ sub X1
+ sta PARAM1
+ lda X2+1
+ sbc X1+1
+ sta PARAM1+1
+ lda Y2
+ sub Y1
+ sta PARAM2
+ lda Y2+1
+ sbc Y1+1
+ sta PARAM2+1
+ lda MODE
+ sta PARAM3
+ ldx #>0
+ stx PARAM3+1
+ jmp DRAW
+
+; ------------------------------------------------------------------------
+; 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
+
+; ------------------------------------------------------------------------
+; 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 Y1
+ sub #(YSIZE - 1)
+ sta PARAM2
+ lda #3 ; (Move graphics cursor; don't draw)
+ jsr mymode
+
+ ldy #0
+@next: lda (ptr3),y
+ beq @end
+ sta PARAM1
+ lda #0
+ sta PARAM2
+ sta PARAM1+1
+ sta PARAM2+1
+ sta PARAM3+1
+ lda MODE
+ sta PARAM3
+ tya
+ pha
+ jsr CHAR
+ lda #XSIZE
+ sta PARAM1
+ lda #0
+ sta PARAM2
+ sta PARAM1+1
+ sta PARAM2+1
+ sta PARAM3+1
+ lda #3
+ sta PARAM3
+ jsr CURMOV
+ pla
+ tay
+ iny
+ bne @next
+@end: rts
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = c128
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-mou.o: %.mou
- @$(CO) -o $(*)-mou.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-mou.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- break.o \
- c64mode.o \
- cgetc.o \
- clrscr.o \
- conio.o \
- crt0.o \
- color.o \
- cputc.o \
- devnum.o \
- fast.o \
- get_tv.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- kernal.o \
- mainargs.o \
- mcbdefault.o \
- mouse_stat_stddrv.o \
- mouse_stddrv.o \
- randomize.o \
- revers.o \
- slow.o \
- status.o \
- systime.o \
- sysuname.o \
- tgi_colors.o \
- tgi_stat_stddrv.o \
- tgi_stddrv.o \
- toggle_videomode.o \
- videomode.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(MOUS:.mou=-mou.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS = c128-georam.emd \
- c128-ram.emd \
- c128-ram2.emd \
- c128-ramcart.emd \
- c128-reu.emd \
- c128-vdc.emd
-
-JOYS = c128-ptvjoy.joy \
- c128-stdjoy.joy
-
-MOUS = c128-1351.mou \
- c128-joymouse.mou \
- c128-potmouse.mou
-
-SERS = c128-swlink.ser
-
-TGIS = c128-640-200-2.tgi \
- c128-640-480-2.tgi
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(MOUS:.mou=.o) $(MOUS:.mou=-mou.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
+++ /dev/null
-;
-; Driver for the 1351 proportional mouse. Parts of the code are from
-; the Commodore 1351 mouse users guide.
-;
-; Ullrich von Bassewitz, 2003-12-29, 2009-09-26
-;
-
- .include "zeropage.inc"
- .include "mouse-kernel.inc"
- .include "c128.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-HEADER:
-
-; Driver signature
-
- .byte $6d, $6f, $75 ; "mou"
- .byte MOUSE_API_VERSION ; Mouse driver API version number
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr HIDE
- .addr SHOW
- .addr SETBOX
- .addr GETBOX
- .addr MOVE
- .addr BUTTONS
- .addr POS
- .addr INFO
- .addr IOCTL
- .addr IRQ
-
-; Mouse driver flags
-
- .byte MOUSE_FLAG_LATE_IRQ
-
-; Callback table, set by the kernel before INSTALL is called
-
-CHIDE: jmp $0000 ; Hide the cursor
-CSHOW: jmp $0000 ; Show the cursor
-CMOVEX: jmp $0000 ; Move the cursor to X coord
-CMOVEY: jmp $0000 ; Move the cursor to Y coord
-
-
-;----------------------------------------------------------------------------
-; Constants
-
-SCREEN_HEIGHT = 200
-SCREEN_WIDTH = 320
-
-;----------------------------------------------------------------------------
-; Global variables. The bounding box values are sorted so that they can be
-; written with the least effort in the SETBOX and GETBOX routines, so don't
-; reorder them.
-
-.bss
-
-Vars:
-OldPotX: .res 1 ; Old hw counter values
-OldPotY: .res 1
-
-YPos: .res 2 ; Current mouse position, Y
-XPos: .res 2 ; Current mouse position, X
-XMin: .res 2 ; X1 value of bounding box
-YMin: .res 2 ; Y1 value of bounding box
-XMax: .res 2 ; X2 value of bounding box
-YMax: .res 2 ; Y2 value of bounding box
-
-OldValue: .res 1 ; Temp for MoveCheck routine
-NewValue: .res 1 ; Temp for MoveCheck routine
-
-; Default values for above variables
-
-.rodata
-
-.proc DefVars
- .byte 0, 0 ; OldPotX/OldPotY
- .word SCREEN_HEIGHT/2 ; YPos
- .word SCREEN_WIDTH/2 ; XPos
- .word 0 ; XMin
- .word 0 ; YMin
- .word SCREEN_WIDTH ; XMax
- .word SCREEN_HEIGHT ; YMax
-.endproc
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an MOUSE_ERR_xx code in a/x.
-
-INSTALL:
-
-; Initialize variables. Just copy the default stuff over
-
- ldx #.sizeof(DefVars)-1
-@L1: lda DefVars,x
- sta Vars,x
- dex
- bpl @L1
-
-; Be sure the mouse cursor is invisible and at the default location. We
-; need to do that here, because our mouse interrupt handler doesn't set the
-; mouse position if it hasn't changed.
-
- sei
- jsr CHIDE
- lda XPos
- ldx XPos+1
- jsr CMOVEX
- lda YPos
- ldx YPos+1
- jsr CMOVEY
- cli
-
-; Done, return zero (= MOUSE_ERR_OK)
-
- ldx #$00
- txa
- rts ; Run into UNINSTALL instead
-
-;----------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-
-UNINSTALL = HIDE ; Hide cursor on exit
-
-;----------------------------------------------------------------------------
-; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently visible and should get hidden. For most drivers,
-; no special action is required besides hiding the mouse cursor.
-; No return code required.
-
-HIDE: sei
- jsr CHIDE
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently hidden and should become visible. For most drivers,
-; no special action is required besides enabling the mouse cursor.
-; No return code required.
-
-SHOW: sei
- jsr CSHOW
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SETBOX: Set the mouse bounding box. The parameters are passed as they come
-; from the C program, that is, a pointer to a mouse_box struct in a/x.
-; No checks are done if the mouse is currently inside the box, this is the job
-; of the caller. It is not necessary to validate the parameters, trust the
-; caller and save some code here. No return code required.
-
-SETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda (ptr1),y
- sta XMin,y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; GETBOX: Return the mouse bounding box. The parameters are passed as they
-; come from the C program, that is, a pointer to a mouse_box struct in a/x.
-
-GETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda XMin,y
- sta (ptr1),y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; MOVE: Move the mouse to a new position. The position is passed as it comes
-; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
-; remove the parameter from the stack on return.
-; No checks are done if the new position is valid (within the bounding box or
-; the screen). No return code required.
-;
-
-MOVE: sei ; No interrupts
-
- sta YPos
- stx YPos+1 ; New Y position
- jsr CMOVEY ; Set it
-
- ldy #$01
- lda (sp),y
- sta XPos+1
- tax
- dey
- lda (sp),y
- sta XPos ; New X position
-
- jsr CMOVEX ; Move the cursor
-
- cli ; Allow interrupts
- rts
-
-;----------------------------------------------------------------------------
-; BUTTONS: Return the button mask in a/x.
-
-BUTTONS:
- lda #$7F
- sei
- sta CIA1_PRA
- lda CIA1_PRB ; Read joystick #0
- cli
- ldx #0
- and #$1F
- eor #$1F
- rts
-
-;----------------------------------------------------------------------------
-; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
-; No return code required.
-
-POS: ldy #MOUSE_POS::XCOORD ; Structure offset
-
- sei ; Disable interrupts
- lda XPos ; Transfer the position
- sta (ptr1),y
- lda XPos+1
- iny
- sta (ptr1),y
- lda YPos
- iny
- sta (ptr1),y
- lda YPos+1
- cli ; Enable interrupts
-
- iny
- sta (ptr1),y ; Store last byte
-
- rts ; Done
-
-;----------------------------------------------------------------------------
-; INFO: Returns mouse position and current button mask in the MOUSE_INFO
-; struct pointed to by ptr1. No return code required.
-;
-; We're cheating here to keep the code smaller: The first fields of the
-; mouse_info struct are identical to the mouse_pos struct, so we will just
-; call _mouse_pos to initialize the struct pointer and fill the position
-; fields.
-
-INFO: jsr POS
-
-; Fill in the button state
-
- jsr BUTTONS ; Will not touch ptr1
- ldy #MOUSE_INFO::BUTTONS
- sta (ptr1),y
-
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>MOUSE_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
-; (so be careful). The routine MUST return carry set if the interrupt has been
-; 'handled' - which means that the interrupt source is gone. Otherwise it
-; MUST return carry clear.
-;
-
-IRQ: lda SID_ADConv1 ; Get mouse X movement
- ldy OldPotX
- jsr MoveCheck ; Calculate movement vector
- sty OldPotX
-
-; Skip processing if nothing has changed
-
- bcc @SkipX
-
-; Calculate the new X coordinate (--> a/y)
-
- add XPos
- tay ; Remember low byte
- txa
- adc XPos+1
- tax
-
-; Limit the X coordinate to the bounding box
-
- cpy XMin
- sbc XMin+1
- bpl @L1
- ldy XMin
- ldx XMin+1
- jmp @L2
-@L1: txa
-
- cpy XMax
- sbc XMax+1
- bmi @L2
- ldy XMax
- ldx XMax+1
-@L2: sty XPos
- stx XPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jsr CMOVEX
-
-; Calculate the Y movement vector
-
-@SkipX: lda SID_ADConv2 ; Get mouse Y movement
- ldy OldPotY
- jsr MoveCheck ; Calculate movement
- sty OldPotY
-
-; Skip processing if nothing has changed
-
- bcc @SkipY
-
-; Calculate the new Y coordinate (--> a/y)
-
- sta OldValue
- lda YPos
- sub OldValue
- tay
- stx OldValue
- lda YPos+1
- sbc OldValue
- tax
-
-; Limit the Y coordinate to the bounding box
-
- cpy YMin
- sbc YMin+1
- bpl @L3
- ldy YMin
- ldx YMin+1
- jmp @L4
-@L3: txa
-
- cpy YMax
- sbc YMax+1
- bmi @L4
- ldy YMax
- ldx YMax+1
-@L4: sty YPos
- stx YPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jsr CMOVEY
-
-; Done
-
- clc ; Interrupt not "handled"
-@SkipY: rts
-
-; --------------------------------------------------------------------------
-;
-; Move check routine, called for both coordinates.
-;
-; Entry: y = old value of pot register
-; a = current value of pot register
-; Exit: y = value to use for old value
-; x/a = delta value for position
-;
-
-MoveCheck:
- sty OldValue
- sta NewValue
- ldx #$00
-
- sub OldValue ; a = mod64 (new - old)
- and #%01111111
- cmp #%01000000 ; if (a > 0)
- bcs @L1 ;
- lsr a ; a /= 2;
- beq @L2 ; if (a != 0)
- ldy NewValue ; y = NewValue
- sec
- rts ; return
-
-@L1: ora #%11000000 ; else or in high order bits
- cmp #$FF ; if (a != -1)
- beq @L2
- sec
- ror a ; a /= 2
- dex ; high byte = -1 (X = $FF)
- ldy NewValue
- sec
- rts
-
-@L2: txa ; A = $00
- clc
- rts
-
+++ /dev/null
-;
-; Graphics driver for the 640x200x2 mode on the C128 VDC
-; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
-; 23.12.2002
-; 2004-04-04, Greg King
-;
-; NOTES:
-; For any smart monkey that will try to optimize this: PLEASE do tests on
-; real VDC, not only VICE.
-;
-; Only DONE routine contains C128-mode specific stuff, everything else will
-; work in C64-mode of C128 (C64 needs full VDC init then).
-;
-; With special initialization and CALC we can get 320x200 double-pixel mode.
-;
-; Color translation values for BROWN and GRAY3 are obviously wrong, they
-; could be replaced by equiv. of ORANGE and GRAY2 but this would give only
-; 14 of 16 colors available.
-;
-; Register 25 ($19) is said to require different value for VDC v1, but I
-; couldn't find what it should be.
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Constants
-
-VDC_ADDR_REG = $D600 ; VDC address
-VDC_DATA_REG = $D601 ; VDC data
-
-VDC_DSP_HI = 12 ; registers used
-VDC_DSP_LO = 13
-VDC_DATA_HI = 18
-VDC_DATA_LO = 19
-VDC_VSCROLL = 24
-VDC_HSCROLL = 25
-VDC_COLORS = 26
-VDC_CSET = 28
-VDC_COUNT = 30
-VDC_DATA = 31
-
-; ------------------------------------------------------------------------
-; 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 640 ; X resolution
-yres: .word 200 ; Y resolution
- .byte 2 ; Number of drawing colors
-pages: .byte 1 ; Number of screens available
- .byte 8 ; System font X size
- .byte 8 ; System font Y size
- .word $006A ; Aspect ratio (based on 4/3 display)
- .byte 0 ; TGI driver flags
-
-; 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 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
-
-ADDR = tmp1
-TEMP = tmp3
-TEMP2 = tmp4 ; HORLINE
-TEMP3 = sreg ; HORLINE
-
-; Absolute variables used in the code
-
-.bss
-
-SCRBASE: .res 1 ; High byte of screen base
-
-ERROR: .res 1 ; Error code
-PALETTE: .res 2 ; The current palette
-
-BITMASK: .res 1 ; $00 = clear, $FF = set pixels
-
-OLDCOLOR: .res 1 ; colors before entering gfx mode
-
-; Text output stuff
-TEXTMAGX: .res 1
-TEXTMAGY: .res 1
-TEXTDIR: .res 1
-
-; Constants and tables
-
-.rodata
-
-DEFPALETTE: .byte $00, $0f ; White on black
-PALETTESIZE = * - DEFPALETTE
-
-BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01
-
-BITMASKL: .byte %11111111, %01111111, %00111111, %00011111
- .byte %00001111, %00000111, %00000011, %00000001
-
-BITMASKR: .byte %10000000, %11000000, %11100000, %11110000
- .byte %11111000, %11111100, %11111110, %11111111
-
-; color translation table (indexed by VIC color)
-COLTRANS: .byte $00, $0f, $08, $06, $0a, $04, $02, $0c
- .byte $0d, $0b, $09, $01, $0e, $05, $03, $07
- ; colors BROWN and GRAY3 are wrong
-
-; VDC initialization table (reg),(val),...,$ff
-InitVDCTab:
- .byte VDC_DSP_HI, 0 ; viewpage 0 as default
- .byte VDC_DSP_LO, 0
- .byte VDC_HSCROLL, $87
- .byte $ff
-
-SCN80CLR: .byte 27,88,147,27,88,0
-
-.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:
- ; check for VDC version and update register $19 value
-
- ; check for VDC ram size and update number of available screens
-
- ldx #VDC_CSET ; determine size of RAM...
- jsr VDCReadReg
- sta tmp1
- ora #%00010000
- jsr VDCWriteReg ; turn on 64k
-
- jsr settestadr1 ; save original value of test byte
- jsr VDCReadByte
- sta tmp2
-
- lda #$55 ; write $55 here
- ldy #ptr1
- jsr test64k ; read it here and there
- lda #$aa ; write $aa here
- ldy #ptr2
- jsr test64k ; read it here and there
-
- jsr settestadr1
- lda tmp2
- jsr VDCWriteByte ; restore original value of test byte
-
- lda ptr1 ; do bytes match?
- cmp ptr1+1
- bne @have64k
- lda ptr2
- cmp ptr2+1
- bne @have64k
-
- ldx #VDC_CSET
- lda tmp1
- jsr VDCWriteReg ; restore 16/64k flag
- jmp @endok ; and leave default values for 16k
-
-@have64k:
- lda #4
- sta pages
-@endok:
- lda #0
- sta SCRBASE ; draw page 0 as default
- rts
-
-test64k:
- sta tmp1
- sty ptr3
- lda #0
- sta ptr3+1
- jsr settestadr1
- lda tmp1
- jsr VDCWriteByte ; write $55
- jsr settestadr1
- jsr VDCReadByte ; read here
- pha
- jsr settestadr2
- jsr VDCReadByte ; and there
- ldy #1
- sta (ptr3),y
- pla
- dey
- sta (ptr3),y
- rts
-
-settestadr1:
- ldy #$02 ; test page 2 (here)
- .byte $2c
-settestadr2:
- ldy #$42 ; or page 64+2 (there)
- lda #0
- jmp VDCSetSourceAddr
-
-; ------------------------------------------------------------------------
-; 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:
-
-; Initialize variables
-
-@L1: ldx #$FF
- stx BITMASK
-
-; Remeber current color value
- ldx #VDC_COLORS
- jsr VDCReadReg
- sta OLDCOLOR
-
-; Switch into graphics mode (set view page 0)
-
- ldy #0
-@L2: ldx InitVDCTab,y
- bmi @L3
- iny
- lda InitVDCTab,y
- jsr VDCWriteReg
- iny
- bne @L2
-@L3:
-
-; 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:
- ; This part is C128-mode specific
- jsr $e179 ; reload character set and setup VDC
- jsr $ff62
- lda $d7 ; in 80-columns?
- bne @L01
-@L0: lda SCN80CLR,y
- beq @L1
- jsr $ffd2 ; print \xe,clr,\xe
- iny
- bne @L0
-@L01: lda #147
- jsr $ffd2 ; print clr
-@L1: lda #0 ; restore view page
- ldx #VDC_DSP_HI
- jsr VDCWriteReg
- lda OLDCOLOR
- ldx #VDC_COLORS
- jsr VDCWriteReg ; restore color (background)
- lda #$47
- ldx #VDC_HSCROLL
- jmp VDCWriteReg ; switch to text screen
-
-; ------------------------------------------------------------------------
-; 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:
- lda #0
- ldy SCRBASE
- jsr VDCSetSourceAddr
- lda #0
- ldx #VDC_VSCROLL
- jsr VDCWriteReg ; set fill mode
- lda #0
- jsr VDCWriteByte ; put 1rst byte (fill value)
- ldy #62 ; 62 times
- lda #0 ; 256 bytes
- ldx #VDC_COUNT
-@L1: jsr VDCWriteReg
- dey
- bne @L1
- lda #127
- jmp VDCWriteReg ; 1+62*256+127=16000=(640*256)/8
-
-; ------------------------------------------------------------------------
-; 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:
- clc
- ror
- ror
- ror
- ldx #VDC_DSP_HI
- jmp VDCWriteReg
-
-; ------------------------------------------------------------------------
-; 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:
- clc
- ror
- ror
- ror
- sta SCRBASE
- 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
- beq @L1
- lda #$FF
-@L1: sta BITMASK
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- ldy #PALETTESIZE - 1
-@L1: lda (ptr1),y ; Copy the palette
- and #$0F ; Make a valid color
- sta PALETTE,y
- dey
- bpl @L1
-
-; Get the color entries from the palette
-
- ldy PALETTE+1 ; Foreground color
- lda COLTRANS,y
- asl a
- asl a
- asl a
- asl a
- ldy PALETTE ; Background color
- ora COLTRANS,y
-
- ldx #VDC_COLORS
- jsr VDCWriteReg
- lda #TGI_ERR_OK ; Clear error code
- 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:
- lda #<PALETTE
- ldx #>PALETTE
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- jsr CALC ; Calculate coordinates
-
- stx TEMP
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- ldx TEMP
-
- sta TEMP
- eor BITMASK
- and BITTAB,X
- eor TEMP
- pha
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- pla
- jsr VDCWriteByte
-
-@L9: 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:
- jsr CALC ; Calculate coordinates
-
- stx TEMP ; preserve X
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- ldx TEMP
-
- ldy #$00
- and BITTAB,X
- beq @L1
- iny
-
-@L1: tya ; Get color value into A
- ldx #$00 ; Clear high byte
- 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
- bne HORLINE
- inc Y2+1
-
-; Original code for a horizontal line
-
-HORLINE:
- lda X1
- pha
- lda X1+1
- pha
- jsr CALC ; get data for LEFT
- lda BITMASKL,x ; remember left address and bitmask
- pha
- lda ADDR
- pha
- lda ADDR+1
- pha
-
- lda X2
- sta X1
- lda X2+1
- sta X1+1
- jsr CALC ; get data for RIGHT
- lda BITMASKR,x
- sta TEMP3
-
- pla ; recall data for LEFT
- sta X1+1
- pla
- sta X1 ; put left address into X1
- pla
-
- cmp #%11111111 ; if left bit <> 0
- beq @L1
- sta TEMP2 ; do left byte only...
- lda X1
- ldy X1+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- sta TEMP
- eor BITMASK
- and TEMP2
- eor TEMP
- pha
- lda X1
- ldy X1+1
- jsr VDCSetSourceAddr
- pla
- jsr VDCWriteByte
- inc X1 ; ... and proceed
- bne @L1
- inc X1+1
-
- ; do right byte (if Y2=0 ++ADDR and skip)
-@L1: lda TEMP3
- cmp #%11111111 ; if right bit <> 7
- bne @L11
- inc ADDR ; right bit = 7 - the next one is the last
- bne @L10
- inc ADDR+1
-@L10: bne @L2
-
-@L11: lda ADDR ; do right byte only...
- ldy ADDR+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- sta TEMP
- eor BITMASK
- and TEMP3
- eor TEMP
- pha
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- pla
- jsr VDCWriteByte
-
-@L2: ; do the fill in the middle
- lda ADDR ; calculate offset in full bytes
- sec
- sbc X1
- beq @L3 ; if equal - there are no more bytes
- sta ADDR
-
- lda X1 ; setup for the left side
- ldy X1+1
- jsr VDCSetSourceAddr
- lda BITMASK ; get color
- jsr VDCWriteByte ; put 1st value
- ldx ADDR
- dex
- beq @L3 ; 1 byte already written
-
- stx ADDR ; if there are more bytes - fill them...
- ldx #VDC_VSCROLL
- lda #0
- jsr VDCWriteReg ; setup for fill
- ldx #VDC_COUNT
- lda ADDR
- jsr VDCWriteReg ; ... fill them NOW!
-
-@L3: pla
- sta X1+1
- pla
- sta X1
-
-; End of horizontal line code
-
- inc Y1
- bne @L4
- inc Y1+1
-@L4: lda Y1
- cmp Y2
- bne @L5
- lda Y1+1
- cmp Y2+1
- bne @L5
- rts
-
-@L5: jmp HORLINE
-
-
-; ------------------------------------------------------------------------
-; 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
- 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:
- rts
-
-; ------------------------------------------------------------------------
-; Calculate all variables to plot the pixel at X1/Y1.
-;------------------------
-;< X1,Y1 - pixel
-;> ADDR - address of card
-;> X - bit number (X1 & 7)
-CALC:
- lda Y1+1
- sta ADDR+1
- lda Y1
- asl
- rol ADDR+1
- asl
- rol ADDR+1 ; Y*4
- clc
- adc Y1
- sta ADDR
- lda Y1+1
- adc ADDR+1
- sta ADDR+1 ; Y*4+Y=Y*5
- lda ADDR
- asl
- rol ADDR+1
- asl
- rol ADDR+1
- asl
- rol ADDR+1
- asl
- rol ADDR+1
- sta ADDR ; Y*5*16=Y*80
- lda X1+1
- sta TEMP
- lda X1
- lsr TEMP
- ror
- lsr TEMP
- ror
- lsr TEMP
- ror
- clc
- adc ADDR
- sta ADDR
- lda ADDR+1 ; ADDR = Y*80+x/8
- adc TEMP
- sta ADDR+1
- lda ADDR+1
- adc SCRBASE
- sta ADDR+1
- lda X1
- and #7
- tax
- rts
-
-;-------------
-; VDC helpers
-
-VDCSetSourceAddr:
- pha
- tya
- ldx #VDC_DATA_HI
- jsr VDCWriteReg
- pla
- ldx #VDC_DATA_LO
- bne VDCWriteReg
-
-VDCReadByte:
- ldx #VDC_DATA
-VDCReadReg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda VDC_DATA_REG
- rts
-
-VDCWriteByte:
- ldx #VDC_DATA
-VDCWriteReg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- sta VDC_DATA_REG
- rts
-
-; ------------------------------------------------------------------------
-
- .include "../tgi/tgidrv_line.inc"
+++ /dev/null
-;
-; Graphics driver for the 640x480x2 mode on the C128 VDC 64k
-; (values for this mode based on Fred Bowen's document)
-; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
-; 23.12.2002
-; 2004-04-04, Greg King
-;
-; NOTES:
-; For any smart monkey that will try to optimize this: PLEASE do tests on
-; real VDC, not only VICE.
-;
-; Only DONE routine contains C128-mode specific stuff, everything else will
-; work in C64-mode of C128 (C64 needs full VDC init then).
-;
-; With special initialization and CALC we can get 320x200 double-pixel mode.
-;
-; Color translation values for BROWN and GRAY3 are obviously wrong, they
-; could be replaced by equiv. of ORANGE and GRAY2 but this would give only
-; 14 of 16 colors available.
-;
-; Register 25 ($19) is said to require different value for VDC v1, but I
-; couldn't find what it should be.
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Constants
-
-VDC_ADDR_REG = $D600 ; VDC address
-VDC_DATA_REG = $D601 ; VDC data
-
-VDC_DSP_HI = 12 ; registers used
-VDC_DSP_LO = 13
-VDC_DATA_HI = 18
-VDC_DATA_LO = 19
-VDC_VSCROLL = 24
-VDC_HSCROLL = 25
-VDC_COLORS = 26
-VDC_CSET = 28
-VDC_COUNT = 30
-VDC_DATA = 31
-
-; ------------------------------------------------------------------------
-; 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 640 ; X resolution
-yres: .word 480 ; Y resolution
- .byte 2 ; Number of drawing colors
-pages: .byte 0 ; Number of screens available
- .byte 8 ; System font X size
- .byte 8 ; System font Y size
- .word $0100 ; Aspect ratio (based on 4/3 display)
- .byte 0 ; TGI driver flags
-
-; 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 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
-
-ADDR = tmp1
-TEMP = tmp3
-TEMP2 = tmp4 ; HORLINE
-TEMP3 = sreg ; HORLINE
-
-; Absolute variables used in the code
-
-.bss
-
-ERROR: .res 1 ; Error code
-PALETTE: .res 2 ; The current palette
-
-BITMASK: .res 1 ; $00 = clear, $FF = set pixels
-
-OLDCOLOR: .res 1 ; colors before entering gfx mode
-
-; Text output stuff
-TEXTMAGX: .res 1
-TEXTMAGY: .res 1
-TEXTDIR: .res 1
-
-; Constants and tables
-
-.rodata
-
-DEFPALETTE: .byte $00, $0f ; White on black
-PALETTESIZE = * - DEFPALETTE
-
-BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01
-
-BITMASKL: .byte %11111111, %01111111, %00111111, %00011111
- .byte %00001111, %00000111, %00000011, %00000001
-
-BITMASKR: .byte %10000000, %11000000, %11100000, %11110000
- .byte %11111000, %11111100, %11111110, %11111111
-
-; color translation table (indexed by VIC color)
-COLTRANS: .byte $00, $0f, $08, $06, $0a, $04, $02, $0c
- .byte $0d, $0b, $09, $01, $0e, $05, $03, $07
- ; colors BROWN and GRAY3 are wrong
-
-; VDC initialization table (reg),(val),...,$ff
-InitVDCTab:
- .byte VDC_DSP_HI, 0 ; viewpage 0 as default
- .byte VDC_DSP_LO, 0
- .byte VDC_HSCROLL, $87
- .byte 2, $66
- .byte 4, $4c
- .byte 5, $06
- .byte 6, $4c
- .byte 7, $47
- .byte 8, $03
- .byte 9, $06
- .byte 27, $00
- .byte $ff
-
-SCN80CLR: .byte 27,88,147,27,88,0
-
-.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:
- ; check for VDC version and update register $19 value
-
- ; check for VDC ram size and update number of available screens
-
- ldx #VDC_CSET ; determine size of RAM...
- jsr VDCReadReg
- sta tmp1
- ora #%00010000
- jsr VDCWriteReg ; turn on 64k
-
- jsr settestadr1 ; save original value of test byte
- jsr VDCReadByte
- sta tmp2
-
- lda #$55 ; write $55 here
- ldy #ptr1
- jsr test64k ; read it here and there
- lda #$aa ; write $aa here
- ldy #ptr2
- jsr test64k ; read it here and there
-
- jsr settestadr1
- lda tmp2
- jsr VDCWriteByte ; restore original value of test byte
-
- lda ptr1 ; do bytes match?
- cmp ptr1+1
- bne @have64k
- lda ptr2
- cmp ptr2+1
- bne @have64k
-
- ldx #VDC_CSET
- lda tmp1
- jsr VDCWriteReg ; restore 16/64k flag
- jmp @endok ; and leave default values for 16k
-
-@have64k:
- lda #1
- sta pages
-@endok:
- rts
-
-test64k:
- sta tmp1
- sty ptr3
- lda #0
- sta ptr3+1
- jsr settestadr1
- lda tmp1
- jsr VDCWriteByte ; write $55
- jsr settestadr1
- jsr VDCReadByte ; read here
- pha
- jsr settestadr2
- jsr VDCReadByte ; and there
- ldy #1
- sta (ptr3),y
- pla
- dey
- sta (ptr3),y
- rts
-
-settestadr1:
- ldy #$02 ; test page 2 (here)
- .byte $2c
-settestadr2:
- ldy #$42 ; or page 64+2 (there)
- lda #0
- jmp VDCSetSourceAddr
-
-; ------------------------------------------------------------------------
-; 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:
- lda pages ; is there enough memory?
- bne @L1 ; Jump if there is one screen
- lda #TGI_ERR_INV_MODE ; Error
- bne @L9
-
-; Initialize variables
-
-@L1: ldx #$FF
- stx BITMASK
-
-; Remeber current color value
- ldx #VDC_COLORS
- jsr VDCReadReg
- sta OLDCOLOR
-
-; Switch into graphics mode (set view page 0)
-
- ldy #0
-@L2: ldx InitVDCTab,y
- bmi @L3
- iny
- lda InitVDCTab,y
- jsr VDCWriteReg
- iny
- bne @L2
-@L3:
-
-; Done, reset the error code
-
- lda #TGI_ERR_OK
-@L9: 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:
- ; This part is C128-mode specific
- jsr $e179 ; reload character set and setup VDC
- jsr $ff62
- lda $d7 ; in 80-columns?
- bne @L01
-@L0: lda SCN80CLR,y
- beq @L1
- jsr $ffd2 ; print \xe,clr,\xe
- iny
- bne @L0
-@L01: lda #147
- jsr $ffd2 ; print clr
-@L1: lda #0 ; restore view page
- ldx #VDC_DSP_HI
- jsr VDCWriteReg
- lda OLDCOLOR
- ldx #VDC_COLORS
- jsr VDCWriteReg ; restore color (background)
- lda #$47
- ldx #VDC_HSCROLL
- jmp VDCWriteReg ; switch to text screen
-
-; ------------------------------------------------------------------------
-; 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:
- lda #0
- tay
- jsr VDCSetSourceAddr
- lda #0
- ldx #VDC_VSCROLL
- jsr VDCWriteReg ; set fill mode
- lda #0
- jsr VDCWriteByte ; put 1rst byte (fill value)
- ldy #159 ; 159 times
- lda #0 ; 256 bytes
- ldx #VDC_COUNT
-@L1: jsr VDCWriteReg
- dey
- bne @L1
- 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:
- 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:
- 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
- beq @L1
- lda #$FF
-@L1: sta BITMASK
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- ldy #PALETTESIZE - 1
-@L1: lda (ptr1),y ; Copy the palette
- and #$0F ; Make a valid color
- sta PALETTE,y
- dey
- bpl @L1
-
-; Get the color entries from the palette
-
- ldy PALETTE+1 ; Foreground color
- lda COLTRANS,y
- asl a
- asl a
- asl a
- asl a
- ldy PALETTE ; Background color
- ora COLTRANS,y
-
- ldx #VDC_COLORS
- jsr VDCWriteReg
- lda #TGI_ERR_OK ; Clear error code
- 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:
- lda #<PALETTE
- ldx #>PALETTE
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- jsr CALC ; Calculate coordinates
-
- stx TEMP
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- ldx TEMP
-
- sta TEMP
- eor BITMASK
- and BITTAB,X
- eor TEMP
- pha
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- pla
- jsr VDCWriteByte
-
-@L9: 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:
- jsr CALC ; Calculate coordinates
-
- stx TEMP ; preserve X
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- ldx TEMP
-
- ldy #$00
- and BITTAB,X
- beq @L1
- iny
-
-@L1: tya ; Get color value into A
- ldx #$00 ; Clear high byte
- 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
- bne HORLINE
- inc Y2+1
-
-; Original code for a horizontal line
-
-HORLINE:
- lda X1
- pha
- lda X1+1
- pha
- jsr CALC ; get data for LEFT
- lda BITMASKL,x ; remember left address and bitmask
- pha
- lda ADDR
- pha
- lda ADDR+1
- pha
-
- lda X2
- sta X1
- lda X2+1
- sta X1+1
- jsr CALC ; get data for RIGHT
- lda BITMASKR,x
- sta TEMP3
-
- pla ; recall data for LEFT
- sta X1+1
- pla
- sta X1 ; put left address into X1
- pla
-
- cmp #%11111111 ; if left bit <> 0
- beq @L1
- sta TEMP2 ; do left byte only...
- lda X1
- ldy X1+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- sta TEMP
- eor BITMASK
- and TEMP2
- eor TEMP
- pha
- lda X1
- ldy X1+1
- jsr VDCSetSourceAddr
- pla
- jsr VDCWriteByte
- inc X1 ; ... and proceed
- bne @L1
- inc X1+1
-
- ; do right byte (if Y2=0 ++ADDR and skip)
-@L1: lda TEMP3
- cmp #%11111111 ; if right bit <> 7
- bne @L11
- inc ADDR ; right bit = 7 - the next one is the last
- bne @L10
- inc ADDR+1
-@L10: bne @L2
-
-@L11: lda ADDR ; do right byte only...
- ldy ADDR+1
- jsr VDCSetSourceAddr
- jsr VDCReadByte
- sta TEMP
- eor BITMASK
- and TEMP3
- eor TEMP
- pha
- lda ADDR
- ldy ADDR+1
- jsr VDCSetSourceAddr
- pla
- jsr VDCWriteByte
-
-@L2: ; do the fill in the middle
- lda ADDR ; calculate offset in full bytes
- sec
- sbc X1
- beq @L3 ; if equal - there are no more bytes
- sta ADDR
-
- lda X1 ; setup for the left side
- ldy X1+1
- jsr VDCSetSourceAddr
- lda BITMASK ; get color
- jsr VDCWriteByte ; put 1st value
- ldx ADDR
- dex
- beq @L3 ; 1 byte already written
-
- stx ADDR ; if there are more bytes - fill them...
- ldx #VDC_VSCROLL
- lda #0
- jsr VDCWriteReg ; setup for fill
- ldx #VDC_COUNT
- lda ADDR
- jsr VDCWriteReg ; ... fill them NOW!
-
-@L3: pla
- sta X1+1
- pla
- sta X1
-
-; End of horizontal line code
-
- inc Y1
- bne @L4
- inc Y1+1
-@L4: lda Y1
- cmp Y2
- bne @L5
- lda Y1+1
- cmp Y2+1
- bne @L5
- rts
-
-@L5: jmp HORLINE
-
-
-; ------------------------------------------------------------------------
-; 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
- 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:
- rts
-
-; ------------------------------------------------------------------------
-; Calculate all variables to plot the pixel at X1/Y1.
-;------------------------
-;< X1,Y1 - pixel
-;> ADDR - address of card
-;> X - bit number (X1 & 7)
-CALC:
- lda Y1
- pha
- lda Y1+1
- pha
- lsr
- ror Y1 ; Y=Y/2
- sta Y1+1
- sta ADDR+1
- lda Y1
- asl
- rol ADDR+1
- asl
- rol ADDR+1 ; Y*4
- clc
- adc Y1
- sta ADDR
- lda Y1+1
- adc ADDR+1
- sta ADDR+1 ; Y*4+Y=Y*5
- lda ADDR
- asl
- rol ADDR+1
- asl
- rol ADDR+1
- asl
- rol ADDR+1
- asl
- rol ADDR+1
- sta ADDR ; Y*5*16=Y*80
- lda X1+1
- sta TEMP
- lda X1
- lsr TEMP
- ror
- lsr TEMP
- ror
- lsr TEMP
- ror
- clc
- adc ADDR
- sta ADDR
- lda ADDR+1 ; ADDR = Y*80+x/8
- adc TEMP
- sta ADDR+1
- pla
- sta Y1+1
- pla
- sta Y1
- and #1
- beq @even ; even line - no offset
- lda ADDR
- clc
- adc #<21360
- sta ADDR
- lda ADDR+1
- adc #>21360
- sta ADDR+1 ; odd lines are 21360 bytes farther
-@even: lda X1
- and #7
- tax
- rts
-
-;-------------
-; VDC helpers
-
-VDCSetSourceAddr:
- pha
- tya
- ldx #VDC_DATA_HI
- jsr VDCWriteReg
- pla
- ldx #VDC_DATA_LO
- bne VDCWriteReg
-
-VDCReadByte:
- ldx #VDC_DATA
-VDCReadReg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda VDC_DATA_REG
- rts
-
-VDCWriteByte:
- ldx #VDC_DATA
-VDCWriteReg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- sta VDC_DATA_REG
- rts
-
-; ------------------------------------------------------------------------
-
- .include "../tgi/tgidrv_line.inc"
+++ /dev/null
-;
-; Extended memory driver for the GEORAM cartridge. Driver works without
-; problems when statically linked.
-;
-; Ullrich von Bassewitz, 2002-11-29
-;
-; GEORAM page size checking routine by
-; Marco van den Heuvel, 2010-01-21
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-GR_WINDOW = $DE00 ; Address of GEORAM window
-GR_PAGE_LO = $DFFE ; Page register low
-GR_PAGE_HI = $DFFF ; Page register high
-
-; ------------------------------------------------------------------------
-; Data.
-
-.data
-
-pagecount: .res 2 ; Number of available pages
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx GR_WINDOW
- cpx GR_WINDOW
- bne @notpresent
- inc GR_WINDOW
- cpx GR_WINDOW
- beq @notpresent
-
- lda #4
- jsr check
- cpy GR_WINDOW
- beq @has64k
- lda #8
- jsr check
- cpy GR_WINDOW
- beq @has128k
- lda #16
- jsr check
- cpy GR_WINDOW
- beq @has256k
- lda #32
- jsr check
- cpy GR_WINDOW
- beq @has512k
- lda #64
- jsr check
- cpy GR_WINDOW
- beq @has1024k
- lda #128
- jsr check
- cpy GR_WINDOW
- beq @has2048k
- ldx #>16384
- bne @setok
-
-@has64k:
- ldx #>256
- bne @setok
-@has128k:
- ldx #>512
- bne @setok
-@has256k:
- ldx #>1024
- bne @setok
-@has512k:
- ldx #>2048
- bne @setok
-@has1024k:
- ldx #>4096
- bne @setok
-@has2048k:
- ldx #>8192
- bne @setok
-
-@notpresent:
- lda #<EM_ERR_NO_DEVICE
- ldx #>EM_ERR_NO_DEVICE
- rts
-
-@setok:
- lda #0
- sta pagecount
- stx pagecount+1
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
- rts
-
-check:
- ldx #0
- stx GR_PAGE_LO
- stx GR_PAGE_HI
- ldy GR_WINDOW
- iny
- sta GR_PAGE_HI
- sty GR_WINDOW
- ldx #0
- stx GR_PAGE_HI
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-; The GeoRAM cartridge does not copy but actually map the window, so USE is
-; identical to MAP.
-
-USE = MAP
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta tmp1
- txa
- asl tmp1
- rol a
- asl tmp1
- rol a
-
- sta GR_PAGE_HI
- lda tmp1
- lsr a
- lsr a
- sta GR_PAGE_LO
-
- lda #<GR_WINDOW
- ldx #>GR_WINDOW
-
-; Use the RTS from COMMIT below to save a precious byte of storage
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - tmp2 contains the high page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1: lda GR_WINDOW,x
- sta (ptr2),y
- iny
- bne @L2
- inc ptr2+1
-@L2: inx
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4: inc tmp1 ; Bump low page register
- bit tmp1 ; Check for overflow in bit 6
- bvc @L6 ; Jump if no overflow
- inc tmp2
-@L5: lda tmp2
- sta GR_PAGE_HI
-@L6: lda tmp1
- sta GR_PAGE_LO
- jmp @L3
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - tmp2 contains the high page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1: lda (ptr2),y
- sta GR_WINDOW,x
- iny
- bne @L2
- inc ptr2+1
-@L2: inx
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4: inc tmp1 ; Bump low page register
- bit tmp1 ; Check for overflow in bit 6
- bvc @L6 ; Jump if no overflow
- inc tmp2
-@L5: lda tmp2
- sta GR_PAGE_HI
-@L6: lda tmp1
- sta GR_PAGE_LO
- jmp @L3
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-
-setup: sta ptr1
- stx ptr1+1 ; Save passed pointer
-
-; Get the page number from the struct and adjust it so that it may be used
-; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
-
- ldy #EM_COPY::PAGE+1
- lda (ptr1),y
- sta tmp2
- dey
- lda (ptr1),y
- asl a
- rol tmp2
- asl a
- rol tmp2
- lsr a
- lsr a
- sta tmp1
-
-; Get the buffer pointer into ptr2
-
- ldy #EM_COPY::BUF
- lda (ptr1),y
- sta ptr2
- iny
- lda (ptr1),y
- sta ptr2+1
-
-; Get the count, calculate -(count-1) and store it into ptr3
-
- ldy #EM_COPY::COUNT
- lda (ptr1),y
- eor #$FF
- sta ptr3
- iny
- lda (ptr1),y
- eor #$FF
- sta ptr3+1
-
-; Get the page offset into X and clear Y
-
- ldy #EM_COPY::OFFS
- lda (ptr1),y
- tax
- ldy #$00
-
-; Done
-
- rts
-
-
+++ /dev/null
-;
-; Driver for a "joystick mouse".
-;
-; Ullrich von Bassewitz, 2004-04-05, 2009-09-26
-;
-
- .include "zeropage.inc"
- .include "mouse-kernel.inc"
- .include "c128.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-HEADER:
-
-; Driver signature
-
- .byte $6d, $6f, $75 ; "mou"
- .byte MOUSE_API_VERSION ; Mouse driver API version number
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr HIDE
- .addr SHOW
- .addr SETBOX
- .addr GETBOX
- .addr MOVE
- .addr BUTTONS
- .addr POS
- .addr INFO
- .addr IOCTL
- .addr IRQ
-
-; Mouse driver flags
-
- .byte MOUSE_FLAG_LATE_IRQ
-
-; Callback table, set by the kernel before INSTALL is called
-
-CHIDE: jmp $0000 ; Hide the cursor
-CSHOW: jmp $0000 ; Show the cursor
-CMOVEX: jmp $0000 ; Move the cursor to X coord
-CMOVEY: jmp $0000 ; Move the cursor to Y coord
-
-
-;----------------------------------------------------------------------------
-; Constants
-
-SCREEN_HEIGHT = 200
-SCREEN_WIDTH = 320
-
-.enum JOY
- UP = $01
- DOWN = $02
- LEFT = $04
- RIGHT = $08
- FIRE = $10
-.endenum
-
-;----------------------------------------------------------------------------
-; Global variables. The bounding box values are sorted so that they can be
-; written with the least effort in the SETBOX and GETBOX routines, so don't
-; reorder them.
-
-.bss
-
-Vars:
-YPos: .res 2 ; Current mouse position, Y
-XPos: .res 2 ; Current mouse position, X
-XMin: .res 2 ; X1 value of bounding box
-YMin: .res 2 ; Y1 value of bounding box
-XMax: .res 2 ; X2 value of bounding box
-YMax: .res 2 ; Y2 value of bounding box
-Buttons: .res 1 ; Button mask
-
-; Temporary value used in the int handler
-
-Temp: .res 1
-
-; Default values for above variables
-
-.rodata
-
-.proc DefVars
- .word SCREEN_HEIGHT/2 ; YPos
- .word SCREEN_WIDTH/2 ; XPos
- .word 0 ; XMin
- .word 0 ; YMin
- .word SCREEN_WIDTH ; XMax
- .word SCREEN_HEIGHT ; YMax
- .byte 0 ; Buttons
-.endproc
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an MOUSE_ERR_xx code in a/x.
-
-INSTALL:
-
-; Initialize variables. Just copy the default stuff over
-
- ldx #.sizeof(DefVars)-1
-@L1: lda DefVars,x
- sta Vars,x
- dex
- bpl @L1
-
-; Be sure the mouse cursor is invisible and at the default location. We
-; need to do that here, because our mouse interrupt handler doesn't set the
-; mouse position if it hasn't changed.
-
- sei
- jsr CHIDE
- lda XPos
- ldx XPos+1
- jsr CMOVEX
- lda YPos
- ldx YPos+1
- jsr CMOVEY
- cli
-
-; Done, return zero (= MOUSE_ERR_OK)
-
- ldx #$00
- txa
- rts
-
-;----------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-
-UNINSTALL = HIDE ; Hide cursor on exit
-
-;----------------------------------------------------------------------------
-; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently visible and should get hidden. For most drivers,
-; no special action is required besides hiding the mouse cursor.
-; No return code required.
-
-HIDE: sei
- jsr CHIDE
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently hidden and should become visible. For most drivers,
-; no special action is required besides enabling the mouse cursor.
-; No return code required.
-
-SHOW: sei
- jsr CSHOW
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SETBOX: Set the mouse bounding box. The parameters are passed as they come
-; from the C program, that is, a pointer to a mouse_box struct in a/x.
-; No checks are done if the mouse is currently inside the box, this is the job
-; of the caller. It is not necessary to validate the parameters, trust the
-; caller and save some code here. No return code required.
-
-SETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda (ptr1),y
- sta XMin,y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; GETBOX: Return the mouse bounding box. The parameters are passed as they
-; come from the C program, that is, a pointer to a mouse_box struct in a/x.
-
-GETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda XMin,y
- sta (ptr1),y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; MOVE: Move the mouse to a new position. The position is passed as it comes
-; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
-; remove the parameter from the stack on return.
-; No checks are done if the new position is valid (within the bounding box or
-; the screen). No return code required.
-;
-
-MOVE: sei ; No interrupts
-
- sta YPos
- stx YPos+1 ; New Y position
- jsr CMOVEY ; Set it
-
- ldy #$01
- lda (sp),y
- sta XPos+1
- tax
- dey
- lda (sp),y
- sta XPos ; New X position
-
- jsr CMOVEX ; Move the cursor
-
- cli ; Allow interrupts
- rts
-
-;----------------------------------------------------------------------------
-; BUTTONS: Return the button mask in a/x.
-
-BUTTONS:
- lda Buttons
- ldx #$00
- rts
-
-;----------------------------------------------------------------------------
-; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
-; No return code required.
-
-POS: ldy #MOUSE_POS::XCOORD ; Structure offset
-
- sei ; Disable interrupts
- lda XPos ; Transfer the position
- sta (ptr1),y
- lda XPos+1
- iny
- sta (ptr1),y
- lda YPos
- iny
- sta (ptr1),y
- lda YPos+1
- cli ; Enable interrupts
-
- iny
- sta (ptr1),y ; Store last byte
-
- rts ; Done
-
-;----------------------------------------------------------------------------
-; INFO: Returns mouse position and current button mask in the MOUSE_INFO
-; struct pointed to by ptr1. No return code required.
-;
-; We're cheating here to keep the code smaller: The first fields of the
-; mouse_info struct are identical to the mouse_pos struct, so we will just
-; call _mouse_pos to initialize the struct pointer and fill the position
-; fields.
-
-INFO: jsr POS
-
-; Fill in the button state
-
- lda Buttons
- ldy #MOUSE_INFO::BUTTONS
- sta (ptr1),y
-
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>MOUSE_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
-; (so be careful). The routine MUST return carry set if the interrupt has been
-; 'handled' - which means that the interrupt source is gone. Otherwise it
-; MUST return carry clear.
-;
-
-IRQ: lda #$7F
- sta CIA1_PRA
- lda CIA1_PRB ; Read joystick #0
- and #$1F
- eor #$1F ; Make all bits active high
- sta Temp
-
-; Check for a pressed button and place the result into Buttons
-
- ldx #$00 ; Assume no button pressed
- and #JOY::FIRE ; Check fire button
- beq @L0 ; Jump if not pressed
- ldx #MOUSE_BTN_LEFT ; Left (only) button is pressed
-@L0: stx Buttons
-
-; Check left/right
-
- lda Temp ; Read joystick #0
- and #(JOY::LEFT | JOY::RIGHT)
- beq @SkipX ;
-
-; We will cheat here and rely on the fact that either the left, OR the right
-; bit can be active
-
- and #JOY::RIGHT ; Check RIGHT bit
- bne @Right
- lda #$FF
- tax
- bne @AddX ; Branch always
-@Right: lda #$01
- ldx #$00
-
-; Calculate the new X coordinate (--> a/y)
-
-@AddX: add XPos
- tay ; Remember low byte
- txa
- adc XPos+1
- tax
-
-; Limit the X coordinate to the bounding box
-
- cpy XMin
- sbc XMin+1
- bpl @L1
- ldy XMin
- ldx XMin+1
- jmp @L2
-@L1: txa
-
- cpy XMax
- sbc XMax+1
- bmi @L2
- ldy XMax
- ldx XMax+1
-@L2: sty XPos
- stx XPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jsr CMOVEX
-
-; Calculate the Y movement vector
-
-@SkipX: lda Temp ; Read joystick #0
- and #(JOY::UP | JOY::DOWN) ; Check up/down
- beq @SkipY ;
-
-; We will cheat here and rely on the fact that either the up, OR the down
-; bit can be active
-
- lsr a ; Check UP bit
- bcc @Down
- lda #$FF
- tax
- bne @AddY
-@Down: lda #$01
- ldx #$00
-
-; Calculate the new Y coordinate (--> a/y)
-
-@AddY: add YPos
- tay ; Remember low byte
- txa
- adc YPos+1
- tax
-
-; Limit the Y coordinate to the bounding box
-
- cpy YMin
- sbc YMin+1
- bpl @L3
- ldy YMin
- ldx YMin+1
- jmp @L4
-@L3: txa
-
- cpy YMax
- sbc YMax+1
- bmi @L4
- ldy YMax
- ldx YMax+1
-@L4: sty YPos
- stx YPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jsr CMOVEY
-
-; Done
-
-@SkipY: clc ; Interrupt not "handled"
- rts
-
+++ /dev/null
-;
-; Driver for a potentiometer "mouse" e.g. Koala Pad
-;
-; Ullrich von Bassewitz, 2004-03-29, 2009-09-26
-; Stefan Haubenthal, 2006-08-20
-;
-
- .include "zeropage.inc"
- .include "mouse-kernel.inc"
- .include "c128.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-HEADER:
-
-; Driver signature
-
- .byte $6d, $6f, $75 ; "mou"
- .byte MOUSE_API_VERSION ; Mouse driver API version number
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr HIDE
- .addr SHOW
- .addr SETBOX
- .addr GETBOX
- .addr MOVE
- .addr BUTTONS
- .addr POS
- .addr INFO
- .addr IOCTL
- .addr IRQ
-
-; Callback table, set by the kernel before INSTALL is called
-
-CHIDE: jmp $0000 ; Hide the cursor
-CSHOW: jmp $0000 ; Show the cursor
-CMOVEX: jmp $0000 ; Move the cursor to X coord
-CMOVEY: jmp $0000 ; Move the cursor to Y coord
-
-
-;----------------------------------------------------------------------------
-; Constants
-
-SCREEN_HEIGHT = 200
-SCREEN_WIDTH = 320
-
-.enum JOY
- UP = $01
- DOWN = $02
- LEFT = $04
- RIGHT = $08
- FIRE = $10
-.endenum
-
-;----------------------------------------------------------------------------
-; Global variables. The bounding box values are sorted so that they can be
-; written with the least effort in the SETBOX and GETBOX routines, so don't
-; reorder them.
-
-.bss
-
-Vars:
-YPos: .res 2 ; Current mouse position, Y
-XPos: .res 2 ; Current mouse position, X
-XMin: .res 2 ; X1 value of bounding box
-YMin: .res 2 ; Y1 value of bounding box
-XMax: .res 2 ; X2 value of bounding box
-YMax: .res 2 ; Y2 value of bounding box
-Buttons: .res 1 ; Button mask
-
-; Temporary value used in the int handler
-
-Temp: .res 1
-
-; Default values for above variables
-
-.rodata
-
-.proc DefVars
- .word SCREEN_HEIGHT/2 ; YPos
- .word SCREEN_WIDTH/2 ; XPos
- .word 0 ; XMin
- .word 0 ; YMin
- .word SCREEN_WIDTH ; XMax
- .word SCREEN_HEIGHT ; YMax
- .byte 0 ; Buttons
-.endproc
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an MOUSE_ERR_xx code in a/x.
-
-INSTALL:
-
-; Initialize variables. Just copy the default stuff over
-
- ldx #.sizeof(DefVars)-1
-@L1: lda DefVars,x
- sta Vars,x
- dex
- bpl @L1
-
-; Be sure the mouse cursor is invisible and at the default location. We
-; need to do that here, because our mouse interrupt handler doesn't set the
-; mouse position if it hasn't changed.
-
- sei
- jsr CHIDE
- lda XPos
- ldx XPos+1
- jsr CMOVEX
- lda YPos
- ldx YPos+1
- jsr CMOVEY
- cli
-
-; Done, return zero (= MOUSE_ERR_OK)
-
- ldx #$00
- txa
- rts
-
-;----------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-
-UNINSTALL = HIDE ; Hide cursor on exit
-
-;----------------------------------------------------------------------------
-; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently visible and should get hidden. For most drivers,
-; no special action is required besides hiding the mouse cursor.
-; No return code required.
-
-HIDE: sei
- jsr CHIDE
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently hidden and should become visible. For most drivers,
-; no special action is required besides enabling the mouse cursor.
-; No return code required.
-
-SHOW: sei
- jsr CSHOW
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SETBOX: Set the mouse bounding box. The parameters are passed as they come
-; from the C program, that is, a pointer to a mouse_box struct in a/x.
-; No checks are done if the mouse is currently inside the box, this is the job
-; of the caller. It is not necessary to validate the parameters, trust the
-; caller and save some code here. No return code required.
-
-SETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda (ptr1),y
- sta XMin,y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; GETBOX: Return the mouse bounding box. The parameters are passed as they
-; come from the C program, that is, a pointer to a mouse_box struct in a/x.
-
-GETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda XMin,y
- sta (ptr1),y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; MOVE: Move the mouse to a new position. The position is passed as it comes
-; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
-; remove the parameter from the stack on return.
-; No checks are done if the new position is valid (within the bounding box or
-; the screen). No return code required.
-;
-
-MOVE: sei ; No interrupts
-
- sta YPos
- stx YPos+1 ; New Y position
- jsr CMOVEY ; Set it
-
- ldy #$01
- lda (sp),y
- sta XPos+1
- tax
- dey
- lda (sp),y
- sta XPos ; New X position
-
- jsr CMOVEX ; Move the cursor
-
- cli ; Allow interrupts
- rts
-
-;----------------------------------------------------------------------------
-; BUTTONS: Return the button mask in a/x.
-
-BUTTONS:
- lda Buttons
- ldx #$00
- rts
-
-;----------------------------------------------------------------------------
-; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
-; No return code required.
-
-POS: ldy #MOUSE_POS::XCOORD ; Structure offset
-
- sei ; Disable interrupts
- lda XPos ; Transfer the position
- sta (ptr1),y
- lda XPos+1
- iny
- sta (ptr1),y
- lda YPos
- iny
- sta (ptr1),y
- lda YPos+1
- cli ; Enable interrupts
-
- iny
- sta (ptr1),y ; Store last byte
-
- rts ; Done
-
-;----------------------------------------------------------------------------
-; INFO: Returns mouse position and current button mask in the MOUSE_INFO
-; struct pointed to by ptr1. No return code required.
-;
-; We're cheating here to keep the code smaller: The first fields of the
-; mouse_info struct are identical to the mouse_pos struct, so we will just
-; call _mouse_pos to initialize the struct pointer and fill the position
-; fields.
-
-INFO: jsr POS
-
-; Fill in the button state
-
- lda Buttons
- ldy #MOUSE_INFO::BUTTONS
- sta (ptr1),y
-
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>MOUSE_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
-; (so be careful).
-;
-
-IRQ: lda #$7F
- sta CIA1_PRA
- lda CIA1_PRB ; Read port #1
- and #%00001100
- eor #%00001100 ; Make all bits active high
- asl
- sta Buttons
- lsr
- lsr
- lsr
- and #%00000001
- ora Buttons
- sta Buttons
- ldx #%01000000
- stx CIA1_PRA
- ldy #0
-: dey
- bne :-
- ldx SID_ADConv1
- stx XPos
- ldx SID_ADConv2
- stx YPos
-
- lda #$FF
- tax
- bne @AddX ; Branch always
- lda #$01
- ldx #$00
-
-; Calculate the new X coordinate (--> a/y)
-
-@AddX: add XPos
- tay ; Remember low byte
- txa
- adc XPos+1
- tax
-
-; Limit the X coordinate to the bounding box
-
- cpy XMin
- sbc XMin+1
- bpl @L1
- ldy XMin
- ldx XMin+1
- jmp @L2
-@L1: txa
-
- cpy XMax
- sbc XMax+1
- bmi @L2
- ldy XMax
- ldx XMax+1
-@L2: sty XPos
- stx XPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jsr CMOVEX
-
- lda #$FF
- tax
- bne @AddY
-@Down: lda #$01
- ldx #$00
-
-; Calculate the new Y coordinate (--> a/y)
-
-@AddY: add YPos
- tay ; Remember low byte
- txa
- adc YPos+1
- tax
-
-; Limit the Y coordinate to the bounding box
-
- cpy YMin
- sbc YMin+1
- bpl @L3
- ldy YMin
- ldx YMin+1
- jmp @L4
-@L3: txa
-
- cpy YMax
- sbc YMax+1
- bmi @L4
- ldy YMax
- ldx YMax+1
-@L4: sty YPos
- stx YPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jmp CMOVEY
+++ /dev/null
-;
-; PTV-4 Player joystick driver for the C128
-;
-; Ullrich von Bassewitz, 2003-09-28, using the C64 driver from
-; Groepaz/Hitmen, 2002-12-23, which is
-; obviously based on Ullrichs driver :)
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "c128.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
- .segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 4 ; Number of joysticks we support
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: tax ; Joystick number into X
- bne joy2
-
-; Read joystick 1
-
-joy1: lda #$7F
- sei
- sta CIA1_PRA
- lda CIA1_PRB
- cli
- and #$1F
- eor #$1F
- rts
-
-; Read joystick 2
-
-joy2: dex
- bne joy3
-
- lda #$E0
- ldy #$FF
- sei
- sta CIA1_DDRA
- lda CIA1_PRA
- sty CIA1_DDRA
- cli
- and #$1F
- eor #$1F
- rts
-
-; Read joystick 3
-
-joy3:
- lda #%10000000 ; cia 2 port B Data-Direction
- sta CIA2_DDRB ; bit 7: out bit 6-0: in
-
- dex
- bne joy4
-
- lda #$80 ; cia 2 port B read/write
- sta CIA2_PRB ; (output one at PB7)
-
- lda CIA2_PRB ; cia 2 port B read/write
- and #$1f ; get bit 4-0 (PB4-PB0)
- eor #$1f
- rts
-
-; Read joystick 4
-
-joy4:
- lda #$00 ; cia 2 port B read/write
- sta CIA2_PRB ; (output zero at PB7)
-
- lda CIA2_PRB ; cia 2 port B read/write
- and #$0f ; get bit 3-0 (PB3-PB0)
- sta tmp1 ; joy 4 directions
-
- lda CIA2_PRB ; cia 2 port B read/write
- and #%00100000 ; get bit 5 (PB5)
- lsr
- ora tmp1
- eor #$1f
-
- ldx #0
- rts
+++ /dev/null
-;
-; Extended memory driver for the C128 RAM in bank #1. Driver works without
-; problems when statically linked.
-;
-; Ullrich von Bassewitz, 2002-12-04
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
- .include "c128.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-BASE = $400
-TOPMEM = $FF00
-PAGES = (TOPMEM - BASE) / 256
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-curpage: .res 1 ; Current page number
-
-window: .res 256 ; Memory "window"
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx #$FF
- stx curpage
- stx curpage+1 ; Invalidate the current page
- inx
- txa ; A = X = EM_ERR_OK
- rts
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda #<PAGES
- ldx #>PAGES
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage
- stx curpage+1 ; Remember the new page
-
- clc
- adc #>BASE
- sta ptr1+1
- ldy #$00
- sty ptr1
-
- lda #<ptr1
- sta FETVEC
-
-; Transfer one page
-
-@L1: ldx #MMU_CFG_RAM1
- jsr FETCH
- sta window,y
- iny
- bne @L1
-
-; Return the memory window
-
- lda #<window
- ldx #>window ; Return the window address
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage
- stx curpage+1 ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage ; Get the current page
- ldx curpage+1
- bmi done ; Jump if no page mapped
-
- clc
- adc #>BASE
- sta ptr1+1
- ldy #$00
- sty ptr1
-
- lda #<ptr1
- sta STAVEC
-
-; Transfer one page. Y must be zero on entry
-
-@L1: lda window,y
- ldx #MMU_CFG_RAM1
- jsr STASH
- iny
- bne @L1
-
-; Done
-
-done: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- clc
- adc #>BASE
- sta ptr1+1 ; From
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; To
-
- lda #<ptr1
- sta FETVEC
-
- ldy #EM_COPY::COUNT+1
- lda (ptr3),y ; Get number of pages
- beq @L2 ; Skip if no full pages
- sta tmp1
-
-; Copy full pages
-
- ldy #$00
-@L1: ldx #MMU_CFG_RAM1
- jsr FETCH
- sta (ptr2),y
- iny
- bne @L1
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- sta tmp1
-
- ldy #$00
-@L3: ldx #MMU_CFG_RAM1
- jsr FETCH
- sta (ptr2),y
- iny
- dec tmp1
- bne @L3
-
-; Done
-
-@L4: rts
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO: sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- clc
- adc #>BASE
- sta ptr1+1 ; To
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; From
-
- lda #<ptr1
- sta STAVEC
-
- ldy #EM_COPY::COUNT+1
- lda (ptr3),y ; Get number of pages
- beq @L2 ; Skip if no full pages
- sta tmp1
-
-; Copy full pages
-
- ldy #$00
-@L1: lda (ptr2),y
- ldx #MMU_CFG_RAM1
- jsr STASH
- iny
- bne @L1
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- sta tmp1
-
- ldy #$00
-@L3: lda (ptr2),y
- ldx #MMU_CFG_RAM1
- jsr STASH
- iny
- dec tmp1
- bne @L3
-
-; Done
-
-@L4: rts
-
+++ /dev/null
-;
-; Extended memory driver for the C128 RAM in banks #1, #2 and #3. Driver works without
-; problems when statically linked.
-;
-; Ullrich von Bassewitz, 2002-12-04
-;
-; Updated to use banks 2 and 3 as well by
-; Marco van den Heuvel, 2010-01-21
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
- .include "c128.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-BASE = $400
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-curpage: .res 2 ; Current page number
-curbank: .res 1 ; Current bank number
-copybank: .res 2 ; temp bank number
-
-window: .res 256 ; Memory "window"
-
-pagecount: .res 2 ; Number of available pages
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx #0
- stx ptr1
- ldx #4
- stx ptr1+1
- ldx #<ptr1
- stx FETVEC
- stx STAVEC
- ldy #0
- ldx #MMU_CFG_RAM1
- jsr FETCH
- sta tmp1
- ldx #MMU_CFG_RAM3
- jsr FETCH
- cmp tmp1
- bne @has_4_banks
- tax
- inx
- txa
- ldx #MMU_CFG_RAM1
- jsr STASH
- ldx #MMU_CFG_RAM3
- jsr FETCH
- cmp tmp1
- beq @has_4_banks
- ldx #0
- lda #251
- bne @setok
-
-@has_4_banks:
- ldx #2
- lda #241
-@setok:
- sta pagecount
- stx pagecount+1
- ldx #$FF
- stx curpage
- stx curpage+1 ; Invalidate the current page
- inx
- txa ; A = X = EM_ERR_OK
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sei
- sta curpage
- stx curpage+1 ; Remember the new page
-
- jsr calculate_bank_and_correct_page
- stx curbank
-
- clc
- adc #>BASE
- sta ptr1+1
- ldy #$00
- sty ptr1
- lda #<ptr1
- sta FETVEC
-
-; Transfer one page
-
-@L1: ldx curbank
- jsr getcurbankmmu
- jsr FETCH
- sta window,y
- iny
- bne @L1
-
-; Return the memory window
-
- lda #<window
- ldx #>window ; Return the window address
- cli
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage
- stx curpage+1 ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: sei
- lda curpage ; Get the current page
- ldx curpage+1
- bmi done ; Jump if no page mapped
-
- jsr calculate_bank_and_correct_page
- stx curbank
-
- clc
- adc #>BASE
- sta ptr1+1
- ldy #$00
- sty ptr1
-
- lda #<ptr1
- sta STAVEC
-
-; Transfer one page. Y must be zero on entry
-
-@L1: lda window,y
- ldx curbank
- jsr getcurbankmmu
- jsr STASH
- iny
- bne @L1
- cli
-
-; Done
-
-done: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- sei
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - ptr4 contains the page buffer and offset
-; - tmp1 contains the bank
-; - tmp2 contains zero (used for linear memory buffer offset)
-
- lda #<ptr4
- sta FETVEC
- jmp @L3
-
-@L1: ldx tmp1
- jsr getcurbankmmu
- ldy #0
- jsr FETCH
- ldy tmp2
- sta (ptr2),y
- inc tmp2
- bne @L2
- inc ptr2+1
-@L2: inc ptr4
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- cli
- rts
-
-; Bump page register
-
-@L4: inc ptr4+1
- lda ptr4+1
- cmp #$ff
- bne @L3
- lda #4
- sta ptr4+1
- inc tmp1
-@L5:
- jmp @L3
-
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- sei
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - ptr4 contains the page buffer and offset
-; - tmp1 contains the bank
-; - tmp2 contains zero (used for linear memory buffer offset)
-
- lda #<ptr4
- sta STAVEC
- jmp @L3
-
-@L1:
- ldy tmp2
- lda (ptr2),y
- ldx tmp1
- jsr getcurbankmmu
- ldy #0
- jsr STASH
- inc tmp2
- bne @L2
- inc ptr2+1
-@L2: inc ptr4
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- cli
- rts
-
-; Bump page register
-
-@L4: inc ptr4+1
- lda ptr4+1
- cmp #$ff
- bne @L3
- inc tmp1
- lda #4
- sta ptr4+1
-@L5:
- jmp @L3
-
-; ------------------------------------------------------------------------
-; Helper function to calculate the correct bank and page
-; when addressing bank 2 or 3
-
-calculate_bank_and_correct_page:
- cpx #2
- beq @calculate_bank_3_with_2
- cpx #1
- beq @calculate_bank_2_or_3_with_1
- sec
- sbc #251
- bcs @calculate_bank_2_with_0
- ldx #1
- lda curpage
- rts
-
-@calculate_bank_3_with_2:
- lda curpage
- clc
- adc #10
-@calculate_bank_3_with_1:
- ldx #3
- rts
-
-@calculate_bank_2_or_3_with_1:
- sec
- sbc #246
- bcs @calculate_bank_3_with_1
- lda curpage
- clc
- adc #5
-@calculate_bank_2_with_0:
- ldx #2
- rts
-
-; ------------------------------------------------------------------------
-; Helper function to get the correct mmu value in x
-
-getcurbankmmu:
- cpx #1
- beq @bank1
- cpx #2
- beq @bank2
- ldx #MMU_CFG_RAM3
- rts
-@bank2:
- ldx #MMU_CFG_RAM2
- rts
-@bank1:
- ldx #MMU_CFG_RAM1
- rts
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-
-setup: sta ptr1
- stx ptr1+1 ; Save passed pointer
-
-; Get the page number from the struct and adjust it so that it may be used
-; with the hardware. That is: page pointer in ptr4 and bank in tmp1
-
- ldy #EM_COPY::PAGE+1
- lda (ptr1),y
- tax
- dey
- lda (ptr1),y
- sta curpage
- jsr calculate_bank_and_correct_page
- clc
- adc #4
- sta ptr4+1
- stx tmp1
-
-; Get the buffer pointer into ptr2
-
- ldy #EM_COPY::BUF
- lda (ptr1),y
- sta ptr2
- iny
- lda (ptr1),y
- sta ptr2+1
-
-; Get the count, calculate -(count-1) and store it into ptr3
-
- ldy #EM_COPY::COUNT
- lda (ptr1),y
- eor #$FF
- sta ptr3
- iny
- lda (ptr1),y
- eor #$FF
- sta ptr3+1
-
-; Get the page offset into the low byte of ptr4 clear tmp2
-
- ldy #EM_COPY::OFFS
- lda (ptr1),y
- sta ptr4
- lda #0
- sta tmp2
-
-; Done
-
- rts
+++ /dev/null
-;
-; Extended memory driver for the RamCart 64/128KB cartridge. Driver works
-; without problems when statically linked.
-; Code is based on GEORAM code by Ullrich von Bassewitz.
-; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
-; 06,22.12.2002
-;
-
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-RAMC_WINDOW = $DF00 ; Address of RamCart window
-RAMC_PAGE_LO = $DE00 ; Page register low
-RAMC_PAGE_HI = $DE01 ; Page register high (only for RC128)
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-
-pagecount: .res 2 ; Number of pages available
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx RAMC_WINDOW
- cpx RAMC_WINDOW
- bne @notpresent
-
- lda #0
- sta RAMC_PAGE_LO
- sta RAMC_PAGE_HI
- ldx RAMC_WINDOW
- cpx RAMC_WINDOW
- bne @notpresent
- lda #2
- sta RAMC_WINDOW
- cmp RAMC_WINDOW
- beq @cont
- cpx RAMC_WINDOW
- beq @readonly
-@cont: ldy #1
- sty RAMC_PAGE_HI
- sty RAMC_WINDOW
- dey
- sty RAMC_PAGE_HI
- iny
- cpy RAMC_WINDOW
- beq @rc64
- ; we're on rc128
- ldx #>512
- bne @setsize
-@rc64: ldx #>256
-@setsize:
- lda #0
- sta pagecount
- stx pagecount+1
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
- rts
-@notpresent:
-@readonly:
- lda #<EM_ERR_NO_DEVICE
- ldx #>EM_ERR_NO_DEVICE
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-; The RamCart cartridge does not copy but actually map the window, so USE is
-; identical to MAP.
-
-USE = MAP
-
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta RAMC_PAGE_LO
- stx RAMC_PAGE_HI
- lda #<RAMC_WINDOW
- ldx #>RAMC_WINDOW
-
-; Use the RTS from COMMIT below to save a precious byte of storage
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - tmp2 contains the high page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1: lda RAMC_WINDOW,x
- sta (ptr2),y
- iny
- bne @L2
- inc ptr2+1
-@L2: inx
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4: inc tmp1
- bne @L5
- inc tmp2
-@L5: lda tmp1
- sta RAMC_PAGE_LO
- lda tmp2
- sta RAMC_PAGE_HI
- jmp @L3
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - tmp2 contains the high page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1: lda (ptr2),y
- sta RAMC_WINDOW,x
- iny
- bne @L2
- inc ptr2+1
-@L2: inx
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4: inc tmp1
- bne @L5
- inc tmp2
-@L5: lda tmp1
- sta RAMC_PAGE_LO
- lda tmp2
- sta RAMC_PAGE_HI
- jmp @L3
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-
-setup: sta ptr1
- stx ptr1+1 ; Save passed pointer
-
-; Get the page number from the struct and adjust it so that it may be used
-; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
-
- ldy #EM_COPY::PAGE+1
- lda (ptr1),y
- sta tmp2
- dey
- lda (ptr1),y
- sta tmp1
-
-; Get the buffer pointer into ptr2
-
- ldy #EM_COPY::BUF
- lda (ptr1),y
- sta ptr2
- iny
- lda (ptr1),y
- sta ptr2+1
-
-; Get the count, calculate -(count-1) and store it into ptr3
-
- ldy #EM_COPY::COUNT
- lda (ptr1),y
- eor #$FF
- sta ptr3
- iny
- lda (ptr1),y
- eor #$FF
- sta ptr3+1
-
-; Get the page offset into X and clear Y
-
- ldy #EM_COPY::OFFS
- lda (ptr1),y
- tax
- ldy #$00
-
-; Done
-
- rts
-
+++ /dev/null
-;
-; Extended memory driver for the Commodore REU. Driver works without
-; problems when statically linked.
-;
-; Ullrich von Bassewitz, 2002-11-29
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
- .include "c128.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-REU_STATUS = $DF00 ; Status register
-REU_COMMAND = $DF01 ; Command register
-REU_C64ADDR = $DF02 ; C64 base address register
-REU_REUADDR = $DF04 ; REU base address register
-REU_COUNT = $DF07 ; Transfer count register
-REU_IRQMASK = $DF09 ; IRQ mask register
-REU_CONTROL = $DF0A ; Control register
-REU_TRIGGER = $FF00 ; REU command trigger
-
-OP_COPYFROM = $ED
-OP_COPYTO = $EC
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-pagecount: .res 2 ; Number of pages available
-curpage: .res 2 ; Current page number
-
-window: .res 256 ; Memory "window"
-
-reu_params: .word $0000 ; Host address, lo, hi
- .word $0000 ; Exp address, lo, hi
- .byte $00 ; Expansion bank no.
- .word $0000 ; # bytes to move, lo, hi
- .byte $00 ; Interrupt mask reg.
- .byte $00 ; Adress control reg.
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx #$00 ; High byte of return code
- lda #$55
- sta REU_REUADDR
- cmp REU_REUADDR ; Check for presence of REU
- bne nodevice
- asl a ; A = $AA
- sta REU_REUADDR
- cmp REU_REUADDR ; Check for presence of REU
- bne nodevice
-
- ldy #>(128*4) ; Assume 128KB
- lda REU_STATUS
- and #$10 ; Check size bit
- beq @L1
- ldy #>(256*4) ; 256KB when size bit is set
-@L1: sty pagecount+1
-
- ldy #$FF
- sty curpage
- sty curpage+1 ; Invalidate the current page
- txa ; X = A = EM_ERR_OK
- rts
-
-; No REU found
-
-nodevice:
- lda #EM_ERR_NO_DEVICE
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage
- stx curpage+1 ; Remember the new page
-
- ldy #OP_COPYFROM
- jsr common ; Copy the window
-
- lda #<window
- ldx #>window ; Return the window address
-done: rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage
- stx curpage+1 ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage
- ldx curpage+1 ; Do we have a page mapped?
- bmi done ; Jump if no page mapped
-
- ldy #OP_COPYTO
-common: sty tmp1
-
- ldy #<window
- sty REU_C64ADDR
- ldy #>window
- sty REU_C64ADDR+1
-
- ldy #0
- sty REU_REUADDR+0
- sta REU_REUADDR+1
- stx REU_REUADDR+2
-
- sty REU_COUNT+0
- ldy #1
- sty REU_COUNT+1 ; Move 256 bytes
- bne transfer1 ; Transfer 256 bytes into REU
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- ldy #OP_COPYFROM
- .byte $2C
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- ldy #OP_COPYTO
- sty tmp1
-
-; Remember the passed pointer
-
- sta ptr1
- stx ptr1+1 ; Save the pointer
-
-; The structure passed to the functions has the same layout as the registers
-; of the Commodore REU, so register programming is easy.
-
- ldy #7-1
-@L1: lda (ptr1),y
- sta REU_C64ADDR,y
- dey
- bpl @L1
-
-; Invalidate the page in the memory window
-
- sty curpage+1 ; Y = $FF
-
-; Reload the REU command and start the transfer
-
-transfer1:
- ldy tmp1
-
-; Transfer subroutine for the REU. Expects command in Y.
-
-transfer:
- sty REU_COMMAND ; Issue command
-
- ldy MMU_CR ; Save the current MMU settings
- lda #MMU_CFG_RAM0 ;
- sei ;
- sta MMU_CR ; Enable RAM in bank #0
- lda REU_TRIGGER ; Don't change $FF00
- sta REU_TRIGGER ; Start the transfer...
-
- sty MMU_CR ; Restore the old configuration
- cli
- rts
-
+++ /dev/null
-;
-; Standard joystick driver for the C128. May be used multiple times when linked
-; to the statically application.
-
-;
-; Ullrich von Bassewitz, 2002-12-21
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "c128.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry not used
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: tax ; Joystick number into X
- bne joy2
-
-; Read joystick 1
-
-joy1: lda #$7F
- sei
- sta CIA1_PRA
- lda CIA1_PRB
- cli
- and #$1F
- eor #$1F
- rts
-
-; Read joystick 2
-
-joy2: ldx #0
- lda #$E0
- ldy #$FF
- sei
- sta CIA1_DDRA
- lda CIA1_PRA
- sty CIA1_DDRA
- cli
- and #$1F
- eor #$1F
- rts
-
-
+++ /dev/null
-;
-; Serial driver for the C128 using a Swiftlink or Turbo-232 cartridge.
-;
-; Ullrich von Bassewitz, 2003-04-18
-;
-; The driver is based on the cc65 rs232 module, which in turn is based on
-; Craig Bruce device driver for the Switftlink/Turbo-232.
-;
-; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
-;
-; This software is Public Domain. It is in Buddy assembler format.
-;
-; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
-; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
-; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
-; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
-;
-; The code assumes that the kernal + I/O are in context. On the C128, call
-; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
-; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
-; interrupt handling assumes that the 65816 is in 6502-emulation mode.
-;
-
- .include "zeropage.inc"
- .include "ser-kernel.inc"
- .include "ser-error.inc"
- .include "c128.inc"
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $73, $65, $72 ; "ser"
- .byte SER_API_VERSION ; Serial API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word OPEN
- .word CLOSE
- .word GET
- .word PUT
- .word STATUS
- .word IOCTL
- .word IRQ
-
-;----------------------------------------------------------------------------
-; I/O definitions
-
-ACIA = $DE00
-ACIA_DATA = ACIA+0 ; Data register
-ACIA_STATUS = ACIA+1 ; Status register
-ACIA_CMD = ACIA+2 ; Command register
-ACIA_CTRL = ACIA+3 ; Control register
-
-;----------------------------------------------------------------------------
-;
-; Global variables
-;
-
-; We reuse the RS232 zero page variables for the driver, since the ROM
-; routines cannot be used together with this driver (may also use $A0F
-; and following in case of problems).
-RecvHead := $A7 ; Head of receive buffer
-RecvTail := $A8 ; Tail of receive buffer
-RecvFreeCnt := $A9 ; Number of bytes in receive buffer
-SendHead := $AA ; Head of send buffer
-SendTail := $AB ; Tail of send buffer
-SendFreeCnt := $B4 ; Number of bytes free in send buffer
-Stopped := $B5 ; Flow-stopped flag
-RtsOff := $B6 ;
-
-; Send and receive buffers: 256 bytes each
-RecvBuf := $0C00 ; Use the ROM buffers
-SendBuf := $0D00
-
-.rodata
-
-; Tables used to translate RS232 params into register values
-
-BaudTable: ; bit7 = 1 means setting is invalid
- .byte $FF ; SER_BAUD_45_5
- .byte $FF ; SER_BAUD_50
- .byte $FF ; SER_BAUD_75
- .byte $FF ; SER_BAUD_110
- .byte $FF ; SER_BAUD_134_5
- .byte $02 ; SER_BAUD_150
- .byte $05 ; SER_BAUD_300
- .byte $06 ; SER_BAUD_600
- .byte $07 ; SER_BAUD_1200
- .byte $FF ; SER_BAUD_1800
- .byte $08 ; SER_BAUD_2400
- .byte $09 ; SER_BAUD_3600
- .byte $0A ; SER_BAUD_4800
- .byte $0B ; SER_BAUD_7200
- .byte $0C ; SER_BAUD_9600
- .byte $0E ; SER_BAUD_19200
- .byte $0F ; SER_BAUD_38400
- .byte $FF ; SER_BAUD_57600
- .byte $FF ; SER_BAUD_115200
- .byte $FF ; SER_BAUD_230400
-
-BitTable:
- .byte $60 ; SER_BITS_5
- .byte $40 ; SER_BITS_6
- .byte $20 ; SER_BITS_7
- .byte $00 ; SER_BITS_8
-
-StopTable:
- .byte $00 ; SER_STOP_1
- .byte $80 ; SER_STOP_2
-
-ParityTable:
- .byte $00 ; SER_PAR_NONE
- .byte $20 ; SER_PAR_ODD
- .byte $60 ; SER_PAR_EVEN
- .byte $A0 ; SER_PAR_MARK
- .byte $E0 ; SER_PAR_SPACE
-
-.code
-
-;----------------------------------------------------------------------------
-; Interrupt stub that is copied into low RAM. The startup code uses a special
-; memory configuration with just kernal and I/O enabled (anything else is RAM).
-; The NMI handler in ROM will switch back to a configuration where just the
-; low 16K RAM are accessible. So we have to copy a smal piece of code into
-; low RAM that enables the cc65 configuration and then jumps to the real NMI
-; handler.
-
-NmiStubOrig := *
-
-.org $1150 ; BASIC graphics area
-.proc NmiStub
-
- lda #MMU_CFG_CC65 ; Bank 0 with kernal ROM...
- sta MMU_CR ; ...enable
- jsr NmiHandler ; Call the actual NMI handler
- lda #$00 ; Get ROM config...
- sta MMU_CR ; ...and enable it
-Vector := *+1
- .byte $4C ; Jump to the saved IRQ vector
-
-.endproc
-.reloc
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an SER_ERR_xx code in a/x.
-
-INSTALL:
-
-; Deactivate DTR and disable 6551 interrupts
-
- lda #%00001010
- sta ACIA_CMD
-
-; Copy the NMI stub into low memory
-
- ldy #.sizeof (NmiStub)-1
-@L1: lda NmiStubOrig,y
- sta NmiStub,y
- dey
- bpl @L1
-
-; Set up the nmi vector
-
- lda NMIVec
- ldy NMIVec+1
- sta NmiStub::Vector+0
- sty NmiStub::Vector+1
- lda #<NmiStub
- ldy #>NmiStub
-SetNMI: sta NMIVec
- sty NMIVec+1
-
-; Done, return an error code
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-;----------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Must return an SER_ERR_xx code in a/x.
-
-UNINSTALL:
-
-; Stop interrupts, drop DTR
-
- lda #%00001010
- sta ACIA_CMD
-
-; Restore NMI vector and return OK
-
- lda NmiStub::Vector+0
- ldy NmiStub::Vector+1
- jmp SetNMI
-
-;----------------------------------------------------------------------------
-; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-OPEN:
-
-; Check if the handshake setting is valid
-
- ldy #SER_PARAMS::HANDSHAKE ; Handshake
- lda (ptr1),y
- cmp #SER_HS_HW ; This is all we support
- bne InvParam
-
-; Initialize buffers
-
- jsr InitBuffers
-
-; Set the value for the control register, which contains stop bits, word
-; length and the baud rate.
-
- ldy #SER_PARAMS::BAUDRATE
- lda (ptr1),y ; Baudrate index
- tay
- lda BaudTable,y ; Get 6551 value
- bmi InvBaud ; Branch if rate not supported
- sta tmp1
-
- ldy #SER_PARAMS::DATABITS ; Databits
- lda (ptr1),y
- tay
- lda BitTable,y
- ora tmp1
- sta tmp1
-
- ldy #SER_PARAMS::STOPBITS ; Stopbits
- lda (ptr1),y
- tay
- lda StopTable,y
- ora tmp1
- ora #%00010000 ; Receiver clock source = baudrate
- sta ACIA_CTRL
-
-; Set the value for the command register. We remember the base value in
-; RtsOff, since we will have to manipulate ACIA_CMD often.
-
- ldy #SER_PARAMS::PARITY ; Parity
- lda (ptr1),y
- tay
- lda ParityTable,y
- ora #%00000001 ; DTR active
- sta RtsOff
- ora #%00001000 ; Enable receive interrupts
- sta ACIA_CMD
-
-; Done
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-; Invalid parameter
-
-InvParam:
- lda #<SER_ERR_INIT_FAILED
- ldx #>SER_ERR_INIT_FAILED
- rts
-
-; Baud rate not available
-
-InvBaud:
- lda #<SER_ERR_BAUD_UNAVAIL
- ldx #>SER_ERR_BAUD_UNAVAIL
- rts
-
-;----------------------------------------------------------------------------
-; CLOSE: Close the port, disable interrupts and flush the buffer. Called
-; without parameters. Must return an error code in a/x.
-;
-
-CLOSE:
-
-; Stop interrupts, drop DTR
-
- lda #%00001010
- sta ACIA_CMD
-
-; Initalize buffers. Returns zero in a
-
- jsr InitBuffers
-
-; Return OK
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-;----------------------------------------------------------------------------
-; GET: Will fetch a character from the receive buffer and store it into the
-; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
-; return.
-;
-
-GET: ldx SendFreeCnt ; Send data if necessary
- inx ; X == $FF?
- beq @L1
- lda #$00
- jsr TryToSend
-
-; Check for buffer empty
-
-@L1: lda RecvFreeCnt ; (25)
- cmp #$ff
- bne @L2
- lda #<SER_ERR_NO_DATA
- ldx #>SER_ERR_NO_DATA
- rts
-
-; Check for flow stopped & enough free: release flow control
-
-@L2: ldx Stopped ; (34)
- beq @L3
- cmp #63
- bcc @L3
- lda #$00
- sta Stopped
- lda RtsOff
- ora #%00001000
- sta ACIA_CMD
-
-; Get byte from buffer
-
-@L3: ldx RecvHead ; (41)
- lda RecvBuf,x
- inc RecvHead
- inc RecvFreeCnt
- ldx #$00 ; (59)
- sta (ptr1,x)
- txa ; Return code = 0
- rts
-
-;----------------------------------------------------------------------------
-; PUT: Output character in A.
-; Must return an error code in a/x.
-;
-
-PUT:
-
-; Try to send
-
- ldx SendFreeCnt
- inx ; X = $ff?
- beq @L2
- pha
- lda #$00
- jsr TryToSend
- pla
-
-; Put byte into send buffer & send
-
-@L2: ldx SendFreeCnt
- bne @L3
- lda #<SER_ERR_OVERFLOW ; X is already zero
- rts
-
-@L3: ldx SendTail
- sta SendBuf,x
- inc SendTail
- dec SendFreeCnt
- lda #$ff
- jsr TryToSend
- lda #<SER_ERR_OK
- tax
- rts
-
-;----------------------------------------------------------------------------
-; STATUS: Return the status in the variable pointed to by ptr1.
-; Must return an error code in a/x.
-;
-
-STATUS: lda ACIA_STATUS
- ldx #0
- sta (ptr1,x)
- txa ; SER_ERR_OK
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>SER_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Not used on the C128
-;
-
-IRQ = $0000
-
-;----------------------------------------------------------------------------
-;
-; NMI handler
-; C128 NMI overhead=76 cycles: int=7, maxLatency=6, ROMenter=33, ROMexit=30
-; C64 NMI overhead=76 cycles: int=7, maxLatency=6, ROMenter=34, ROMexit=29
-;
-; timing: normal=76+43+9=128 cycles, assertFlow=76+52+9=137 cycles
-;
-; C128 @ 115.2k: 177 cycles avail (fast)
-; C64 @ 57.6k: 177 cycles avail, worstAvail=177-43? = 134
-; SCPU @ 230.4k: 868 cycles avail: for a joke!
-;
-; Note: Because of the C128 banking, a small stub has to go into low memory,
-; since the ROM NMI entry point switches to a configuration, where only the
-; low 16K of RAM are visible. The entry code switches into the standard cc65
-; configuration (I/O + 16K kernal) and then jumps here. Registers are already
-; saved by the ROM code.
-
-NmiHandler:
- lda ACIA_STATUS ;(4) ;status ;check for byte received
- and #$08 ;(2)
- beq @L9 ;(2*)
- cld
- lda ACIA_DATA ;(4) data ;get byte and put into receive buffer
- ldy RecvTail ;(4)
- ldx RecvFreeCnt ;(4)
- beq @L9 ;(2*) Jump if no space in receive buffer
- sta RecvBuf,y ;(5)
- inc RecvTail ;(6)
- dec RecvFreeCnt ;(6)
- cpx #33 ;(2) check for buffer space low
- bcc @L2 ;(2*)
- rts
-
-; Assert flow control
-
-@L2: lda RtsOff ;(3) assert flow control if buffer space too low
- sta ACIA_CMD ;(4) command
- sta Stopped ;(3)
-@L9: rts
-
-;----------------------------------------------------------------------------
-; Try to send a byte. Internal routine. A = TryHard
-
-.proc TryToSend
-
- sta tmp1 ; Remember tryHard flag
-@L0: lda SendFreeCnt
- cmp #$ff
- beq @L3 ; Bail out
-
-; Check for flow stopped
-
-@L1: lda Stopped
- bne @L3 ; Bail out
-
-; Check that swiftlink is ready to send
-
-@L2: lda ACIA_STATUS
- and #$10
- bne @L4
- bit tmp1 ;keep trying if must try hard
- bmi @L0
-@L3: rts
-
-; Send byte and try again
-
-@L4: ldx SendHead
- lda SendBuf,x
- sta ACIA_DATA
- inc SendHead
- inc SendFreeCnt
- jmp @L0
-
-.endproc
-
-
-;----------------------------------------------------------------------------
-; Initialize buffers
-
-InitBuffers:
- ldx #0
- stx Stopped
- stx RecvHead
- stx RecvTail
- stx SendHead
- stx SendTail
- dex ; X = 255
- stx RecvFreeCnt
- stx SendFreeCnt
- rts
-
-
+++ /dev/null
-;
-; Extended memory driver for the VDC RAM available on all C128 machines
-; (based on code by Ullrich von Bassewitz)
-; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
-; 06,20.12.2002
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word DEINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-VDC_ADDR_REG = $D600 ; VDC address
-VDC_DATA_REG = $D601 ; VDC data
-
-VDC_DATA_HI = 18 ; used registers
-VDC_DATA_LO = 19
-VDC_CSET = 28
-VDC_DATA = 31
-
-; ------------------------------------------------------------------------
-; Data.
-
-.data
-
-pagecount: .word 64 ; $0000-$3fff as 16k default
-curpage: .word $ffff ; currently mapped-in page (invalid)
-
-.bss
-
-window: .res 256 ; memory window
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ; do test for VDC presence here???
-
- ldx #VDC_CSET ; determine size of RAM...
- jsr vdcgetreg
- sta tmp1
- ora #%00010000
- jsr vdcputreg ; turn on 64k
-
- jsr settestadr1 ; save original value of test byte
- jsr vdcgetbyte
- sta tmp2
-
- lda #$55 ; write $55 here
- ldy #ptr1
- jsr test64k ; read it here and there
- lda #$aa ; write $aa here
- ldy #ptr2
- jsr test64k ; read it here and there
-
- jsr settestadr1
- lda tmp2
- jsr vdcputbyte ; restore original value of test byte
-
- lda ptr1 ; do bytes match?
- cmp ptr1+1
- bne @have64k
- lda ptr2
- cmp ptr2+1
- bne @have64k
-
- ldx #VDC_CSET
- lda tmp1
- jsr vdcputreg ; restore 16/64k flag
- jmp @endok ; and leave default values for 16k
-
-@have64k:
- lda #<256
- ldx #>256
- sta pagecount
- stx pagecount+1
-@endok:
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
- rts
-
-test64k:
- sta tmp1
- sty ptr3
- lda #0
- sta ptr3+1
- jsr settestadr1
- lda tmp1
- jsr vdcputbyte ; write $55
- jsr settestadr1
- jsr vdcgetbyte ; read here
- pha
- jsr settestadr2
- jsr vdcgetbyte ; and there
- ldy #1
- sta (ptr3),y
- pla
- dey
- sta (ptr3),y
- rts
-
-settestadr1:
- ldy #$02 ; test page 2 (here)
- .byte $2c
-settestadr2:
- ldy #$42 ; or page 64+2 (there)
- lda #0
- jmp vdcsetsrcaddr
-
-; ------------------------------------------------------------------------
-; DEINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-DEINSTALL:
- ;on C128 restore font and clear the screen?
- rts
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage
- stx curpage+1
- sta ptr1+1
- ldy #0
- sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
- jsr transferin
-
- lda #<window
- ldx #>window
- rts
-
-; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
-
-transferin:
- lda ptr1
- ldy ptr1+1
- jsr vdcsetsrcaddr ; set source address in VDC
- ldy #0
- ldx #VDC_DATA
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda VDC_DATA_REG ; get 2 bytes at a time to speed-up
- sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config)
- iny
- lda VDC_DATA_REG
- sta (ptr2),y
- iny
- bne @L0
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage
- stx curpage+1 ; Remember the page
- lda #<window
- ldx #>window ; Return the window
-done: rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT:
- lda curpage ; jump if no page mapped
- ldx curpage+1
- bmi done
- sta ptr1+1
- ldy #0
- sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
-; fall through to transferout
-
-; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
-
-transferout:
- lda ptr1
- ldy ptr1+1
- jsr vdcsetsrcaddr ; set source address in VDC
- ldy #0
- ldx #VDC_DATA
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda (ptr2),y ; speedup does not work for writing
- sta VDC_DATA_REG
- iny
- bne @L0
- rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
- beq @L2 ; Skip if no full pages
-
-; Copy full pages
-
-@L1: jsr transferin
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- sta tmp1
-
-; Transfer the bytes in the last page
-
- ldy #0
-@L3: jsr vdcgetbyte
- sta (ptr2),y
- iny
- dec tmp1
- lda tmp1
- bne @L3
-@L4: rts
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- jsr setup
- beq @L2 ; Skip if no full pages
-
-; Copy full pages
-
-@L1: jsr transferout
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- sta tmp1
-
-; Transfer the bytes in the last page
-
- ldy #0
-@L3: lda (ptr2),y
- jsr vdcputbyte
- iny
- dec tmp1
- lda tmp1
- bne @L3
-@L4: rts
-
-;-------------------------------------------------------------------------
-; Helper functions to handle VDC ram
-;
-
-vdcsetsrcaddr:
- ldx #VDC_DATA_LO
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- sta VDC_DATA_REG
- dex
- tya
- stx VDC_ADDR_REG
- sta VDC_DATA_REG
- rts
-
-vdcgetbyte:
- ldx #VDC_DATA
-vdcgetreg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda VDC_DATA_REG
- rts
-
-vdcputbyte:
- ldx #VDC_DATA
-vdcputreg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- sta VDC_DATA_REG
- rts
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-;
-
-setup:
- sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- sta ptr1+1 ; From
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; To
-
- ldy #EM_COPY::COUNT+1
- lda (ptr3),y ; Get number of pages
- sta tmp1
- rts
-
--- /dev/null
+;
+; Extended memory driver for the GEORAM cartridge. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2002-11-29
+;
+; GEORAM page size checking routine by
+; Marco van den Heuvel, 2010-01-21
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+GR_WINDOW = $DE00 ; Address of GEORAM window
+GR_PAGE_LO = $DFFE ; Page register low
+GR_PAGE_HI = $DFFF ; Page register high
+
+; ------------------------------------------------------------------------
+; Data.
+
+.data
+
+pagecount: .res 2 ; Number of available pages
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx GR_WINDOW
+ cpx GR_WINDOW
+ bne @notpresent
+ inc GR_WINDOW
+ cpx GR_WINDOW
+ beq @notpresent
+
+ lda #4
+ jsr check
+ cpy GR_WINDOW
+ beq @has64k
+ lda #8
+ jsr check
+ cpy GR_WINDOW
+ beq @has128k
+ lda #16
+ jsr check
+ cpy GR_WINDOW
+ beq @has256k
+ lda #32
+ jsr check
+ cpy GR_WINDOW
+ beq @has512k
+ lda #64
+ jsr check
+ cpy GR_WINDOW
+ beq @has1024k
+ lda #128
+ jsr check
+ cpy GR_WINDOW
+ beq @has2048k
+ ldx #>16384
+ bne @setok
+
+@has64k:
+ ldx #>256
+ bne @setok
+@has128k:
+ ldx #>512
+ bne @setok
+@has256k:
+ ldx #>1024
+ bne @setok
+@has512k:
+ ldx #>2048
+ bne @setok
+@has1024k:
+ ldx #>4096
+ bne @setok
+@has2048k:
+ ldx #>8192
+ bne @setok
+
+@notpresent:
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+ rts
+
+@setok:
+ lda #0
+ sta pagecount
+ stx pagecount+1
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+ rts
+
+check:
+ ldx #0
+ stx GR_PAGE_LO
+ stx GR_PAGE_HI
+ ldy GR_WINDOW
+ iny
+ sta GR_PAGE_HI
+ sty GR_WINDOW
+ ldx #0
+ stx GR_PAGE_HI
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+; The GeoRAM cartridge does not copy but actually map the window, so USE is
+; identical to MAP.
+
+USE = MAP
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta tmp1
+ txa
+ asl tmp1
+ rol a
+ asl tmp1
+ rol a
+
+ sta GR_PAGE_HI
+ lda tmp1
+ lsr a
+ lsr a
+ sta GR_PAGE_LO
+
+ lda #<GR_WINDOW
+ ldx #>GR_WINDOW
+
+; Use the RTS from COMMIT below to save a precious byte of storage
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - tmp2 contains the high page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1: lda GR_WINDOW,x
+ sta (ptr2),y
+ iny
+ bne @L2
+ inc ptr2+1
+@L2: inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4: inc tmp1 ; Bump low page register
+ bit tmp1 ; Check for overflow in bit 6
+ bvc @L6 ; Jump if no overflow
+ inc tmp2
+@L5: lda tmp2
+ sta GR_PAGE_HI
+@L6: lda tmp1
+ sta GR_PAGE_LO
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - tmp2 contains the high page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1: lda (ptr2),y
+ sta GR_WINDOW,x
+ iny
+ bne @L2
+ inc ptr2+1
+@L2: inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4: inc tmp1 ; Bump low page register
+ bit tmp1 ; Check for overflow in bit 6
+ bvc @L6 ; Jump if no overflow
+ inc tmp2
+@L5: lda tmp2
+ sta GR_PAGE_HI
+@L6: lda tmp1
+ sta GR_PAGE_LO
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+
+setup: sta ptr1
+ stx ptr1+1 ; Save passed pointer
+
+; Get the page number from the struct and adjust it so that it may be used
+; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
+
+ ldy #EM_COPY::PAGE+1
+ lda (ptr1),y
+ sta tmp2
+ dey
+ lda (ptr1),y
+ asl a
+ rol tmp2
+ asl a
+ rol tmp2
+ lsr a
+ lsr a
+ sta tmp1
+
+; Get the buffer pointer into ptr2
+
+ ldy #EM_COPY::BUF
+ lda (ptr1),y
+ sta ptr2
+ iny
+ lda (ptr1),y
+ sta ptr2+1
+
+; Get the count, calculate -(count-1) and store it into ptr3
+
+ ldy #EM_COPY::COUNT
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3
+ iny
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3+1
+
+; Get the page offset into X and clear Y
+
+ ldy #EM_COPY::OFFS
+ lda (ptr1),y
+ tax
+ ldy #$00
+
+; Done
+
+ rts
+
+
--- /dev/null
+;
+; Extended memory driver for the C128 RAM in bank #1. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2002-12-04
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+ .include "c128.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BASE = $400
+TOPMEM = $FF00
+PAGES = (TOPMEM - BASE) / 256
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+curpage: .res 1 ; Current page number
+
+window: .res 256 ; Memory "window"
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx #$FF
+ stx curpage
+ stx curpage+1 ; Invalidate the current page
+ inx
+ txa ; A = X = EM_ERR_OK
+ rts
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda #<PAGES
+ ldx #>PAGES
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage
+ stx curpage+1 ; Remember the new page
+
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+
+ lda #<ptr1
+ sta FETVEC
+
+; Transfer one page
+
+@L1: ldx #MMU_CFG_RAM1
+ jsr FETCH
+ sta window,y
+ iny
+ bne @L1
+
+; Return the memory window
+
+ lda #<window
+ ldx #>window ; Return the window address
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage
+ stx curpage+1 ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage ; Get the current page
+ ldx curpage+1
+ bmi done ; Jump if no page mapped
+
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+
+ lda #<ptr1
+ sta STAVEC
+
+; Transfer one page. Y must be zero on entry
+
+@L1: lda window,y
+ ldx #MMU_CFG_RAM1
+ jsr STASH
+ iny
+ bne @L1
+
+; Done
+
+done: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ clc
+ adc #>BASE
+ sta ptr1+1 ; From
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; To
+
+ lda #<ptr1
+ sta FETVEC
+
+ ldy #EM_COPY::COUNT+1
+ lda (ptr3),y ; Get number of pages
+ beq @L2 ; Skip if no full pages
+ sta tmp1
+
+; Copy full pages
+
+ ldy #$00
+@L1: ldx #MMU_CFG_RAM1
+ jsr FETCH
+ sta (ptr2),y
+ iny
+ bne @L1
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+ ldy #$00
+@L3: ldx #MMU_CFG_RAM1
+ jsr FETCH
+ sta (ptr2),y
+ iny
+ dec tmp1
+ bne @L3
+
+; Done
+
+@L4: rts
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO: sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ clc
+ adc #>BASE
+ sta ptr1+1 ; To
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; From
+
+ lda #<ptr1
+ sta STAVEC
+
+ ldy #EM_COPY::COUNT+1
+ lda (ptr3),y ; Get number of pages
+ beq @L2 ; Skip if no full pages
+ sta tmp1
+
+; Copy full pages
+
+ ldy #$00
+@L1: lda (ptr2),y
+ ldx #MMU_CFG_RAM1
+ jsr STASH
+ iny
+ bne @L1
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+ ldy #$00
+@L3: lda (ptr2),y
+ ldx #MMU_CFG_RAM1
+ jsr STASH
+ iny
+ dec tmp1
+ bne @L3
+
+; Done
+
+@L4: rts
+
--- /dev/null
+;
+; Extended memory driver for the C128 RAM in banks #1, #2 and #3. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2002-12-04
+;
+; Updated to use banks 2 and 3 as well by
+; Marco van den Heuvel, 2010-01-21
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+ .include "c128.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BASE = $400
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+curpage: .res 2 ; Current page number
+curbank: .res 1 ; Current bank number
+copybank: .res 2 ; temp bank number
+
+window: .res 256 ; Memory "window"
+
+pagecount: .res 2 ; Number of available pages
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx #0
+ stx ptr1
+ ldx #4
+ stx ptr1+1
+ ldx #<ptr1
+ stx FETVEC
+ stx STAVEC
+ ldy #0
+ ldx #MMU_CFG_RAM1
+ jsr FETCH
+ sta tmp1
+ ldx #MMU_CFG_RAM3
+ jsr FETCH
+ cmp tmp1
+ bne @has_4_banks
+ tax
+ inx
+ txa
+ ldx #MMU_CFG_RAM1
+ jsr STASH
+ ldx #MMU_CFG_RAM3
+ jsr FETCH
+ cmp tmp1
+ beq @has_4_banks
+ ldx #0
+ lda #251
+ bne @setok
+
+@has_4_banks:
+ ldx #2
+ lda #241
+@setok:
+ sta pagecount
+ stx pagecount+1
+ ldx #$FF
+ stx curpage
+ stx curpage+1 ; Invalidate the current page
+ inx
+ txa ; A = X = EM_ERR_OK
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sei
+ sta curpage
+ stx curpage+1 ; Remember the new page
+
+ jsr calculate_bank_and_correct_page
+ stx curbank
+
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+ lda #<ptr1
+ sta FETVEC
+
+; Transfer one page
+
+@L1: ldx curbank
+ jsr getcurbankmmu
+ jsr FETCH
+ sta window,y
+ iny
+ bne @L1
+
+; Return the memory window
+
+ lda #<window
+ ldx #>window ; Return the window address
+ cli
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage
+ stx curpage+1 ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: sei
+ lda curpage ; Get the current page
+ ldx curpage+1
+ bmi done ; Jump if no page mapped
+
+ jsr calculate_bank_and_correct_page
+ stx curbank
+
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+
+ lda #<ptr1
+ sta STAVEC
+
+; Transfer one page. Y must be zero on entry
+
+@L1: lda window,y
+ ldx curbank
+ jsr getcurbankmmu
+ jsr STASH
+ iny
+ bne @L1
+ cli
+
+; Done
+
+done: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ sei
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - ptr4 contains the page buffer and offset
+; - tmp1 contains the bank
+; - tmp2 contains zero (used for linear memory buffer offset)
+
+ lda #<ptr4
+ sta FETVEC
+ jmp @L3
+
+@L1: ldx tmp1
+ jsr getcurbankmmu
+ ldy #0
+ jsr FETCH
+ ldy tmp2
+ sta (ptr2),y
+ inc tmp2
+ bne @L2
+ inc ptr2+1
+@L2: inc ptr4
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ cli
+ rts
+
+; Bump page register
+
+@L4: inc ptr4+1
+ lda ptr4+1
+ cmp #$ff
+ bne @L3
+ lda #4
+ sta ptr4+1
+ inc tmp1
+@L5:
+ jmp @L3
+
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ sei
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - ptr4 contains the page buffer and offset
+; - tmp1 contains the bank
+; - tmp2 contains zero (used for linear memory buffer offset)
+
+ lda #<ptr4
+ sta STAVEC
+ jmp @L3
+
+@L1:
+ ldy tmp2
+ lda (ptr2),y
+ ldx tmp1
+ jsr getcurbankmmu
+ ldy #0
+ jsr STASH
+ inc tmp2
+ bne @L2
+ inc ptr2+1
+@L2: inc ptr4
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ cli
+ rts
+
+; Bump page register
+
+@L4: inc ptr4+1
+ lda ptr4+1
+ cmp #$ff
+ bne @L3
+ inc tmp1
+ lda #4
+ sta ptr4+1
+@L5:
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; Helper function to calculate the correct bank and page
+; when addressing bank 2 or 3
+
+calculate_bank_and_correct_page:
+ cpx #2
+ beq @calculate_bank_3_with_2
+ cpx #1
+ beq @calculate_bank_2_or_3_with_1
+ sec
+ sbc #251
+ bcs @calculate_bank_2_with_0
+ ldx #1
+ lda curpage
+ rts
+
+@calculate_bank_3_with_2:
+ lda curpage
+ clc
+ adc #10
+@calculate_bank_3_with_1:
+ ldx #3
+ rts
+
+@calculate_bank_2_or_3_with_1:
+ sec
+ sbc #246
+ bcs @calculate_bank_3_with_1
+ lda curpage
+ clc
+ adc #5
+@calculate_bank_2_with_0:
+ ldx #2
+ rts
+
+; ------------------------------------------------------------------------
+; Helper function to get the correct mmu value in x
+
+getcurbankmmu:
+ cpx #1
+ beq @bank1
+ cpx #2
+ beq @bank2
+ ldx #MMU_CFG_RAM3
+ rts
+@bank2:
+ ldx #MMU_CFG_RAM2
+ rts
+@bank1:
+ ldx #MMU_CFG_RAM1
+ rts
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+
+setup: sta ptr1
+ stx ptr1+1 ; Save passed pointer
+
+; Get the page number from the struct and adjust it so that it may be used
+; with the hardware. That is: page pointer in ptr4 and bank in tmp1
+
+ ldy #EM_COPY::PAGE+1
+ lda (ptr1),y
+ tax
+ dey
+ lda (ptr1),y
+ sta curpage
+ jsr calculate_bank_and_correct_page
+ clc
+ adc #4
+ sta ptr4+1
+ stx tmp1
+
+; Get the buffer pointer into ptr2
+
+ ldy #EM_COPY::BUF
+ lda (ptr1),y
+ sta ptr2
+ iny
+ lda (ptr1),y
+ sta ptr2+1
+
+; Get the count, calculate -(count-1) and store it into ptr3
+
+ ldy #EM_COPY::COUNT
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3
+ iny
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3+1
+
+; Get the page offset into the low byte of ptr4 clear tmp2
+
+ ldy #EM_COPY::OFFS
+ lda (ptr1),y
+ sta ptr4
+ lda #0
+ sta tmp2
+
+; Done
+
+ rts
--- /dev/null
+;
+; Extended memory driver for the RamCart 64/128KB cartridge. Driver works
+; without problems when statically linked.
+; Code is based on GEORAM code by Ullrich von Bassewitz.
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 06,22.12.2002
+;
+
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+RAMC_WINDOW = $DF00 ; Address of RamCart window
+RAMC_PAGE_LO = $DE00 ; Page register low
+RAMC_PAGE_HI = $DE01 ; Page register high (only for RC128)
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+
+pagecount: .res 2 ; Number of pages available
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx RAMC_WINDOW
+ cpx RAMC_WINDOW
+ bne @notpresent
+
+ lda #0
+ sta RAMC_PAGE_LO
+ sta RAMC_PAGE_HI
+ ldx RAMC_WINDOW
+ cpx RAMC_WINDOW
+ bne @notpresent
+ lda #2
+ sta RAMC_WINDOW
+ cmp RAMC_WINDOW
+ beq @cont
+ cpx RAMC_WINDOW
+ beq @readonly
+@cont: ldy #1
+ sty RAMC_PAGE_HI
+ sty RAMC_WINDOW
+ dey
+ sty RAMC_PAGE_HI
+ iny
+ cpy RAMC_WINDOW
+ beq @rc64
+ ; we're on rc128
+ ldx #>512
+ bne @setsize
+@rc64: ldx #>256
+@setsize:
+ lda #0
+ sta pagecount
+ stx pagecount+1
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+ rts
+@notpresent:
+@readonly:
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+; The RamCart cartridge does not copy but actually map the window, so USE is
+; identical to MAP.
+
+USE = MAP
+
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta RAMC_PAGE_LO
+ stx RAMC_PAGE_HI
+ lda #<RAMC_WINDOW
+ ldx #>RAMC_WINDOW
+
+; Use the RTS from COMMIT below to save a precious byte of storage
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - tmp2 contains the high page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1: lda RAMC_WINDOW,x
+ sta (ptr2),y
+ iny
+ bne @L2
+ inc ptr2+1
+@L2: inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4: inc tmp1
+ bne @L5
+ inc tmp2
+@L5: lda tmp1
+ sta RAMC_PAGE_LO
+ lda tmp2
+ sta RAMC_PAGE_HI
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - tmp2 contains the high page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1: lda (ptr2),y
+ sta RAMC_WINDOW,x
+ iny
+ bne @L2
+ inc ptr2+1
+@L2: inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4: inc tmp1
+ bne @L5
+ inc tmp2
+@L5: lda tmp1
+ sta RAMC_PAGE_LO
+ lda tmp2
+ sta RAMC_PAGE_HI
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+
+setup: sta ptr1
+ stx ptr1+1 ; Save passed pointer
+
+; Get the page number from the struct and adjust it so that it may be used
+; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
+
+ ldy #EM_COPY::PAGE+1
+ lda (ptr1),y
+ sta tmp2
+ dey
+ lda (ptr1),y
+ sta tmp1
+
+; Get the buffer pointer into ptr2
+
+ ldy #EM_COPY::BUF
+ lda (ptr1),y
+ sta ptr2
+ iny
+ lda (ptr1),y
+ sta ptr2+1
+
+; Get the count, calculate -(count-1) and store it into ptr3
+
+ ldy #EM_COPY::COUNT
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3
+ iny
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3+1
+
+; Get the page offset into X and clear Y
+
+ ldy #EM_COPY::OFFS
+ lda (ptr1),y
+ tax
+ ldy #$00
+
+; Done
+
+ rts
+
--- /dev/null
+;
+; Extended memory driver for the Commodore REU. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2002-11-29
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+ .include "c128.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+REU_STATUS = $DF00 ; Status register
+REU_COMMAND = $DF01 ; Command register
+REU_C64ADDR = $DF02 ; C64 base address register
+REU_REUADDR = $DF04 ; REU base address register
+REU_COUNT = $DF07 ; Transfer count register
+REU_IRQMASK = $DF09 ; IRQ mask register
+REU_CONTROL = $DF0A ; Control register
+REU_TRIGGER = $FF00 ; REU command trigger
+
+OP_COPYFROM = $ED
+OP_COPYTO = $EC
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+pagecount: .res 2 ; Number of pages available
+curpage: .res 2 ; Current page number
+
+window: .res 256 ; Memory "window"
+
+reu_params: .word $0000 ; Host address, lo, hi
+ .word $0000 ; Exp address, lo, hi
+ .byte $00 ; Expansion bank no.
+ .word $0000 ; # bytes to move, lo, hi
+ .byte $00 ; Interrupt mask reg.
+ .byte $00 ; Adress control reg.
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx #$00 ; High byte of return code
+ lda #$55
+ sta REU_REUADDR
+ cmp REU_REUADDR ; Check for presence of REU
+ bne nodevice
+ asl a ; A = $AA
+ sta REU_REUADDR
+ cmp REU_REUADDR ; Check for presence of REU
+ bne nodevice
+
+ ldy #>(128*4) ; Assume 128KB
+ lda REU_STATUS
+ and #$10 ; Check size bit
+ beq @L1
+ ldy #>(256*4) ; 256KB when size bit is set
+@L1: sty pagecount+1
+
+ ldy #$FF
+ sty curpage
+ sty curpage+1 ; Invalidate the current page
+ txa ; X = A = EM_ERR_OK
+ rts
+
+; No REU found
+
+nodevice:
+ lda #EM_ERR_NO_DEVICE
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage
+ stx curpage+1 ; Remember the new page
+
+ ldy #OP_COPYFROM
+ jsr common ; Copy the window
+
+ lda #<window
+ ldx #>window ; Return the window address
+done: rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage
+ stx curpage+1 ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage
+ ldx curpage+1 ; Do we have a page mapped?
+ bmi done ; Jump if no page mapped
+
+ ldy #OP_COPYTO
+common: sty tmp1
+
+ ldy #<window
+ sty REU_C64ADDR
+ ldy #>window
+ sty REU_C64ADDR+1
+
+ ldy #0
+ sty REU_REUADDR+0
+ sta REU_REUADDR+1
+ stx REU_REUADDR+2
+
+ sty REU_COUNT+0
+ ldy #1
+ sty REU_COUNT+1 ; Move 256 bytes
+ bne transfer1 ; Transfer 256 bytes into REU
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ ldy #OP_COPYFROM
+ .byte $2C
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ ldy #OP_COPYTO
+ sty tmp1
+
+; Remember the passed pointer
+
+ sta ptr1
+ stx ptr1+1 ; Save the pointer
+
+; The structure passed to the functions has the same layout as the registers
+; of the Commodore REU, so register programming is easy.
+
+ ldy #7-1
+@L1: lda (ptr1),y
+ sta REU_C64ADDR,y
+ dey
+ bpl @L1
+
+; Invalidate the page in the memory window
+
+ sty curpage+1 ; Y = $FF
+
+; Reload the REU command and start the transfer
+
+transfer1:
+ ldy tmp1
+
+; Transfer subroutine for the REU. Expects command in Y.
+
+transfer:
+ sty REU_COMMAND ; Issue command
+
+ ldy MMU_CR ; Save the current MMU settings
+ lda #MMU_CFG_RAM0 ;
+ sei ;
+ sta MMU_CR ; Enable RAM in bank #0
+ lda REU_TRIGGER ; Don't change $FF00
+ sta REU_TRIGGER ; Start the transfer...
+
+ sty MMU_CR ; Restore the old configuration
+ cli
+ rts
+
--- /dev/null
+;
+; Extended memory driver for the VDC RAM available on all C128 machines
+; (based on code by Ullrich von Bassewitz)
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 06,20.12.2002
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word DEINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+VDC_ADDR_REG = $D600 ; VDC address
+VDC_DATA_REG = $D601 ; VDC data
+
+VDC_DATA_HI = 18 ; used registers
+VDC_DATA_LO = 19
+VDC_CSET = 28
+VDC_DATA = 31
+
+; ------------------------------------------------------------------------
+; Data.
+
+.data
+
+pagecount: .word 64 ; $0000-$3fff as 16k default
+curpage: .word $ffff ; currently mapped-in page (invalid)
+
+.bss
+
+window: .res 256 ; memory window
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ; do test for VDC presence here???
+
+ ldx #VDC_CSET ; determine size of RAM...
+ jsr vdcgetreg
+ sta tmp1
+ ora #%00010000
+ jsr vdcputreg ; turn on 64k
+
+ jsr settestadr1 ; save original value of test byte
+ jsr vdcgetbyte
+ sta tmp2
+
+ lda #$55 ; write $55 here
+ ldy #ptr1
+ jsr test64k ; read it here and there
+ lda #$aa ; write $aa here
+ ldy #ptr2
+ jsr test64k ; read it here and there
+
+ jsr settestadr1
+ lda tmp2
+ jsr vdcputbyte ; restore original value of test byte
+
+ lda ptr1 ; do bytes match?
+ cmp ptr1+1
+ bne @have64k
+ lda ptr2
+ cmp ptr2+1
+ bne @have64k
+
+ ldx #VDC_CSET
+ lda tmp1
+ jsr vdcputreg ; restore 16/64k flag
+ jmp @endok ; and leave default values for 16k
+
+@have64k:
+ lda #<256
+ ldx #>256
+ sta pagecount
+ stx pagecount+1
+@endok:
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+ rts
+
+test64k:
+ sta tmp1
+ sty ptr3
+ lda #0
+ sta ptr3+1
+ jsr settestadr1
+ lda tmp1
+ jsr vdcputbyte ; write $55
+ jsr settestadr1
+ jsr vdcgetbyte ; read here
+ pha
+ jsr settestadr2
+ jsr vdcgetbyte ; and there
+ ldy #1
+ sta (ptr3),y
+ pla
+ dey
+ sta (ptr3),y
+ rts
+
+settestadr1:
+ ldy #$02 ; test page 2 (here)
+ .byte $2c
+settestadr2:
+ ldy #$42 ; or page 64+2 (there)
+ lda #0
+ jmp vdcsetsrcaddr
+
+; ------------------------------------------------------------------------
+; DEINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+DEINSTALL:
+ ;on C128 restore font and clear the screen?
+ rts
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage
+ stx curpage+1
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+ jsr transferin
+
+ lda #<window
+ ldx #>window
+ rts
+
+; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
+
+transferin:
+ lda ptr1
+ ldy ptr1+1
+ jsr vdcsetsrcaddr ; set source address in VDC
+ ldy #0
+ ldx #VDC_DATA
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda VDC_DATA_REG ; get 2 bytes at a time to speed-up
+ sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config)
+ iny
+ lda VDC_DATA_REG
+ sta (ptr2),y
+ iny
+ bne @L0
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage
+ stx curpage+1 ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+done: rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT:
+ lda curpage ; jump if no page mapped
+ ldx curpage+1
+ bmi done
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+; fall through to transferout
+
+; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
+
+transferout:
+ lda ptr1
+ ldy ptr1+1
+ jsr vdcsetsrcaddr ; set source address in VDC
+ ldy #0
+ ldx #VDC_DATA
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda (ptr2),y ; speedup does not work for writing
+ sta VDC_DATA_REG
+ iny
+ bne @L0
+ rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+ beq @L2 ; Skip if no full pages
+
+; Copy full pages
+
+@L1: jsr transferin
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+; Transfer the bytes in the last page
+
+ ldy #0
+@L3: jsr vdcgetbyte
+ sta (ptr2),y
+ iny
+ dec tmp1
+ lda tmp1
+ bne @L3
+@L4: rts
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ jsr setup
+ beq @L2 ; Skip if no full pages
+
+; Copy full pages
+
+@L1: jsr transferout
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+; Transfer the bytes in the last page
+
+ ldy #0
+@L3: lda (ptr2),y
+ jsr vdcputbyte
+ iny
+ dec tmp1
+ lda tmp1
+ bne @L3
+@L4: rts
+
+;-------------------------------------------------------------------------
+; Helper functions to handle VDC ram
+;
+
+vdcsetsrcaddr:
+ ldx #VDC_DATA_LO
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ sta VDC_DATA_REG
+ dex
+ tya
+ stx VDC_ADDR_REG
+ sta VDC_DATA_REG
+ rts
+
+vdcgetbyte:
+ ldx #VDC_DATA
+vdcgetreg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda VDC_DATA_REG
+ rts
+
+vdcputbyte:
+ ldx #VDC_DATA
+vdcputreg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ sta VDC_DATA_REG
+ rts
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+;
+
+setup:
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ sta ptr1+1 ; From
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; To
+
+ ldy #EM_COPY::COUNT+1
+ lda (ptr3),y ; Get number of pages
+ sta tmp1
+ rts
+
--- /dev/null
+;
+; PTV-4 Player joystick driver for the C128
+;
+; Ullrich von Bassewitz, 2003-09-28, using the C64 driver from
+; Groepaz/Hitmen, 2002-12-23, which is
+; obviously based on Ullrichs driver :)
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "c128.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ .segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 4 ; Number of joysticks we support
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: tax ; Joystick number into X
+ bne joy2
+
+; Read joystick 1
+
+joy1: lda #$7F
+ sei
+ sta CIA1_PRA
+ lda CIA1_PRB
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+; Read joystick 2
+
+joy2: dex
+ bne joy3
+
+ lda #$E0
+ ldy #$FF
+ sei
+ sta CIA1_DDRA
+ lda CIA1_PRA
+ sty CIA1_DDRA
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+; Read joystick 3
+
+joy3:
+ lda #%10000000 ; cia 2 port B Data-Direction
+ sta CIA2_DDRB ; bit 7: out bit 6-0: in
+
+ dex
+ bne joy4
+
+ lda #$80 ; cia 2 port B read/write
+ sta CIA2_PRB ; (output one at PB7)
+
+ lda CIA2_PRB ; cia 2 port B read/write
+ and #$1f ; get bit 4-0 (PB4-PB0)
+ eor #$1f
+ rts
+
+; Read joystick 4
+
+joy4:
+ lda #$00 ; cia 2 port B read/write
+ sta CIA2_PRB ; (output zero at PB7)
+
+ lda CIA2_PRB ; cia 2 port B read/write
+ and #$0f ; get bit 3-0 (PB3-PB0)
+ sta tmp1 ; joy 4 directions
+
+ lda CIA2_PRB ; cia 2 port B read/write
+ and #%00100000 ; get bit 5 (PB5)
+ lsr
+ ora tmp1
+ eor #$1f
+
+ ldx #0
+ rts
--- /dev/null
+;
+; Standard joystick driver for the C128. May be used multiple times when linked
+; to the statically application.
+
+;
+; Ullrich von Bassewitz, 2002-12-21
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "c128.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry not used
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: tax ; Joystick number into X
+ bne joy2
+
+; Read joystick 1
+
+joy1: lda #$7F
+ sei
+ sta CIA1_PRA
+ lda CIA1_PRB
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+; Read joystick 2
+
+joy2: ldx #0
+ lda #$E0
+ ldy #$FF
+ sei
+ sta CIA1_DDRA
+ lda CIA1_PRA
+ sty CIA1_DDRA
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+
--- /dev/null
+;
+; Driver for the 1351 proportional mouse. Parts of the code are from
+; the Commodore 1351 mouse users guide.
+;
+; Ullrich von Bassewitz, 2003-12-29, 2009-09-26
+;
+
+ .include "zeropage.inc"
+ .include "mouse-kernel.inc"
+ .include "c128.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+HEADER:
+
+; Driver signature
+
+ .byte $6d, $6f, $75 ; "mou"
+ .byte MOUSE_API_VERSION ; Mouse driver API version number
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr HIDE
+ .addr SHOW
+ .addr SETBOX
+ .addr GETBOX
+ .addr MOVE
+ .addr BUTTONS
+ .addr POS
+ .addr INFO
+ .addr IOCTL
+ .addr IRQ
+
+; Mouse driver flags
+
+ .byte MOUSE_FLAG_LATE_IRQ
+
+; Callback table, set by the kernel before INSTALL is called
+
+CHIDE: jmp $0000 ; Hide the cursor
+CSHOW: jmp $0000 ; Show the cursor
+CMOVEX: jmp $0000 ; Move the cursor to X coord
+CMOVEY: jmp $0000 ; Move the cursor to Y coord
+
+
+;----------------------------------------------------------------------------
+; Constants
+
+SCREEN_HEIGHT = 200
+SCREEN_WIDTH = 320
+
+;----------------------------------------------------------------------------
+; Global variables. The bounding box values are sorted so that they can be
+; written with the least effort in the SETBOX and GETBOX routines, so don't
+; reorder them.
+
+.bss
+
+Vars:
+OldPotX: .res 1 ; Old hw counter values
+OldPotY: .res 1
+
+YPos: .res 2 ; Current mouse position, Y
+XPos: .res 2 ; Current mouse position, X
+XMin: .res 2 ; X1 value of bounding box
+YMin: .res 2 ; Y1 value of bounding box
+XMax: .res 2 ; X2 value of bounding box
+YMax: .res 2 ; Y2 value of bounding box
+
+OldValue: .res 1 ; Temp for MoveCheck routine
+NewValue: .res 1 ; Temp for MoveCheck routine
+
+; Default values for above variables
+
+.rodata
+
+.proc DefVars
+ .byte 0, 0 ; OldPotX/OldPotY
+ .word SCREEN_HEIGHT/2 ; YPos
+ .word SCREEN_WIDTH/2 ; XPos
+ .word 0 ; XMin
+ .word 0 ; YMin
+ .word SCREEN_WIDTH ; XMax
+ .word SCREEN_HEIGHT ; YMax
+.endproc
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an MOUSE_ERR_xx code in a/x.
+
+INSTALL:
+
+; Initialize variables. Just copy the default stuff over
+
+ ldx #.sizeof(DefVars)-1
+@L1: lda DefVars,x
+ sta Vars,x
+ dex
+ bpl @L1
+
+; Be sure the mouse cursor is invisible and at the default location. We
+; need to do that here, because our mouse interrupt handler doesn't set the
+; mouse position if it hasn't changed.
+
+ sei
+ jsr CHIDE
+ lda XPos
+ ldx XPos+1
+ jsr CMOVEX
+ lda YPos
+ ldx YPos+1
+ jsr CMOVEY
+ cli
+
+; Done, return zero (= MOUSE_ERR_OK)
+
+ ldx #$00
+ txa
+ rts ; Run into UNINSTALL instead
+
+;----------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+
+UNINSTALL = HIDE ; Hide cursor on exit
+
+;----------------------------------------------------------------------------
+; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently visible and should get hidden. For most drivers,
+; no special action is required besides hiding the mouse cursor.
+; No return code required.
+
+HIDE: sei
+ jsr CHIDE
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently hidden and should become visible. For most drivers,
+; no special action is required besides enabling the mouse cursor.
+; No return code required.
+
+SHOW: sei
+ jsr CSHOW
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SETBOX: Set the mouse bounding box. The parameters are passed as they come
+; from the C program, that is, a pointer to a mouse_box struct in a/x.
+; No checks are done if the mouse is currently inside the box, this is the job
+; of the caller. It is not necessary to validate the parameters, trust the
+; caller and save some code here. No return code required.
+
+SETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda (ptr1),y
+ sta XMin,y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; GETBOX: Return the mouse bounding box. The parameters are passed as they
+; come from the C program, that is, a pointer to a mouse_box struct in a/x.
+
+GETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda XMin,y
+ sta (ptr1),y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; MOVE: Move the mouse to a new position. The position is passed as it comes
+; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
+; remove the parameter from the stack on return.
+; No checks are done if the new position is valid (within the bounding box or
+; the screen). No return code required.
+;
+
+MOVE: sei ; No interrupts
+
+ sta YPos
+ stx YPos+1 ; New Y position
+ jsr CMOVEY ; Set it
+
+ ldy #$01
+ lda (sp),y
+ sta XPos+1
+ tax
+ dey
+ lda (sp),y
+ sta XPos ; New X position
+
+ jsr CMOVEX ; Move the cursor
+
+ cli ; Allow interrupts
+ rts
+
+;----------------------------------------------------------------------------
+; BUTTONS: Return the button mask in a/x.
+
+BUTTONS:
+ lda #$7F
+ sei
+ sta CIA1_PRA
+ lda CIA1_PRB ; Read joystick #0
+ cli
+ ldx #0
+ and #$1F
+ eor #$1F
+ rts
+
+;----------------------------------------------------------------------------
+; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
+; No return code required.
+
+POS: ldy #MOUSE_POS::XCOORD ; Structure offset
+
+ sei ; Disable interrupts
+ lda XPos ; Transfer the position
+ sta (ptr1),y
+ lda XPos+1
+ iny
+ sta (ptr1),y
+ lda YPos
+ iny
+ sta (ptr1),y
+ lda YPos+1
+ cli ; Enable interrupts
+
+ iny
+ sta (ptr1),y ; Store last byte
+
+ rts ; Done
+
+;----------------------------------------------------------------------------
+; INFO: Returns mouse position and current button mask in the MOUSE_INFO
+; struct pointed to by ptr1. No return code required.
+;
+; We're cheating here to keep the code smaller: The first fields of the
+; mouse_info struct are identical to the mouse_pos struct, so we will just
+; call _mouse_pos to initialize the struct pointer and fill the position
+; fields.
+
+INFO: jsr POS
+
+; Fill in the button state
+
+ jsr BUTTONS ; Will not touch ptr1
+ ldy #MOUSE_INFO::BUTTONS
+ sta (ptr1),y
+
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>MOUSE_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
+; (so be careful). The routine MUST return carry set if the interrupt has been
+; 'handled' - which means that the interrupt source is gone. Otherwise it
+; MUST return carry clear.
+;
+
+IRQ: lda SID_ADConv1 ; Get mouse X movement
+ ldy OldPotX
+ jsr MoveCheck ; Calculate movement vector
+ sty OldPotX
+
+; Skip processing if nothing has changed
+
+ bcc @SkipX
+
+; Calculate the new X coordinate (--> a/y)
+
+ add XPos
+ tay ; Remember low byte
+ txa
+ adc XPos+1
+ tax
+
+; Limit the X coordinate to the bounding box
+
+ cpy XMin
+ sbc XMin+1
+ bpl @L1
+ ldy XMin
+ ldx XMin+1
+ jmp @L2
+@L1: txa
+
+ cpy XMax
+ sbc XMax+1
+ bmi @L2
+ ldy XMax
+ ldx XMax+1
+@L2: sty XPos
+ stx XPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jsr CMOVEX
+
+; Calculate the Y movement vector
+
+@SkipX: lda SID_ADConv2 ; Get mouse Y movement
+ ldy OldPotY
+ jsr MoveCheck ; Calculate movement
+ sty OldPotY
+
+; Skip processing if nothing has changed
+
+ bcc @SkipY
+
+; Calculate the new Y coordinate (--> a/y)
+
+ sta OldValue
+ lda YPos
+ sub OldValue
+ tay
+ stx OldValue
+ lda YPos+1
+ sbc OldValue
+ tax
+
+; Limit the Y coordinate to the bounding box
+
+ cpy YMin
+ sbc YMin+1
+ bpl @L3
+ ldy YMin
+ ldx YMin+1
+ jmp @L4
+@L3: txa
+
+ cpy YMax
+ sbc YMax+1
+ bmi @L4
+ ldy YMax
+ ldx YMax+1
+@L4: sty YPos
+ stx YPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jsr CMOVEY
+
+; Done
+
+ clc ; Interrupt not "handled"
+@SkipY: rts
+
+; --------------------------------------------------------------------------
+;
+; Move check routine, called for both coordinates.
+;
+; Entry: y = old value of pot register
+; a = current value of pot register
+; Exit: y = value to use for old value
+; x/a = delta value for position
+;
+
+MoveCheck:
+ sty OldValue
+ sta NewValue
+ ldx #$00
+
+ sub OldValue ; a = mod64 (new - old)
+ and #%01111111
+ cmp #%01000000 ; if (a > 0)
+ bcs @L1 ;
+ lsr a ; a /= 2;
+ beq @L2 ; if (a != 0)
+ ldy NewValue ; y = NewValue
+ sec
+ rts ; return
+
+@L1: ora #%11000000 ; else or in high order bits
+ cmp #$FF ; if (a != -1)
+ beq @L2
+ sec
+ ror a ; a /= 2
+ dex ; high byte = -1 (X = $FF)
+ ldy NewValue
+ sec
+ rts
+
+@L2: txa ; A = $00
+ clc
+ rts
+
--- /dev/null
+;
+; Driver for a "joystick mouse".
+;
+; Ullrich von Bassewitz, 2004-04-05, 2009-09-26
+;
+
+ .include "zeropage.inc"
+ .include "mouse-kernel.inc"
+ .include "c128.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+HEADER:
+
+; Driver signature
+
+ .byte $6d, $6f, $75 ; "mou"
+ .byte MOUSE_API_VERSION ; Mouse driver API version number
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr HIDE
+ .addr SHOW
+ .addr SETBOX
+ .addr GETBOX
+ .addr MOVE
+ .addr BUTTONS
+ .addr POS
+ .addr INFO
+ .addr IOCTL
+ .addr IRQ
+
+; Mouse driver flags
+
+ .byte MOUSE_FLAG_LATE_IRQ
+
+; Callback table, set by the kernel before INSTALL is called
+
+CHIDE: jmp $0000 ; Hide the cursor
+CSHOW: jmp $0000 ; Show the cursor
+CMOVEX: jmp $0000 ; Move the cursor to X coord
+CMOVEY: jmp $0000 ; Move the cursor to Y coord
+
+
+;----------------------------------------------------------------------------
+; Constants
+
+SCREEN_HEIGHT = 200
+SCREEN_WIDTH = 320
+
+.enum JOY
+ UP = $01
+ DOWN = $02
+ LEFT = $04
+ RIGHT = $08
+ FIRE = $10
+.endenum
+
+;----------------------------------------------------------------------------
+; Global variables. The bounding box values are sorted so that they can be
+; written with the least effort in the SETBOX and GETBOX routines, so don't
+; reorder them.
+
+.bss
+
+Vars:
+YPos: .res 2 ; Current mouse position, Y
+XPos: .res 2 ; Current mouse position, X
+XMin: .res 2 ; X1 value of bounding box
+YMin: .res 2 ; Y1 value of bounding box
+XMax: .res 2 ; X2 value of bounding box
+YMax: .res 2 ; Y2 value of bounding box
+Buttons: .res 1 ; Button mask
+
+; Temporary value used in the int handler
+
+Temp: .res 1
+
+; Default values for above variables
+
+.rodata
+
+.proc DefVars
+ .word SCREEN_HEIGHT/2 ; YPos
+ .word SCREEN_WIDTH/2 ; XPos
+ .word 0 ; XMin
+ .word 0 ; YMin
+ .word SCREEN_WIDTH ; XMax
+ .word SCREEN_HEIGHT ; YMax
+ .byte 0 ; Buttons
+.endproc
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an MOUSE_ERR_xx code in a/x.
+
+INSTALL:
+
+; Initialize variables. Just copy the default stuff over
+
+ ldx #.sizeof(DefVars)-1
+@L1: lda DefVars,x
+ sta Vars,x
+ dex
+ bpl @L1
+
+; Be sure the mouse cursor is invisible and at the default location. We
+; need to do that here, because our mouse interrupt handler doesn't set the
+; mouse position if it hasn't changed.
+
+ sei
+ jsr CHIDE
+ lda XPos
+ ldx XPos+1
+ jsr CMOVEX
+ lda YPos
+ ldx YPos+1
+ jsr CMOVEY
+ cli
+
+; Done, return zero (= MOUSE_ERR_OK)
+
+ ldx #$00
+ txa
+ rts
+
+;----------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+
+UNINSTALL = HIDE ; Hide cursor on exit
+
+;----------------------------------------------------------------------------
+; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently visible and should get hidden. For most drivers,
+; no special action is required besides hiding the mouse cursor.
+; No return code required.
+
+HIDE: sei
+ jsr CHIDE
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently hidden and should become visible. For most drivers,
+; no special action is required besides enabling the mouse cursor.
+; No return code required.
+
+SHOW: sei
+ jsr CSHOW
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SETBOX: Set the mouse bounding box. The parameters are passed as they come
+; from the C program, that is, a pointer to a mouse_box struct in a/x.
+; No checks are done if the mouse is currently inside the box, this is the job
+; of the caller. It is not necessary to validate the parameters, trust the
+; caller and save some code here. No return code required.
+
+SETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda (ptr1),y
+ sta XMin,y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; GETBOX: Return the mouse bounding box. The parameters are passed as they
+; come from the C program, that is, a pointer to a mouse_box struct in a/x.
+
+GETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda XMin,y
+ sta (ptr1),y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; MOVE: Move the mouse to a new position. The position is passed as it comes
+; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
+; remove the parameter from the stack on return.
+; No checks are done if the new position is valid (within the bounding box or
+; the screen). No return code required.
+;
+
+MOVE: sei ; No interrupts
+
+ sta YPos
+ stx YPos+1 ; New Y position
+ jsr CMOVEY ; Set it
+
+ ldy #$01
+ lda (sp),y
+ sta XPos+1
+ tax
+ dey
+ lda (sp),y
+ sta XPos ; New X position
+
+ jsr CMOVEX ; Move the cursor
+
+ cli ; Allow interrupts
+ rts
+
+;----------------------------------------------------------------------------
+; BUTTONS: Return the button mask in a/x.
+
+BUTTONS:
+ lda Buttons
+ ldx #$00
+ rts
+
+;----------------------------------------------------------------------------
+; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
+; No return code required.
+
+POS: ldy #MOUSE_POS::XCOORD ; Structure offset
+
+ sei ; Disable interrupts
+ lda XPos ; Transfer the position
+ sta (ptr1),y
+ lda XPos+1
+ iny
+ sta (ptr1),y
+ lda YPos
+ iny
+ sta (ptr1),y
+ lda YPos+1
+ cli ; Enable interrupts
+
+ iny
+ sta (ptr1),y ; Store last byte
+
+ rts ; Done
+
+;----------------------------------------------------------------------------
+; INFO: Returns mouse position and current button mask in the MOUSE_INFO
+; struct pointed to by ptr1. No return code required.
+;
+; We're cheating here to keep the code smaller: The first fields of the
+; mouse_info struct are identical to the mouse_pos struct, so we will just
+; call _mouse_pos to initialize the struct pointer and fill the position
+; fields.
+
+INFO: jsr POS
+
+; Fill in the button state
+
+ lda Buttons
+ ldy #MOUSE_INFO::BUTTONS
+ sta (ptr1),y
+
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>MOUSE_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
+; (so be careful). The routine MUST return carry set if the interrupt has been
+; 'handled' - which means that the interrupt source is gone. Otherwise it
+; MUST return carry clear.
+;
+
+IRQ: lda #$7F
+ sta CIA1_PRA
+ lda CIA1_PRB ; Read joystick #0
+ and #$1F
+ eor #$1F ; Make all bits active high
+ sta Temp
+
+; Check for a pressed button and place the result into Buttons
+
+ ldx #$00 ; Assume no button pressed
+ and #JOY::FIRE ; Check fire button
+ beq @L0 ; Jump if not pressed
+ ldx #MOUSE_BTN_LEFT ; Left (only) button is pressed
+@L0: stx Buttons
+
+; Check left/right
+
+ lda Temp ; Read joystick #0
+ and #(JOY::LEFT | JOY::RIGHT)
+ beq @SkipX ;
+
+; We will cheat here and rely on the fact that either the left, OR the right
+; bit can be active
+
+ and #JOY::RIGHT ; Check RIGHT bit
+ bne @Right
+ lda #$FF
+ tax
+ bne @AddX ; Branch always
+@Right: lda #$01
+ ldx #$00
+
+; Calculate the new X coordinate (--> a/y)
+
+@AddX: add XPos
+ tay ; Remember low byte
+ txa
+ adc XPos+1
+ tax
+
+; Limit the X coordinate to the bounding box
+
+ cpy XMin
+ sbc XMin+1
+ bpl @L1
+ ldy XMin
+ ldx XMin+1
+ jmp @L2
+@L1: txa
+
+ cpy XMax
+ sbc XMax+1
+ bmi @L2
+ ldy XMax
+ ldx XMax+1
+@L2: sty XPos
+ stx XPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jsr CMOVEX
+
+; Calculate the Y movement vector
+
+@SkipX: lda Temp ; Read joystick #0
+ and #(JOY::UP | JOY::DOWN) ; Check up/down
+ beq @SkipY ;
+
+; We will cheat here and rely on the fact that either the up, OR the down
+; bit can be active
+
+ lsr a ; Check UP bit
+ bcc @Down
+ lda #$FF
+ tax
+ bne @AddY
+@Down: lda #$01
+ ldx #$00
+
+; Calculate the new Y coordinate (--> a/y)
+
+@AddY: add YPos
+ tay ; Remember low byte
+ txa
+ adc YPos+1
+ tax
+
+; Limit the Y coordinate to the bounding box
+
+ cpy YMin
+ sbc YMin+1
+ bpl @L3
+ ldy YMin
+ ldx YMin+1
+ jmp @L4
+@L3: txa
+
+ cpy YMax
+ sbc YMax+1
+ bmi @L4
+ ldy YMax
+ ldx YMax+1
+@L4: sty YPos
+ stx YPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jsr CMOVEY
+
+; Done
+
+@SkipY: clc ; Interrupt not "handled"
+ rts
+
--- /dev/null
+;
+; Driver for a potentiometer "mouse" e.g. Koala Pad
+;
+; Ullrich von Bassewitz, 2004-03-29, 2009-09-26
+; Stefan Haubenthal, 2006-08-20
+;
+
+ .include "zeropage.inc"
+ .include "mouse-kernel.inc"
+ .include "c128.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+HEADER:
+
+; Driver signature
+
+ .byte $6d, $6f, $75 ; "mou"
+ .byte MOUSE_API_VERSION ; Mouse driver API version number
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr HIDE
+ .addr SHOW
+ .addr SETBOX
+ .addr GETBOX
+ .addr MOVE
+ .addr BUTTONS
+ .addr POS
+ .addr INFO
+ .addr IOCTL
+ .addr IRQ
+
+; Callback table, set by the kernel before INSTALL is called
+
+CHIDE: jmp $0000 ; Hide the cursor
+CSHOW: jmp $0000 ; Show the cursor
+CMOVEX: jmp $0000 ; Move the cursor to X coord
+CMOVEY: jmp $0000 ; Move the cursor to Y coord
+
+
+;----------------------------------------------------------------------------
+; Constants
+
+SCREEN_HEIGHT = 200
+SCREEN_WIDTH = 320
+
+.enum JOY
+ UP = $01
+ DOWN = $02
+ LEFT = $04
+ RIGHT = $08
+ FIRE = $10
+.endenum
+
+;----------------------------------------------------------------------------
+; Global variables. The bounding box values are sorted so that they can be
+; written with the least effort in the SETBOX and GETBOX routines, so don't
+; reorder them.
+
+.bss
+
+Vars:
+YPos: .res 2 ; Current mouse position, Y
+XPos: .res 2 ; Current mouse position, X
+XMin: .res 2 ; X1 value of bounding box
+YMin: .res 2 ; Y1 value of bounding box
+XMax: .res 2 ; X2 value of bounding box
+YMax: .res 2 ; Y2 value of bounding box
+Buttons: .res 1 ; Button mask
+
+; Temporary value used in the int handler
+
+Temp: .res 1
+
+; Default values for above variables
+
+.rodata
+
+.proc DefVars
+ .word SCREEN_HEIGHT/2 ; YPos
+ .word SCREEN_WIDTH/2 ; XPos
+ .word 0 ; XMin
+ .word 0 ; YMin
+ .word SCREEN_WIDTH ; XMax
+ .word SCREEN_HEIGHT ; YMax
+ .byte 0 ; Buttons
+.endproc
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an MOUSE_ERR_xx code in a/x.
+
+INSTALL:
+
+; Initialize variables. Just copy the default stuff over
+
+ ldx #.sizeof(DefVars)-1
+@L1: lda DefVars,x
+ sta Vars,x
+ dex
+ bpl @L1
+
+; Be sure the mouse cursor is invisible and at the default location. We
+; need to do that here, because our mouse interrupt handler doesn't set the
+; mouse position if it hasn't changed.
+
+ sei
+ jsr CHIDE
+ lda XPos
+ ldx XPos+1
+ jsr CMOVEX
+ lda YPos
+ ldx YPos+1
+ jsr CMOVEY
+ cli
+
+; Done, return zero (= MOUSE_ERR_OK)
+
+ ldx #$00
+ txa
+ rts
+
+;----------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+
+UNINSTALL = HIDE ; Hide cursor on exit
+
+;----------------------------------------------------------------------------
+; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently visible and should get hidden. For most drivers,
+; no special action is required besides hiding the mouse cursor.
+; No return code required.
+
+HIDE: sei
+ jsr CHIDE
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently hidden and should become visible. For most drivers,
+; no special action is required besides enabling the mouse cursor.
+; No return code required.
+
+SHOW: sei
+ jsr CSHOW
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SETBOX: Set the mouse bounding box. The parameters are passed as they come
+; from the C program, that is, a pointer to a mouse_box struct in a/x.
+; No checks are done if the mouse is currently inside the box, this is the job
+; of the caller. It is not necessary to validate the parameters, trust the
+; caller and save some code here. No return code required.
+
+SETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda (ptr1),y
+ sta XMin,y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; GETBOX: Return the mouse bounding box. The parameters are passed as they
+; come from the C program, that is, a pointer to a mouse_box struct in a/x.
+
+GETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda XMin,y
+ sta (ptr1),y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; MOVE: Move the mouse to a new position. The position is passed as it comes
+; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
+; remove the parameter from the stack on return.
+; No checks are done if the new position is valid (within the bounding box or
+; the screen). No return code required.
+;
+
+MOVE: sei ; No interrupts
+
+ sta YPos
+ stx YPos+1 ; New Y position
+ jsr CMOVEY ; Set it
+
+ ldy #$01
+ lda (sp),y
+ sta XPos+1
+ tax
+ dey
+ lda (sp),y
+ sta XPos ; New X position
+
+ jsr CMOVEX ; Move the cursor
+
+ cli ; Allow interrupts
+ rts
+
+;----------------------------------------------------------------------------
+; BUTTONS: Return the button mask in a/x.
+
+BUTTONS:
+ lda Buttons
+ ldx #$00
+ rts
+
+;----------------------------------------------------------------------------
+; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
+; No return code required.
+
+POS: ldy #MOUSE_POS::XCOORD ; Structure offset
+
+ sei ; Disable interrupts
+ lda XPos ; Transfer the position
+ sta (ptr1),y
+ lda XPos+1
+ iny
+ sta (ptr1),y
+ lda YPos
+ iny
+ sta (ptr1),y
+ lda YPos+1
+ cli ; Enable interrupts
+
+ iny
+ sta (ptr1),y ; Store last byte
+
+ rts ; Done
+
+;----------------------------------------------------------------------------
+; INFO: Returns mouse position and current button mask in the MOUSE_INFO
+; struct pointed to by ptr1. No return code required.
+;
+; We're cheating here to keep the code smaller: The first fields of the
+; mouse_info struct are identical to the mouse_pos struct, so we will just
+; call _mouse_pos to initialize the struct pointer and fill the position
+; fields.
+
+INFO: jsr POS
+
+; Fill in the button state
+
+ lda Buttons
+ ldy #MOUSE_INFO::BUTTONS
+ sta (ptr1),y
+
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>MOUSE_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
+; (so be careful).
+;
+
+IRQ: lda #$7F
+ sta CIA1_PRA
+ lda CIA1_PRB ; Read port #1
+ and #%00001100
+ eor #%00001100 ; Make all bits active high
+ asl
+ sta Buttons
+ lsr
+ lsr
+ lsr
+ and #%00000001
+ ora Buttons
+ sta Buttons
+ ldx #%01000000
+ stx CIA1_PRA
+ ldy #0
+: dey
+ bne :-
+ ldx SID_ADConv1
+ stx XPos
+ ldx SID_ADConv2
+ stx YPos
+
+ lda #$FF
+ tax
+ bne @AddX ; Branch always
+ lda #$01
+ ldx #$00
+
+; Calculate the new X coordinate (--> a/y)
+
+@AddX: add XPos
+ tay ; Remember low byte
+ txa
+ adc XPos+1
+ tax
+
+; Limit the X coordinate to the bounding box
+
+ cpy XMin
+ sbc XMin+1
+ bpl @L1
+ ldy XMin
+ ldx XMin+1
+ jmp @L2
+@L1: txa
+
+ cpy XMax
+ sbc XMax+1
+ bmi @L2
+ ldy XMax
+ ldx XMax+1
+@L2: sty XPos
+ stx XPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jsr CMOVEX
+
+ lda #$FF
+ tax
+ bne @AddY
+@Down: lda #$01
+ ldx #$00
+
+; Calculate the new Y coordinate (--> a/y)
+
+@AddY: add YPos
+ tay ; Remember low byte
+ txa
+ adc YPos+1
+ tax
+
+; Limit the Y coordinate to the bounding box
+
+ cpy YMin
+ sbc YMin+1
+ bpl @L3
+ ldy YMin
+ ldx YMin+1
+ jmp @L4
+@L3: txa
+
+ cpy YMax
+ sbc YMax+1
+ bmi @L4
+ ldy YMax
+ ldx YMax+1
+@L4: sty YPos
+ stx YPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jmp CMOVEY
--- /dev/null
+;
+; Serial driver for the C128 using a Swiftlink or Turbo-232 cartridge.
+;
+; Ullrich von Bassewitz, 2003-04-18
+;
+; The driver is based on the cc65 rs232 module, which in turn is based on
+; Craig Bruce device driver for the Switftlink/Turbo-232.
+;
+; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
+;
+; This software is Public Domain. It is in Buddy assembler format.
+;
+; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
+; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
+; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
+; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
+;
+; The code assumes that the kernal + I/O are in context. On the C128, call
+; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
+; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
+; interrupt handling assumes that the 65816 is in 6502-emulation mode.
+;
+
+ .include "zeropage.inc"
+ .include "ser-kernel.inc"
+ .include "ser-error.inc"
+ .include "c128.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $73, $65, $72 ; "ser"
+ .byte SER_API_VERSION ; Serial API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word OPEN
+ .word CLOSE
+ .word GET
+ .word PUT
+ .word STATUS
+ .word IOCTL
+ .word IRQ
+
+;----------------------------------------------------------------------------
+; I/O definitions
+
+ACIA = $DE00
+ACIA_DATA = ACIA+0 ; Data register
+ACIA_STATUS = ACIA+1 ; Status register
+ACIA_CMD = ACIA+2 ; Command register
+ACIA_CTRL = ACIA+3 ; Control register
+
+;----------------------------------------------------------------------------
+;
+; Global variables
+;
+
+; We reuse the RS232 zero page variables for the driver, since the ROM
+; routines cannot be used together with this driver (may also use $A0F
+; and following in case of problems).
+RecvHead := $A7 ; Head of receive buffer
+RecvTail := $A8 ; Tail of receive buffer
+RecvFreeCnt := $A9 ; Number of bytes in receive buffer
+SendHead := $AA ; Head of send buffer
+SendTail := $AB ; Tail of send buffer
+SendFreeCnt := $B4 ; Number of bytes free in send buffer
+Stopped := $B5 ; Flow-stopped flag
+RtsOff := $B6 ;
+
+; Send and receive buffers: 256 bytes each
+RecvBuf := $0C00 ; Use the ROM buffers
+SendBuf := $0D00
+
+.rodata
+
+; Tables used to translate RS232 params into register values
+
+BaudTable: ; bit7 = 1 means setting is invalid
+ .byte $FF ; SER_BAUD_45_5
+ .byte $FF ; SER_BAUD_50
+ .byte $FF ; SER_BAUD_75
+ .byte $FF ; SER_BAUD_110
+ .byte $FF ; SER_BAUD_134_5
+ .byte $02 ; SER_BAUD_150
+ .byte $05 ; SER_BAUD_300
+ .byte $06 ; SER_BAUD_600
+ .byte $07 ; SER_BAUD_1200
+ .byte $FF ; SER_BAUD_1800
+ .byte $08 ; SER_BAUD_2400
+ .byte $09 ; SER_BAUD_3600
+ .byte $0A ; SER_BAUD_4800
+ .byte $0B ; SER_BAUD_7200
+ .byte $0C ; SER_BAUD_9600
+ .byte $0E ; SER_BAUD_19200
+ .byte $0F ; SER_BAUD_38400
+ .byte $FF ; SER_BAUD_57600
+ .byte $FF ; SER_BAUD_115200
+ .byte $FF ; SER_BAUD_230400
+
+BitTable:
+ .byte $60 ; SER_BITS_5
+ .byte $40 ; SER_BITS_6
+ .byte $20 ; SER_BITS_7
+ .byte $00 ; SER_BITS_8
+
+StopTable:
+ .byte $00 ; SER_STOP_1
+ .byte $80 ; SER_STOP_2
+
+ParityTable:
+ .byte $00 ; SER_PAR_NONE
+ .byte $20 ; SER_PAR_ODD
+ .byte $60 ; SER_PAR_EVEN
+ .byte $A0 ; SER_PAR_MARK
+ .byte $E0 ; SER_PAR_SPACE
+
+.code
+
+;----------------------------------------------------------------------------
+; Interrupt stub that is copied into low RAM. The startup code uses a special
+; memory configuration with just kernal and I/O enabled (anything else is RAM).
+; The NMI handler in ROM will switch back to a configuration where just the
+; low 16K RAM are accessible. So we have to copy a smal piece of code into
+; low RAM that enables the cc65 configuration and then jumps to the real NMI
+; handler.
+
+NmiStubOrig := *
+
+.org $1150 ; BASIC graphics area
+.proc NmiStub
+
+ lda #MMU_CFG_CC65 ; Bank 0 with kernal ROM...
+ sta MMU_CR ; ...enable
+ jsr NmiHandler ; Call the actual NMI handler
+ lda #$00 ; Get ROM config...
+ sta MMU_CR ; ...and enable it
+Vector := *+1
+ .byte $4C ; Jump to the saved IRQ vector
+
+.endproc
+.reloc
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an SER_ERR_xx code in a/x.
+
+INSTALL:
+
+; Deactivate DTR and disable 6551 interrupts
+
+ lda #%00001010
+ sta ACIA_CMD
+
+; Copy the NMI stub into low memory
+
+ ldy #.sizeof (NmiStub)-1
+@L1: lda NmiStubOrig,y
+ sta NmiStub,y
+ dey
+ bpl @L1
+
+; Set up the nmi vector
+
+ lda NMIVec
+ ldy NMIVec+1
+ sta NmiStub::Vector+0
+ sty NmiStub::Vector+1
+ lda #<NmiStub
+ ldy #>NmiStub
+SetNMI: sta NMIVec
+ sty NMIVec+1
+
+; Done, return an error code
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+;----------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Must return an SER_ERR_xx code in a/x.
+
+UNINSTALL:
+
+; Stop interrupts, drop DTR
+
+ lda #%00001010
+ sta ACIA_CMD
+
+; Restore NMI vector and return OK
+
+ lda NmiStub::Vector+0
+ ldy NmiStub::Vector+1
+ jmp SetNMI
+
+;----------------------------------------------------------------------------
+; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+OPEN:
+
+; Check if the handshake setting is valid
+
+ ldy #SER_PARAMS::HANDSHAKE ; Handshake
+ lda (ptr1),y
+ cmp #SER_HS_HW ; This is all we support
+ bne InvParam
+
+; Initialize buffers
+
+ jsr InitBuffers
+
+; Set the value for the control register, which contains stop bits, word
+; length and the baud rate.
+
+ ldy #SER_PARAMS::BAUDRATE
+ lda (ptr1),y ; Baudrate index
+ tay
+ lda BaudTable,y ; Get 6551 value
+ bmi InvBaud ; Branch if rate not supported
+ sta tmp1
+
+ ldy #SER_PARAMS::DATABITS ; Databits
+ lda (ptr1),y
+ tay
+ lda BitTable,y
+ ora tmp1
+ sta tmp1
+
+ ldy #SER_PARAMS::STOPBITS ; Stopbits
+ lda (ptr1),y
+ tay
+ lda StopTable,y
+ ora tmp1
+ ora #%00010000 ; Receiver clock source = baudrate
+ sta ACIA_CTRL
+
+; Set the value for the command register. We remember the base value in
+; RtsOff, since we will have to manipulate ACIA_CMD often.
+
+ ldy #SER_PARAMS::PARITY ; Parity
+ lda (ptr1),y
+ tay
+ lda ParityTable,y
+ ora #%00000001 ; DTR active
+ sta RtsOff
+ ora #%00001000 ; Enable receive interrupts
+ sta ACIA_CMD
+
+; Done
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+; Invalid parameter
+
+InvParam:
+ lda #<SER_ERR_INIT_FAILED
+ ldx #>SER_ERR_INIT_FAILED
+ rts
+
+; Baud rate not available
+
+InvBaud:
+ lda #<SER_ERR_BAUD_UNAVAIL
+ ldx #>SER_ERR_BAUD_UNAVAIL
+ rts
+
+;----------------------------------------------------------------------------
+; CLOSE: Close the port, disable interrupts and flush the buffer. Called
+; without parameters. Must return an error code in a/x.
+;
+
+CLOSE:
+
+; Stop interrupts, drop DTR
+
+ lda #%00001010
+ sta ACIA_CMD
+
+; Initalize buffers. Returns zero in a
+
+ jsr InitBuffers
+
+; Return OK
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+;----------------------------------------------------------------------------
+; GET: Will fetch a character from the receive buffer and store it into the
+; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; return.
+;
+
+GET: ldx SendFreeCnt ; Send data if necessary
+ inx ; X == $FF?
+ beq @L1
+ lda #$00
+ jsr TryToSend
+
+; Check for buffer empty
+
+@L1: lda RecvFreeCnt ; (25)
+ cmp #$ff
+ bne @L2
+ lda #<SER_ERR_NO_DATA
+ ldx #>SER_ERR_NO_DATA
+ rts
+
+; Check for flow stopped & enough free: release flow control
+
+@L2: ldx Stopped ; (34)
+ beq @L3
+ cmp #63
+ bcc @L3
+ lda #$00
+ sta Stopped
+ lda RtsOff
+ ora #%00001000
+ sta ACIA_CMD
+
+; Get byte from buffer
+
+@L3: ldx RecvHead ; (41)
+ lda RecvBuf,x
+ inc RecvHead
+ inc RecvFreeCnt
+ ldx #$00 ; (59)
+ sta (ptr1,x)
+ txa ; Return code = 0
+ rts
+
+;----------------------------------------------------------------------------
+; PUT: Output character in A.
+; Must return an error code in a/x.
+;
+
+PUT:
+
+; Try to send
+
+ ldx SendFreeCnt
+ inx ; X = $ff?
+ beq @L2
+ pha
+ lda #$00
+ jsr TryToSend
+ pla
+
+; Put byte into send buffer & send
+
+@L2: ldx SendFreeCnt
+ bne @L3
+ lda #<SER_ERR_OVERFLOW ; X is already zero
+ rts
+
+@L3: ldx SendTail
+ sta SendBuf,x
+ inc SendTail
+ dec SendFreeCnt
+ lda #$ff
+ jsr TryToSend
+ lda #<SER_ERR_OK
+ tax
+ rts
+
+;----------------------------------------------------------------------------
+; STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an error code in a/x.
+;
+
+STATUS: lda ACIA_STATUS
+ ldx #0
+ sta (ptr1,x)
+ txa ; SER_ERR_OK
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>SER_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Not used on the C128
+;
+
+IRQ = $0000
+
+;----------------------------------------------------------------------------
+;
+; NMI handler
+; C128 NMI overhead=76 cycles: int=7, maxLatency=6, ROMenter=33, ROMexit=30
+; C64 NMI overhead=76 cycles: int=7, maxLatency=6, ROMenter=34, ROMexit=29
+;
+; timing: normal=76+43+9=128 cycles, assertFlow=76+52+9=137 cycles
+;
+; C128 @ 115.2k: 177 cycles avail (fast)
+; C64 @ 57.6k: 177 cycles avail, worstAvail=177-43? = 134
+; SCPU @ 230.4k: 868 cycles avail: for a joke!
+;
+; Note: Because of the C128 banking, a small stub has to go into low memory,
+; since the ROM NMI entry point switches to a configuration, where only the
+; low 16K of RAM are visible. The entry code switches into the standard cc65
+; configuration (I/O + 16K kernal) and then jumps here. Registers are already
+; saved by the ROM code.
+
+NmiHandler:
+ lda ACIA_STATUS ;(4) ;status ;check for byte received
+ and #$08 ;(2)
+ beq @L9 ;(2*)
+ cld
+ lda ACIA_DATA ;(4) data ;get byte and put into receive buffer
+ ldy RecvTail ;(4)
+ ldx RecvFreeCnt ;(4)
+ beq @L9 ;(2*) Jump if no space in receive buffer
+ sta RecvBuf,y ;(5)
+ inc RecvTail ;(6)
+ dec RecvFreeCnt ;(6)
+ cpx #33 ;(2) check for buffer space low
+ bcc @L2 ;(2*)
+ rts
+
+; Assert flow control
+
+@L2: lda RtsOff ;(3) assert flow control if buffer space too low
+ sta ACIA_CMD ;(4) command
+ sta Stopped ;(3)
+@L9: rts
+
+;----------------------------------------------------------------------------
+; Try to send a byte. Internal routine. A = TryHard
+
+.proc TryToSend
+
+ sta tmp1 ; Remember tryHard flag
+@L0: lda SendFreeCnt
+ cmp #$ff
+ beq @L3 ; Bail out
+
+; Check for flow stopped
+
+@L1: lda Stopped
+ bne @L3 ; Bail out
+
+; Check that swiftlink is ready to send
+
+@L2: lda ACIA_STATUS
+ and #$10
+ bne @L4
+ bit tmp1 ;keep trying if must try hard
+ bmi @L0
+@L3: rts
+
+; Send byte and try again
+
+@L4: ldx SendHead
+ lda SendBuf,x
+ sta ACIA_DATA
+ inc SendHead
+ inc SendFreeCnt
+ jmp @L0
+
+.endproc
+
+
+;----------------------------------------------------------------------------
+; Initialize buffers
+
+InitBuffers:
+ ldx #0
+ stx Stopped
+ stx RecvHead
+ stx RecvTail
+ stx SendHead
+ stx SendTail
+ dex ; X = 255
+ stx RecvFreeCnt
+ stx SendFreeCnt
+ rts
+
+
--- /dev/null
+;
+; Graphics driver for the 640x200x2 mode on the C128 VDC
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 23.12.2002
+; 2004-04-04, Greg King
+;
+; NOTES:
+; For any smart monkey that will try to optimize this: PLEASE do tests on
+; real VDC, not only VICE.
+;
+; Only DONE routine contains C128-mode specific stuff, everything else will
+; work in C64-mode of C128 (C64 needs full VDC init then).
+;
+; With special initialization and CALC we can get 320x200 double-pixel mode.
+;
+; Color translation values for BROWN and GRAY3 are obviously wrong, they
+; could be replaced by equiv. of ORANGE and GRAY2 but this would give only
+; 14 of 16 colors available.
+;
+; Register 25 ($19) is said to require different value for VDC v1, but I
+; couldn't find what it should be.
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Constants
+
+VDC_ADDR_REG = $D600 ; VDC address
+VDC_DATA_REG = $D601 ; VDC data
+
+VDC_DSP_HI = 12 ; registers used
+VDC_DSP_LO = 13
+VDC_DATA_HI = 18
+VDC_DATA_LO = 19
+VDC_VSCROLL = 24
+VDC_HSCROLL = 25
+VDC_COLORS = 26
+VDC_CSET = 28
+VDC_COUNT = 30
+VDC_DATA = 31
+
+; ------------------------------------------------------------------------
+; 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 640 ; X resolution
+yres: .word 200 ; Y resolution
+ .byte 2 ; Number of drawing colors
+pages: .byte 1 ; Number of screens available
+ .byte 8 ; System font X size
+ .byte 8 ; System font Y size
+ .word $006A ; Aspect ratio (based on 4/3 display)
+ .byte 0 ; TGI driver flags
+
+; 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 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
+
+ADDR = tmp1
+TEMP = tmp3
+TEMP2 = tmp4 ; HORLINE
+TEMP3 = sreg ; HORLINE
+
+; Absolute variables used in the code
+
+.bss
+
+SCRBASE: .res 1 ; High byte of screen base
+
+ERROR: .res 1 ; Error code
+PALETTE: .res 2 ; The current palette
+
+BITMASK: .res 1 ; $00 = clear, $FF = set pixels
+
+OLDCOLOR: .res 1 ; colors before entering gfx mode
+
+; Text output stuff
+TEXTMAGX: .res 1
+TEXTMAGY: .res 1
+TEXTDIR: .res 1
+
+; Constants and tables
+
+.rodata
+
+DEFPALETTE: .byte $00, $0f ; White on black
+PALETTESIZE = * - DEFPALETTE
+
+BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01
+
+BITMASKL: .byte %11111111, %01111111, %00111111, %00011111
+ .byte %00001111, %00000111, %00000011, %00000001
+
+BITMASKR: .byte %10000000, %11000000, %11100000, %11110000
+ .byte %11111000, %11111100, %11111110, %11111111
+
+; color translation table (indexed by VIC color)
+COLTRANS: .byte $00, $0f, $08, $06, $0a, $04, $02, $0c
+ .byte $0d, $0b, $09, $01, $0e, $05, $03, $07
+ ; colors BROWN and GRAY3 are wrong
+
+; VDC initialization table (reg),(val),...,$ff
+InitVDCTab:
+ .byte VDC_DSP_HI, 0 ; viewpage 0 as default
+ .byte VDC_DSP_LO, 0
+ .byte VDC_HSCROLL, $87
+ .byte $ff
+
+SCN80CLR: .byte 27,88,147,27,88,0
+
+.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:
+ ; check for VDC version and update register $19 value
+
+ ; check for VDC ram size and update number of available screens
+
+ ldx #VDC_CSET ; determine size of RAM...
+ jsr VDCReadReg
+ sta tmp1
+ ora #%00010000
+ jsr VDCWriteReg ; turn on 64k
+
+ jsr settestadr1 ; save original value of test byte
+ jsr VDCReadByte
+ sta tmp2
+
+ lda #$55 ; write $55 here
+ ldy #ptr1
+ jsr test64k ; read it here and there
+ lda #$aa ; write $aa here
+ ldy #ptr2
+ jsr test64k ; read it here and there
+
+ jsr settestadr1
+ lda tmp2
+ jsr VDCWriteByte ; restore original value of test byte
+
+ lda ptr1 ; do bytes match?
+ cmp ptr1+1
+ bne @have64k
+ lda ptr2
+ cmp ptr2+1
+ bne @have64k
+
+ ldx #VDC_CSET
+ lda tmp1
+ jsr VDCWriteReg ; restore 16/64k flag
+ jmp @endok ; and leave default values for 16k
+
+@have64k:
+ lda #4
+ sta pages
+@endok:
+ lda #0
+ sta SCRBASE ; draw page 0 as default
+ rts
+
+test64k:
+ sta tmp1
+ sty ptr3
+ lda #0
+ sta ptr3+1
+ jsr settestadr1
+ lda tmp1
+ jsr VDCWriteByte ; write $55
+ jsr settestadr1
+ jsr VDCReadByte ; read here
+ pha
+ jsr settestadr2
+ jsr VDCReadByte ; and there
+ ldy #1
+ sta (ptr3),y
+ pla
+ dey
+ sta (ptr3),y
+ rts
+
+settestadr1:
+ ldy #$02 ; test page 2 (here)
+ .byte $2c
+settestadr2:
+ ldy #$42 ; or page 64+2 (there)
+ lda #0
+ jmp VDCSetSourceAddr
+
+; ------------------------------------------------------------------------
+; 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:
+
+; Initialize variables
+
+@L1: ldx #$FF
+ stx BITMASK
+
+; Remeber current color value
+ ldx #VDC_COLORS
+ jsr VDCReadReg
+ sta OLDCOLOR
+
+; Switch into graphics mode (set view page 0)
+
+ ldy #0
+@L2: ldx InitVDCTab,y
+ bmi @L3
+ iny
+ lda InitVDCTab,y
+ jsr VDCWriteReg
+ iny
+ bne @L2
+@L3:
+
+; 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:
+ ; This part is C128-mode specific
+ jsr $e179 ; reload character set and setup VDC
+ jsr $ff62
+ lda $d7 ; in 80-columns?
+ bne @L01
+@L0: lda SCN80CLR,y
+ beq @L1
+ jsr $ffd2 ; print \xe,clr,\xe
+ iny
+ bne @L0
+@L01: lda #147
+ jsr $ffd2 ; print clr
+@L1: lda #0 ; restore view page
+ ldx #VDC_DSP_HI
+ jsr VDCWriteReg
+ lda OLDCOLOR
+ ldx #VDC_COLORS
+ jsr VDCWriteReg ; restore color (background)
+ lda #$47
+ ldx #VDC_HSCROLL
+ jmp VDCWriteReg ; switch to text screen
+
+; ------------------------------------------------------------------------
+; 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:
+ lda #0
+ ldy SCRBASE
+ jsr VDCSetSourceAddr
+ lda #0
+ ldx #VDC_VSCROLL
+ jsr VDCWriteReg ; set fill mode
+ lda #0
+ jsr VDCWriteByte ; put 1rst byte (fill value)
+ ldy #62 ; 62 times
+ lda #0 ; 256 bytes
+ ldx #VDC_COUNT
+@L1: jsr VDCWriteReg
+ dey
+ bne @L1
+ lda #127
+ jmp VDCWriteReg ; 1+62*256+127=16000=(640*256)/8
+
+; ------------------------------------------------------------------------
+; 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:
+ clc
+ ror
+ ror
+ ror
+ ldx #VDC_DSP_HI
+ jmp VDCWriteReg
+
+; ------------------------------------------------------------------------
+; 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:
+ clc
+ ror
+ ror
+ ror
+ sta SCRBASE
+ 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
+ beq @L1
+ lda #$FF
+@L1: sta BITMASK
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ ldy #PALETTESIZE - 1
+@L1: lda (ptr1),y ; Copy the palette
+ and #$0F ; Make a valid color
+ sta PALETTE,y
+ dey
+ bpl @L1
+
+; Get the color entries from the palette
+
+ ldy PALETTE+1 ; Foreground color
+ lda COLTRANS,y
+ asl a
+ asl a
+ asl a
+ asl a
+ ldy PALETTE ; Background color
+ ora COLTRANS,y
+
+ ldx #VDC_COLORS
+ jsr VDCWriteReg
+ lda #TGI_ERR_OK ; Clear error code
+ 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:
+ lda #<PALETTE
+ ldx #>PALETTE
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ jsr CALC ; Calculate coordinates
+
+ stx TEMP
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ ldx TEMP
+
+ sta TEMP
+ eor BITMASK
+ and BITTAB,X
+ eor TEMP
+ pha
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ pla
+ jsr VDCWriteByte
+
+@L9: 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:
+ jsr CALC ; Calculate coordinates
+
+ stx TEMP ; preserve X
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ ldx TEMP
+
+ ldy #$00
+ and BITTAB,X
+ beq @L1
+ iny
+
+@L1: tya ; Get color value into A
+ ldx #$00 ; Clear high byte
+ 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
+ bne HORLINE
+ inc Y2+1
+
+; Original code for a horizontal line
+
+HORLINE:
+ lda X1
+ pha
+ lda X1+1
+ pha
+ jsr CALC ; get data for LEFT
+ lda BITMASKL,x ; remember left address and bitmask
+ pha
+ lda ADDR
+ pha
+ lda ADDR+1
+ pha
+
+ lda X2
+ sta X1
+ lda X2+1
+ sta X1+1
+ jsr CALC ; get data for RIGHT
+ lda BITMASKR,x
+ sta TEMP3
+
+ pla ; recall data for LEFT
+ sta X1+1
+ pla
+ sta X1 ; put left address into X1
+ pla
+
+ cmp #%11111111 ; if left bit <> 0
+ beq @L1
+ sta TEMP2 ; do left byte only...
+ lda X1
+ ldy X1+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ sta TEMP
+ eor BITMASK
+ and TEMP2
+ eor TEMP
+ pha
+ lda X1
+ ldy X1+1
+ jsr VDCSetSourceAddr
+ pla
+ jsr VDCWriteByte
+ inc X1 ; ... and proceed
+ bne @L1
+ inc X1+1
+
+ ; do right byte (if Y2=0 ++ADDR and skip)
+@L1: lda TEMP3
+ cmp #%11111111 ; if right bit <> 7
+ bne @L11
+ inc ADDR ; right bit = 7 - the next one is the last
+ bne @L10
+ inc ADDR+1
+@L10: bne @L2
+
+@L11: lda ADDR ; do right byte only...
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ sta TEMP
+ eor BITMASK
+ and TEMP3
+ eor TEMP
+ pha
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ pla
+ jsr VDCWriteByte
+
+@L2: ; do the fill in the middle
+ lda ADDR ; calculate offset in full bytes
+ sec
+ sbc X1
+ beq @L3 ; if equal - there are no more bytes
+ sta ADDR
+
+ lda X1 ; setup for the left side
+ ldy X1+1
+ jsr VDCSetSourceAddr
+ lda BITMASK ; get color
+ jsr VDCWriteByte ; put 1st value
+ ldx ADDR
+ dex
+ beq @L3 ; 1 byte already written
+
+ stx ADDR ; if there are more bytes - fill them...
+ ldx #VDC_VSCROLL
+ lda #0
+ jsr VDCWriteReg ; setup for fill
+ ldx #VDC_COUNT
+ lda ADDR
+ jsr VDCWriteReg ; ... fill them NOW!
+
+@L3: pla
+ sta X1+1
+ pla
+ sta X1
+
+; End of horizontal line code
+
+ inc Y1
+ bne @L4
+ inc Y1+1
+@L4: lda Y1
+ cmp Y2
+ bne @L5
+ lda Y1+1
+ cmp Y2+1
+ bne @L5
+ rts
+
+@L5: jmp HORLINE
+
+
+; ------------------------------------------------------------------------
+; 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
+ 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:
+ rts
+
+; ------------------------------------------------------------------------
+; Calculate all variables to plot the pixel at X1/Y1.
+;------------------------
+;< X1,Y1 - pixel
+;> ADDR - address of card
+;> X - bit number (X1 & 7)
+CALC:
+ lda Y1+1
+ sta ADDR+1
+ lda Y1
+ asl
+ rol ADDR+1
+ asl
+ rol ADDR+1 ; Y*4
+ clc
+ adc Y1
+ sta ADDR
+ lda Y1+1
+ adc ADDR+1
+ sta ADDR+1 ; Y*4+Y=Y*5
+ lda ADDR
+ asl
+ rol ADDR+1
+ asl
+ rol ADDR+1
+ asl
+ rol ADDR+1
+ asl
+ rol ADDR+1
+ sta ADDR ; Y*5*16=Y*80
+ lda X1+1
+ sta TEMP
+ lda X1
+ lsr TEMP
+ ror
+ lsr TEMP
+ ror
+ lsr TEMP
+ ror
+ clc
+ adc ADDR
+ sta ADDR
+ lda ADDR+1 ; ADDR = Y*80+x/8
+ adc TEMP
+ sta ADDR+1
+ lda ADDR+1
+ adc SCRBASE
+ sta ADDR+1
+ lda X1
+ and #7
+ tax
+ rts
+
+;-------------
+; VDC helpers
+
+VDCSetSourceAddr:
+ pha
+ tya
+ ldx #VDC_DATA_HI
+ jsr VDCWriteReg
+ pla
+ ldx #VDC_DATA_LO
+ bne VDCWriteReg
+
+VDCReadByte:
+ ldx #VDC_DATA
+VDCReadReg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda VDC_DATA_REG
+ rts
+
+VDCWriteByte:
+ ldx #VDC_DATA
+VDCWriteReg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ sta VDC_DATA_REG
+ rts
+
+; ------------------------------------------------------------------------
+
+ .include "../../tgi/tgidrv_line.inc"
--- /dev/null
+;
+; Graphics driver for the 640x480x2 mode on the C128 VDC 64k
+; (values for this mode based on Fred Bowen's document)
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 23.12.2002
+; 2004-04-04, Greg King
+;
+; NOTES:
+; For any smart monkey that will try to optimize this: PLEASE do tests on
+; real VDC, not only VICE.
+;
+; Only DONE routine contains C128-mode specific stuff, everything else will
+; work in C64-mode of C128 (C64 needs full VDC init then).
+;
+; With special initialization and CALC we can get 320x200 double-pixel mode.
+;
+; Color translation values for BROWN and GRAY3 are obviously wrong, they
+; could be replaced by equiv. of ORANGE and GRAY2 but this would give only
+; 14 of 16 colors available.
+;
+; Register 25 ($19) is said to require different value for VDC v1, but I
+; couldn't find what it should be.
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Constants
+
+VDC_ADDR_REG = $D600 ; VDC address
+VDC_DATA_REG = $D601 ; VDC data
+
+VDC_DSP_HI = 12 ; registers used
+VDC_DSP_LO = 13
+VDC_DATA_HI = 18
+VDC_DATA_LO = 19
+VDC_VSCROLL = 24
+VDC_HSCROLL = 25
+VDC_COLORS = 26
+VDC_CSET = 28
+VDC_COUNT = 30
+VDC_DATA = 31
+
+; ------------------------------------------------------------------------
+; 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 640 ; X resolution
+yres: .word 480 ; Y resolution
+ .byte 2 ; Number of drawing colors
+pages: .byte 0 ; Number of screens available
+ .byte 8 ; System font X size
+ .byte 8 ; System font Y size
+ .word $0100 ; Aspect ratio (based on 4/3 display)
+ .byte 0 ; TGI driver flags
+
+; 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 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
+
+ADDR = tmp1
+TEMP = tmp3
+TEMP2 = tmp4 ; HORLINE
+TEMP3 = sreg ; HORLINE
+
+; Absolute variables used in the code
+
+.bss
+
+ERROR: .res 1 ; Error code
+PALETTE: .res 2 ; The current palette
+
+BITMASK: .res 1 ; $00 = clear, $FF = set pixels
+
+OLDCOLOR: .res 1 ; colors before entering gfx mode
+
+; Text output stuff
+TEXTMAGX: .res 1
+TEXTMAGY: .res 1
+TEXTDIR: .res 1
+
+; Constants and tables
+
+.rodata
+
+DEFPALETTE: .byte $00, $0f ; White on black
+PALETTESIZE = * - DEFPALETTE
+
+BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01
+
+BITMASKL: .byte %11111111, %01111111, %00111111, %00011111
+ .byte %00001111, %00000111, %00000011, %00000001
+
+BITMASKR: .byte %10000000, %11000000, %11100000, %11110000
+ .byte %11111000, %11111100, %11111110, %11111111
+
+; color translation table (indexed by VIC color)
+COLTRANS: .byte $00, $0f, $08, $06, $0a, $04, $02, $0c
+ .byte $0d, $0b, $09, $01, $0e, $05, $03, $07
+ ; colors BROWN and GRAY3 are wrong
+
+; VDC initialization table (reg),(val),...,$ff
+InitVDCTab:
+ .byte VDC_DSP_HI, 0 ; viewpage 0 as default
+ .byte VDC_DSP_LO, 0
+ .byte VDC_HSCROLL, $87
+ .byte 2, $66
+ .byte 4, $4c
+ .byte 5, $06
+ .byte 6, $4c
+ .byte 7, $47
+ .byte 8, $03
+ .byte 9, $06
+ .byte 27, $00
+ .byte $ff
+
+SCN80CLR: .byte 27,88,147,27,88,0
+
+.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:
+ ; check for VDC version and update register $19 value
+
+ ; check for VDC ram size and update number of available screens
+
+ ldx #VDC_CSET ; determine size of RAM...
+ jsr VDCReadReg
+ sta tmp1
+ ora #%00010000
+ jsr VDCWriteReg ; turn on 64k
+
+ jsr settestadr1 ; save original value of test byte
+ jsr VDCReadByte
+ sta tmp2
+
+ lda #$55 ; write $55 here
+ ldy #ptr1
+ jsr test64k ; read it here and there
+ lda #$aa ; write $aa here
+ ldy #ptr2
+ jsr test64k ; read it here and there
+
+ jsr settestadr1
+ lda tmp2
+ jsr VDCWriteByte ; restore original value of test byte
+
+ lda ptr1 ; do bytes match?
+ cmp ptr1+1
+ bne @have64k
+ lda ptr2
+ cmp ptr2+1
+ bne @have64k
+
+ ldx #VDC_CSET
+ lda tmp1
+ jsr VDCWriteReg ; restore 16/64k flag
+ jmp @endok ; and leave default values for 16k
+
+@have64k:
+ lda #1
+ sta pages
+@endok:
+ rts
+
+test64k:
+ sta tmp1
+ sty ptr3
+ lda #0
+ sta ptr3+1
+ jsr settestadr1
+ lda tmp1
+ jsr VDCWriteByte ; write $55
+ jsr settestadr1
+ jsr VDCReadByte ; read here
+ pha
+ jsr settestadr2
+ jsr VDCReadByte ; and there
+ ldy #1
+ sta (ptr3),y
+ pla
+ dey
+ sta (ptr3),y
+ rts
+
+settestadr1:
+ ldy #$02 ; test page 2 (here)
+ .byte $2c
+settestadr2:
+ ldy #$42 ; or page 64+2 (there)
+ lda #0
+ jmp VDCSetSourceAddr
+
+; ------------------------------------------------------------------------
+; 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:
+ lda pages ; is there enough memory?
+ bne @L1 ; Jump if there is one screen
+ lda #TGI_ERR_INV_MODE ; Error
+ bne @L9
+
+; Initialize variables
+
+@L1: ldx #$FF
+ stx BITMASK
+
+; Remeber current color value
+ ldx #VDC_COLORS
+ jsr VDCReadReg
+ sta OLDCOLOR
+
+; Switch into graphics mode (set view page 0)
+
+ ldy #0
+@L2: ldx InitVDCTab,y
+ bmi @L3
+ iny
+ lda InitVDCTab,y
+ jsr VDCWriteReg
+ iny
+ bne @L2
+@L3:
+
+; Done, reset the error code
+
+ lda #TGI_ERR_OK
+@L9: 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:
+ ; This part is C128-mode specific
+ jsr $e179 ; reload character set and setup VDC
+ jsr $ff62
+ lda $d7 ; in 80-columns?
+ bne @L01
+@L0: lda SCN80CLR,y
+ beq @L1
+ jsr $ffd2 ; print \xe,clr,\xe
+ iny
+ bne @L0
+@L01: lda #147
+ jsr $ffd2 ; print clr
+@L1: lda #0 ; restore view page
+ ldx #VDC_DSP_HI
+ jsr VDCWriteReg
+ lda OLDCOLOR
+ ldx #VDC_COLORS
+ jsr VDCWriteReg ; restore color (background)
+ lda #$47
+ ldx #VDC_HSCROLL
+ jmp VDCWriteReg ; switch to text screen
+
+; ------------------------------------------------------------------------
+; 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:
+ lda #0
+ tay
+ jsr VDCSetSourceAddr
+ lda #0
+ ldx #VDC_VSCROLL
+ jsr VDCWriteReg ; set fill mode
+ lda #0
+ jsr VDCWriteByte ; put 1rst byte (fill value)
+ ldy #159 ; 159 times
+ lda #0 ; 256 bytes
+ ldx #VDC_COUNT
+@L1: jsr VDCWriteReg
+ dey
+ bne @L1
+ 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:
+ 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:
+ 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
+ beq @L1
+ lda #$FF
+@L1: sta BITMASK
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ ldy #PALETTESIZE - 1
+@L1: lda (ptr1),y ; Copy the palette
+ and #$0F ; Make a valid color
+ sta PALETTE,y
+ dey
+ bpl @L1
+
+; Get the color entries from the palette
+
+ ldy PALETTE+1 ; Foreground color
+ lda COLTRANS,y
+ asl a
+ asl a
+ asl a
+ asl a
+ ldy PALETTE ; Background color
+ ora COLTRANS,y
+
+ ldx #VDC_COLORS
+ jsr VDCWriteReg
+ lda #TGI_ERR_OK ; Clear error code
+ 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:
+ lda #<PALETTE
+ ldx #>PALETTE
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ jsr CALC ; Calculate coordinates
+
+ stx TEMP
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ ldx TEMP
+
+ sta TEMP
+ eor BITMASK
+ and BITTAB,X
+ eor TEMP
+ pha
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ pla
+ jsr VDCWriteByte
+
+@L9: 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:
+ jsr CALC ; Calculate coordinates
+
+ stx TEMP ; preserve X
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ ldx TEMP
+
+ ldy #$00
+ and BITTAB,X
+ beq @L1
+ iny
+
+@L1: tya ; Get color value into A
+ ldx #$00 ; Clear high byte
+ 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
+ bne HORLINE
+ inc Y2+1
+
+; Original code for a horizontal line
+
+HORLINE:
+ lda X1
+ pha
+ lda X1+1
+ pha
+ jsr CALC ; get data for LEFT
+ lda BITMASKL,x ; remember left address and bitmask
+ pha
+ lda ADDR
+ pha
+ lda ADDR+1
+ pha
+
+ lda X2
+ sta X1
+ lda X2+1
+ sta X1+1
+ jsr CALC ; get data for RIGHT
+ lda BITMASKR,x
+ sta TEMP3
+
+ pla ; recall data for LEFT
+ sta X1+1
+ pla
+ sta X1 ; put left address into X1
+ pla
+
+ cmp #%11111111 ; if left bit <> 0
+ beq @L1
+ sta TEMP2 ; do left byte only...
+ lda X1
+ ldy X1+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ sta TEMP
+ eor BITMASK
+ and TEMP2
+ eor TEMP
+ pha
+ lda X1
+ ldy X1+1
+ jsr VDCSetSourceAddr
+ pla
+ jsr VDCWriteByte
+ inc X1 ; ... and proceed
+ bne @L1
+ inc X1+1
+
+ ; do right byte (if Y2=0 ++ADDR and skip)
+@L1: lda TEMP3
+ cmp #%11111111 ; if right bit <> 7
+ bne @L11
+ inc ADDR ; right bit = 7 - the next one is the last
+ bne @L10
+ inc ADDR+1
+@L10: bne @L2
+
+@L11: lda ADDR ; do right byte only...
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ jsr VDCReadByte
+ sta TEMP
+ eor BITMASK
+ and TEMP3
+ eor TEMP
+ pha
+ lda ADDR
+ ldy ADDR+1
+ jsr VDCSetSourceAddr
+ pla
+ jsr VDCWriteByte
+
+@L2: ; do the fill in the middle
+ lda ADDR ; calculate offset in full bytes
+ sec
+ sbc X1
+ beq @L3 ; if equal - there are no more bytes
+ sta ADDR
+
+ lda X1 ; setup for the left side
+ ldy X1+1
+ jsr VDCSetSourceAddr
+ lda BITMASK ; get color
+ jsr VDCWriteByte ; put 1st value
+ ldx ADDR
+ dex
+ beq @L3 ; 1 byte already written
+
+ stx ADDR ; if there are more bytes - fill them...
+ ldx #VDC_VSCROLL
+ lda #0
+ jsr VDCWriteReg ; setup for fill
+ ldx #VDC_COUNT
+ lda ADDR
+ jsr VDCWriteReg ; ... fill them NOW!
+
+@L3: pla
+ sta X1+1
+ pla
+ sta X1
+
+; End of horizontal line code
+
+ inc Y1
+ bne @L4
+ inc Y1+1
+@L4: lda Y1
+ cmp Y2
+ bne @L5
+ lda Y1+1
+ cmp Y2+1
+ bne @L5
+ rts
+
+@L5: jmp HORLINE
+
+
+; ------------------------------------------------------------------------
+; 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
+ 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:
+ rts
+
+; ------------------------------------------------------------------------
+; Calculate all variables to plot the pixel at X1/Y1.
+;------------------------
+;< X1,Y1 - pixel
+;> ADDR - address of card
+;> X - bit number (X1 & 7)
+CALC:
+ lda Y1
+ pha
+ lda Y1+1
+ pha
+ lsr
+ ror Y1 ; Y=Y/2
+ sta Y1+1
+ sta ADDR+1
+ lda Y1
+ asl
+ rol ADDR+1
+ asl
+ rol ADDR+1 ; Y*4
+ clc
+ adc Y1
+ sta ADDR
+ lda Y1+1
+ adc ADDR+1
+ sta ADDR+1 ; Y*4+Y=Y*5
+ lda ADDR
+ asl
+ rol ADDR+1
+ asl
+ rol ADDR+1
+ asl
+ rol ADDR+1
+ asl
+ rol ADDR+1
+ sta ADDR ; Y*5*16=Y*80
+ lda X1+1
+ sta TEMP
+ lda X1
+ lsr TEMP
+ ror
+ lsr TEMP
+ ror
+ lsr TEMP
+ ror
+ clc
+ adc ADDR
+ sta ADDR
+ lda ADDR+1 ; ADDR = Y*80+x/8
+ adc TEMP
+ sta ADDR+1
+ pla
+ sta Y1+1
+ pla
+ sta Y1
+ and #1
+ beq @even ; even line - no offset
+ lda ADDR
+ clc
+ adc #<21360
+ sta ADDR
+ lda ADDR+1
+ adc #>21360
+ sta ADDR+1 ; odd lines are 21360 bytes farther
+@even: lda X1
+ and #7
+ tax
+ rts
+
+;-------------
+; VDC helpers
+
+VDCSetSourceAddr:
+ pha
+ tya
+ ldx #VDC_DATA_HI
+ jsr VDCWriteReg
+ pla
+ ldx #VDC_DATA_LO
+ bne VDCWriteReg
+
+VDCReadByte:
+ ldx #VDC_DATA
+VDCReadReg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda VDC_DATA_REG
+ rts
+
+VDCWriteByte:
+ ldx #VDC_DATA
+VDCWriteReg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ sta VDC_DATA_REG
+ rts
+
+; ------------------------------------------------------------------------
+
+ .include "../../tgi/tgidrv_line.inc"
+++ /dev/null
-#
-# makefile for CC65 runtime library (C16)
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = c16
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I. -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- break.o \
- cgetc.o \
- clrscr.o \
- color.o \
- conio.o \
- cputc.o \
- crt0.o \
- devnum.o \
- get_tv.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- kclose.o \
- kernal.o \
- mainargs.o \
- randomize.o \
- revers.o \
- status.o \
- systime.o \
- sysuname.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS = c16-ram.emd
-
-JOYS = c16-stdjoy.joy
-
-SERS =
-
-TGIS =
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS)
+++ /dev/null
-;
-; Extended memory driver for the C16 hidden RAM. Driver works without
-; problems when statically linked.
-;
-; Ullrich von Bassewitz, 2003-12-15
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
- .include "plus4.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-BASE = $8000
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-pages: .res 1 ; Number of pages
-curpage: .res 1 ; Current page number
-window: .res 256 ; Memory "window"
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
-
-; Determine how much memory is available. We will use all memory above
-; $8000 up to MEMTOP
-
- sec
- jsr $FF99 ; MEMTOP: Get top memory into Y/X
- tya
- sub #>BASE ; Low 32 K are used
- bcc nomem
- beq nomem ; Offering zero pages is a bad idea
- sta pages
-
- ldx #$FF
- stx curpage ; Invalidate the current page
- inx ; X = 0
- txa ; A = X = EM_ERR_OK
- rts
-
-nomem: ldx #>EM_ERR_NO_DEVICE
- lda #<EM_ERR_NO_DEVICE
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pages
- ldx #$00 ; 128 pages max
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage ; Remember the new page
-
- add #>BASE
- sta ptr1+1
- ldy #$00
- sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
-; Transfer one page
-
- jsr transfer ; Transfer one page
-
-; Return the memory window
-
- lda #<window
- ldx #>window ; Return the window address
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage ; Get the current page
- bmi done ; Jump if no page mapped
-
- add #>BASE
- sta ptr2+1
- ldy #$00
- sty ptr2
-
- lda #<window
- sta ptr1
- lda #>window
- sta ptr1+1
-
-; Transfer one page. Y must be zero on entry. Because we bank out the
-; kernal, we will run the routine with interrupts disabled but leave
-; short breath times. Unroll the following loop to make it somewhat faster.
-
-transfer:
- sei
- sta ENABLE_RAM
-
- .repeat 8
- lda (ptr1),y
- sta (ptr2),y
- iny
- .endrepeat
-
- sta ENABLE_ROM
- cli
-
- bne transfer
-
-; Done
-
-done: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- add #>BASE
- sta ptr1+1 ; From
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; To
-
-common: ldy #EM_COPY::COUNT+1
- lda (ptr3),y ; Get number of pages
- beq @L2 ; Skip if no full pages
- sta tmp1
-
-; Copy full pages allowing interrupts after each page copied
-
- ldy #$00
-@L1: jsr transfer
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- tax
-
- sei ; Disable ints
- sta ENABLE_RAM ; Bank out the ROM
-
-; Transfer the bytes in the last page
-
- ldy #$00
-@L3: lda (ptr1),y
- sta (ptr2),y
- iny
- dex
- bne @L3
-
-; Restore the old memory configuration, allow interrupts
-
- sta ENABLE_ROM
- cli
-
-; Done
-
-@L4: rts
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO: sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr2
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- add #>BASE
- sta ptr2+1 ; To
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr1
- iny
- lda (ptr3),y
- sta ptr1+1 ; From
-
- jmp common
-
-
+++ /dev/null
-;
-; Standard joystick driver for the C16. May be used multiple times when linked
-; to the statically application.
-;
-; Ullrich von Bassewitz, 2002-12-21
-;
-
- .include "../plus4/plus4-stdjoy.s"
-
--- /dev/null
+;
+; Extended memory driver for the C16 hidden RAM. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2003-12-15
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+ .include "plus4.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BASE = $8000
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+pages: .res 1 ; Number of pages
+curpage: .res 1 ; Current page number
+window: .res 256 ; Memory "window"
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+
+; Determine how much memory is available. We will use all memory above
+; $8000 up to MEMTOP
+
+ sec
+ jsr $FF99 ; MEMTOP: Get top memory into Y/X
+ tya
+ sub #>BASE ; Low 32 K are used
+ bcc nomem
+ beq nomem ; Offering zero pages is a bad idea
+ sta pages
+
+ ldx #$FF
+ stx curpage ; Invalidate the current page
+ inx ; X = 0
+ txa ; A = X = EM_ERR_OK
+ rts
+
+nomem: ldx #>EM_ERR_NO_DEVICE
+ lda #<EM_ERR_NO_DEVICE
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pages
+ ldx #$00 ; 128 pages max
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage ; Remember the new page
+
+ add #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+; Transfer one page
+
+ jsr transfer ; Transfer one page
+
+; Return the memory window
+
+ lda #<window
+ ldx #>window ; Return the window address
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage ; Get the current page
+ bmi done ; Jump if no page mapped
+
+ add #>BASE
+ sta ptr2+1
+ ldy #$00
+ sty ptr2
+
+ lda #<window
+ sta ptr1
+ lda #>window
+ sta ptr1+1
+
+; Transfer one page. Y must be zero on entry. Because we bank out the
+; kernal, we will run the routine with interrupts disabled but leave
+; short breath times. Unroll the following loop to make it somewhat faster.
+
+transfer:
+ sei
+ sta ENABLE_RAM
+
+ .repeat 8
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+ .endrepeat
+
+ sta ENABLE_ROM
+ cli
+
+ bne transfer
+
+; Done
+
+done: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ add #>BASE
+ sta ptr1+1 ; From
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; To
+
+common: ldy #EM_COPY::COUNT+1
+ lda (ptr3),y ; Get number of pages
+ beq @L2 ; Skip if no full pages
+ sta tmp1
+
+; Copy full pages allowing interrupts after each page copied
+
+ ldy #$00
+@L1: jsr transfer
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ tax
+
+ sei ; Disable ints
+ sta ENABLE_RAM ; Bank out the ROM
+
+; Transfer the bytes in the last page
+
+ ldy #$00
+@L3: lda (ptr1),y
+ sta (ptr2),y
+ iny
+ dex
+ bne @L3
+
+; Restore the old memory configuration, allow interrupts
+
+ sta ENABLE_ROM
+ cli
+
+; Done
+
+@L4: rts
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO: sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr2
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ add #>BASE
+ sta ptr2+1 ; To
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr1
+ iny
+ lda (ptr3),y
+ sta ptr1+1 ; From
+
+ jmp common
+
+
--- /dev/null
+;
+; Standard joystick driver for the C16. May be used multiple times when linked
+; to the statically application.
+;
+; Ullrich von Bassewitz, 2002-12-21
+;
+
+ .include "../../plus4/joy/plus4-stdjoy.s"
+
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = c64
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-mou.o: %.mou
- @$(CO) -o $(*)-mou.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-mou.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- break.o \
- crt0.o \
- cgetc.o \
- clrscr.o \
- color.o \
- conio.o \
- cputc.o \
- devnum.o \
- get_ostype.o \
- get_tv.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- kernal.o \
- kplot.o \
- mainargs.o \
- mcbdefault.o \
- mouse_stat_stddrv.o \
- mouse_stddrv.o \
- randomize.o \
- revers.o \
- status.o \
- systime.o \
- sysuname.o \
- tgi_colors.o \
- tgi_stat_stddrv.o \
- tgi_stddrv.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(MOUS:.mou=-mou.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS = c64-c256k.emd \
- c64-dqbb.emd \
- c64-georam.emd \
- c64-isepic.emd \
- c64-ram.emd \
- c64-ramcart.emd \
- c64-reu.emd \
- c64-vdc.emd \
- dtv-himem.emd
-
-JOYS = c64-hitjoy.joy \
- c64-numpad.joy \
- c64-ptvjoy.joy \
- c64-stdjoy.joy
-
-MOUS = c64-1351.mou \
- c64-joymouse.mou \
- c64-potmouse.mou
-
-SERS = c64-swlink.ser
-
-TGIS = c64-320-200-2.tgi
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(MOUS:.mou=.o) $(MOUS:.mou=-mou.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
+++ /dev/null
-;
-; Driver for the 1351 proportional mouse. Parts of the code are from
-; the Commodore 1351 mouse users guide.
-;
-; 2009-09-26, Ullrich von Bassewitz
-; 2010-02-06, Greg King
-;
-; The driver prevents the keyboard from interfering by changing the
-; keyboard's output port into an input port while the driver reads its
-; controller device. That disables a wire that is left active by the
-; Kernal. That wire is used by the STOP-key to break out of BASIC
-; programs -- CC65 programs don't use that feature. The wire is shared
-; by these keys: STOP, "Q", Commodore, Space, "2", CTRL, Left-Arrow, and
-; "1". I listed them, in order, from bit 7 over to bit 0. The
-; rightmost five keys can look like joystick switches.
-;
-; The driver prevents the mouse/joystick from interfering by "blinding"
-; the keyboard scanner while any button/switch is active. It changes
-; the input port into an output port, then stores all zero-bits in that
-; port's latch. Reading from an output port sees the bitwise-AND of the
-; latch and the input signals. Therefore, the scanner thinks that eight
-; keys are being pushed at the same time. It doesn't know what to do
-; about that condition; so, it does nothing. The driver lets the
-; scanner see normally, again, when no buttons/switches are active.
-;
-
- .include "zeropage.inc"
- .include "mouse-kernel.inc"
- .include "c64.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-HEADER:
-
-; Driver signature
-
- .byte $6d, $6f, $75 ; "mou"
- .byte MOUSE_API_VERSION ; Mouse driver API version number
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr HIDE
- .addr SHOW
- .addr SETBOX
- .addr GETBOX
- .addr MOVE
- .addr BUTTONS
- .addr POS
- .addr INFO
- .addr IOCTL
- .addr IRQ
-
-; Mouse driver flags
-
- .byte MOUSE_FLAG_LATE_IRQ
-
-; Callback table, set by the kernel before INSTALL is called
-
-CHIDE: jmp $0000 ; Hide the cursor
-CSHOW: jmp $0000 ; Show the cursor
-CMOVEX: jmp $0000 ; Move the cursor to X coord
-CMOVEY: jmp $0000 ; Move the cursor to Y coord
-
-
-;----------------------------------------------------------------------------
-; Constants
-
-SCREEN_HEIGHT = YSIZE * 8 - 1 ; (origin is zero)
-SCREEN_WIDTH = XSIZE * 8 - 1
-
-;----------------------------------------------------------------------------
-; Global variables. The bounding box values are sorted so that they can be
-; written with the least effort in the SETBOX and GETBOX routines, so don't
-; reorder them.
-
-.bss
-
-Vars:
-OldPotX: .res 1 ; Old hw counter values
-OldPotY: .res 1
-
-XPos: .res 2 ; Current mouse position, X
-YPos: .res 2 ; Current mouse position, Y
-XMin: .res 2 ; X1 value of bounding box
-YMin: .res 2 ; Y1 value of bounding box
-XMax: .res 2 ; X2 value of bounding box
-YMax: .res 2 ; Y2 value of bounding box
-Buttons: .res 1 ; button status bits
-
-OldValue: .res 1 ; Temp for MoveCheck routine
-NewValue: .res 1 ; Temp for MoveCheck routine
-
-; Default values for above variables
-
-.rodata
-
-; (We use ".proc" because we want to define both a label and a scope.)
-
-.proc DefVars
- .byte 0, 0 ; OldPotX/OldPotY
- .word SCREEN_WIDTH/2 ; XPos
- .word SCREEN_HEIGHT/2 ; YPos
- .word 0 ; XMin
- .word 0 ; YMin
- .word SCREEN_WIDTH ; XMax
- .word SCREEN_HEIGHT ; YMax
- .byte %00000000 ; Buttons
-.endproc
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an MOUSE_ERR_xx code in a/x.
-
-INSTALL:
-
-; Initialize variables. Just copy the default stuff over
-
- ldx #.sizeof(DefVars)-1
-@L1: lda DefVars,x
- sta Vars,x
- dex
- bpl @L1
-
-; Be sure the mouse cursor is invisible and at the default location. We
-; need to do that here, because our mouse interrupt handler doesn't set the
-; mouse position if it hasn't changed.
-
- sei
- jsr CHIDE
- lda XPos
- ldx XPos+1
- jsr CMOVEX
- lda YPos
- ldx YPos+1
- jsr CMOVEY
- cli
-
-; Done, return zero (= MOUSE_ERR_OK)
-
- ldx #$00
- txa
- rts
-
-;----------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-
-UNINSTALL = HIDE ; Hide cursor on exit
-
-;----------------------------------------------------------------------------
-; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently visible and should get hidden. For most drivers,
-; no special action is required besides hiding the mouse cursor.
-; No return code required.
-
-HIDE: sei
- jsr CHIDE
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently hidden and should become visible. For most drivers,
-; no special action is required besides enabling the mouse cursor.
-; No return code required.
-
-SHOW: sei
- jsr CSHOW
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SETBOX: Set the mouse bounding box. The parameters are passed as they come
-; from the C program, that is, a pointer to a mouse_box struct in a/x.
-; No checks are done if the mouse is currently inside the box, this is the job
-; of the caller. It is not necessary to validate the parameters, trust the
-; caller and save some code here. No return code required.
-
-SETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda (ptr1),y
- sta XMin,y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; GETBOX: Return the mouse bounding box. The parameters are passed as they
-; come from the C program, that is, a pointer to a mouse_box struct in a/x.
-
-GETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
-@L1: lda XMin,y
- sta (ptr1),y
- dey
- bpl @L1
- rts
-
-;----------------------------------------------------------------------------
-; MOVE: Move the mouse to a new position. The position is passed as it comes
-; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
-; remove the parameter from the stack on return.
-; No checks are done if the new position is valid (within the bounding box or
-; the screen). No return code required.
-;
-
-MOVE: sei ; No interrupts
-
- sta YPos
- stx YPos+1 ; New Y position
- jsr CMOVEY ; Set it
-
- ldy #$01
- lda (sp),y
- sta XPos+1
- tax
- dey
- lda (sp),y
- sta XPos ; New X position
-
- jsr CMOVEX ; Move the cursor
-
- cli ; Allow interrupts
- rts
-
-;----------------------------------------------------------------------------
-; BUTTONS: Return the button mask in a/x.
-
-BUTTONS:
- lda Buttons
- ldx #0
- and #$1F
- rts
-
-;----------------------------------------------------------------------------
-; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
-; No return code required.
-
-POS: ldy #MOUSE_POS::XCOORD ; Structure offset
-
- sei ; Disable interrupts
- lda XPos ; Transfer the position
- sta (ptr1),y
- lda XPos+1
- iny
- sta (ptr1),y
- lda YPos
- iny
- sta (ptr1),y
- lda YPos+1
- cli ; Enable interrupts
-
- iny
- sta (ptr1),y ; Store last byte
-
- rts ; Done
-
-;----------------------------------------------------------------------------
-; INFO: Returns mouse position and current button mask in the MOUSE_INFO
-; struct pointed to by ptr1. No return code required.
-;
-; We're cheating here to keep the code smaller: The first fields of the
-; mouse_info struct are identical to the mouse_pos struct, so we will just
-; call _mouse_pos to initialize the struct pointer and fill the position
-; fields.
-
-INFO: jsr POS
-
-; Fill in the button state
-
- jsr BUTTONS ; Will not touch ptr1
- ldy #MOUSE_INFO::BUTTONS
- sta (ptr1),y
-
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>MOUSE_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
-; (so be careful). The routine MUST return carry set if the interrupt has been
-; 'handled' - which means that the interrupt source is gone. Otherwise it
-; MUST return carry clear.
-;
-
-IRQ:
-
-; Record the state of the buttons.
-; Avoid crosstalk between the keyboard and the mouse.
-
- ldy #%00000000 ; Set ports A and B to input
- sty CIA1_DDRB
- sty CIA1_DDRA ; Keyboard won't look like mouse
- lda CIA1_PRB ; Read Control-Port 1
- dec CIA1_DDRA ; Set port A back to output
- eor #%11111111 ; Bit goes up when button goes down
- sta Buttons
- beq @L0 ;(bze)
- dec CIA1_DDRB ; Mouse won't look like keyboard
- sty CIA1_PRB ; Set "all keys pushed"
-
-@L0: lda SID_ADConv1 ; Get mouse X movement
- ldy OldPotX
- jsr MoveCheck ; Calculate movement vector
-
-; Skip processing if nothing has changed
-
- bcc @SkipX
- sty OldPotX
-
-; Calculate the new X coordinate (--> a/y)
-
- add XPos
- tay ; Remember low byte
- txa
- adc XPos+1
- tax
-
-; Limit the X coordinate to the bounding box
-
- cpy XMin
- sbc XMin+1
- bpl @L1
- ldy XMin
- ldx XMin+1
- jmp @L2
-@L1: txa
-
- cpy XMax
- sbc XMax+1
- bmi @L2
- ldy XMax
- ldx XMax+1
-@L2: sty XPos
- stx XPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jsr CMOVEX
-
-; Calculate the Y movement vector
-
-@SkipX: lda SID_ADConv2 ; Get mouse Y movement
- ldy OldPotY
- jsr MoveCheck ; Calculate movement
-
-; Skip processing if nothing has changed
-
- bcc @SkipY
- sty OldPotY
-
-; Calculate the new Y coordinate (--> a/y)
-
- sta OldValue
- lda YPos
- sub OldValue
- tay
- stx OldValue
- lda YPos+1
- sbc OldValue
- tax
-
-; Limit the Y coordinate to the bounding box
-
- cpy YMin
- sbc YMin+1
- bpl @L3
- ldy YMin
- ldx YMin+1
- jmp @L4
-@L3: txa
-
- cpy YMax
- sbc YMax+1
- bmi @L4
- ldy YMax
- ldx YMax+1
-@L4: sty YPos
- stx YPos+1
-
-; Move the mouse pointer to the new Y pos
-
- tya
- jsr CMOVEY
-
-; Done
-
- clc ; Interrupt not "handled"
-@SkipY: rts
-
-; --------------------------------------------------------------------------
-;
-; Move check routine, called for both coordinates.
-;
-; Entry: y = old value of pot register
-; a = current value of pot register
-; Exit: y = value to use for old value
-; x/a = delta value for position
-;
-
-MoveCheck:
- sty OldValue
- sta NewValue
- ldx #$00
-
- sub OldValue ; a = mod64 (new - old)
- and #%01111111
- cmp #%01000000 ; if (a > 0)
- bcs @L1 ;
- lsr a ; a /= 2;
- beq @L2 ; if (a != 0)
- ldy NewValue ; y = NewValue
- sec
- rts ; return
-
-@L1: ora #%11000000 ; else, "or" in high-order bits
- cmp #$FF ; if (a != -1)
- beq @L2
- sec
- ror a ; a /= 2
- dex ; high byte = -1 (X = $FF)
- ldy NewValue
- sec
- rts
-
-@L2: txa ; A = $00
- clc
- rts
-
+++ /dev/null
-;
-; Graphics driver for the 320x200x2 mode on the C64.
-;
-; Based on Stephen L. Judds GRLIB code
-;
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; 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
- .word 320 ; X resolution
- .word 200 ; Y resolution
- .byte 2 ; Number of drawing colors
- .byte 1 ; Number of screens available
- .byte 8 ; System font X size
- .byte 8 ; System font Y size
- .word $00D4 ; Aspect ratio (based on 4/3 display)
- .byte 0 ; TGI driver flags
-
-; Next comes the jump table. With the exception of IRQ, 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 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
-TEXT := ptr3
-
-ROW := tmp2 ; Bitmap row...
-COL := tmp3 ; ...and column, both set by PLOT
-TEMP := tmp4
-TEMP2 := sreg
-POINT := regsave
-INRANGE := regsave+2 ; PLOT variable, $00 = coordinates in range
-
-CHUNK := X2 ; Used in the line routine
-OLDCHUNK := X2+1 ; Dito
-
-; Absolute variables used in the code
-
-.bss
-
-ERROR: .res 1 ; Error code
-PALETTE: .res 2 ; The current palette
-
-BITMASK: .res 1 ; $00 = clear, $FF = set pixels
-
-; INIT/DONE
-OLDD018: .res 1 ; Old register value
-
-; Line routine stuff
-DX: .res 2
-DY: .res 2
-
-; BAR variables
-X1SAVE: .res 2
-Y1SAVE: .res 2
-X2SAVE: .res 2
-Y2SAVE: .res 2
-
-; Text output stuff
-TEXTMAGX: .res 1
-TEXTMAGY: .res 1
-TEXTDIR: .res 1
-
-; Constants and tables
-
-.rodata
-
-DEFPALETTE: .byte $00, $01 ; White on black
-PALETTESIZE = * - DEFPALETTE
-
-BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01
-BITCHUNK: .byte $FF,$7F,$3F,$1F,$0F,$07,$03,$01
-
-CHARROM := $D000 ; Character rom base address
-CBASE := $D000 ; Color memory base address
-VBASE := $E000 ; Video memory base address
-
-
-.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:
- rts
-
-
-; ------------------------------------------------------------------------
-; 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:
-
-; Initialize variables
-
- ldx #$FF
- stx BITMASK
-
-; Switch into graphics mode
-
- lda $DD02 ; Set the data direction regs
- ora #3
- sta $DD02
- lda $DD00
- and #$FC ; Switch to bank 3
- sta $DD00
-
- lda $D018
- sta OLDD018
- lda #$48 ; Set color map to $D000, screen to $E000
- sta $D018
-
- lda $D011 ; And turn on bitmap
- ora #$20
-DONE1: sta $D011
-
-; 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: lda $DD02 ; Set the data direction regs
- ora #3
- sta $DD02
- lda $DD00
- ora #$03 ; Bank 0
- sta $DD00
-
- lda OLDD018 ; Screen mem --> $0400
- sta $D018
-
- lda $D011
- and #<~$20
- sta $D011
- rts
-
-; ------------------------------------------------------------------------
-; 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: ldy #$00
- tya
-@L1: sta VBASE+$0000,y
- sta VBASE+$0100,y
- sta VBASE+$0200,y
- sta VBASE+$0300,y
- sta VBASE+$0400,y
- sta VBASE+$0500,y
- sta VBASE+$0600,y
- sta VBASE+$0700,y
- sta VBASE+$0800,y
- sta VBASE+$0900,y
- sta VBASE+$0A00,y
- sta VBASE+$0B00,y
- sta VBASE+$0C00,y
- sta VBASE+$0D00,y
- sta VBASE+$0E00,y
- sta VBASE+$0F00,y
- sta VBASE+$1000,y
- sta VBASE+$1100,y
- sta VBASE+$1200,y
- sta VBASE+$1300,y
- sta VBASE+$1400,y
- sta VBASE+$1500,y
- sta VBASE+$1600,y
- sta VBASE+$1700,y
- sta VBASE+$1800,y
- sta VBASE+$1900,y
- sta VBASE+$1A00,y
- sta VBASE+$1B00,y
- sta VBASE+$1C00,y
- sta VBASE+$1D00,y
- sta VBASE+$1E00,y
- sta VBASE+$1F00,y
- iny
- bne @L1
- 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:
- 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:
- 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
- beq @L1
- lda #$FF
-@L1: sta BITMASK
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- ldy #PALETTESIZE - 1
-@L1: lda (ptr1),y ; Copy the palette
- and #$0F ; Make a valid color
- sta PALETTE,y
- dey
- bpl @L1
-
-; Get the color entries from the palette
-
- lda PALETTE+1 ; Foreground color
- asl a
- asl a
- asl a
- asl a
- ora PALETTE ; Background color
- tax
-
-; Initialize the color map with the new color settings (it is below the
-; I/O area)
-
- ldy #$00
- sei
- lda $01 ; Get ROM config
- pha ; Save it
- and #%11111100 ; Clear bit 0 and 1
- sta $01
- txa ; Load color code
-@L2: sta CBASE+$0000,y
- sta CBASE+$0100,y
- sta CBASE+$0200,y
- sta CBASE+$0300,y
- iny
- bne @L2
- pla
- sta $01
- cli
-
-; Done, reset the error code
-
- lda #TGI_ERR_OK
- 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:
- lda #<PALETTE
- ldx #>PALETTE
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- jsr CALC ; Calculate coordinates
-
- sei ; Get underneath ROM
- lda $01
- pha
- lda #$34
- sta $01
-
- lda (POINT),Y
- eor BITMASK
- and BITTAB,X
- eor (POINT),Y
- sta (POINT),Y
-
- pla
- sta $01
- cli
-
-@L9: 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:
- jsr CALC ; Calculate coordinates
-
- sei ; Get underneath ROM
- lda $01
- pha
- lda #$34
- sta $01
-
- lda (POINT),Y
- ldy #$00
- and BITTAB,X
- beq @L1
- iny
-
-@L1: pla
- sta $01
- cli
-
- tya ; Get color value into A
- ldx #$00 ; Clear high byte
- 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.
-;
-; To deal with off-screen coordinates, the current row
-; and column (40x25) is kept track of. These are set
-; negative when the point is off the screen, and made
-; positive when the point is within the visible screen.
-;
-; X1,X2 etc. are set up above (x2=LINNUM in particular)
-; Format is LINE x2,y2,x1,y1
-;
-; Must set an error code: NO
-;
-
-LINE:
-
-@CHECK: lda X2 ;Make sure x1<x2
- sec
- sbc X1
- tax
- lda X2+1
- sbc X1+1
- bpl @CONT
- lda Y2 ;If not, swap P1 and P2
- ldy Y1
- sta Y1
- sty Y2
- lda Y2+1
- ldy Y1+1
- sta Y1+1
- sty Y2+1
- lda X1
- ldy X2
- sty X1
- sta X2
- lda X2+1
- ldy X1+1
- sta X1+1
- sty X2+1
- bcc @CHECK
-
-@CONT: sta DX+1
- stx DX
-
- ldx #$C8 ;INY
- lda Y2 ;Calculate dy
- sec
- sbc Y1
- tay
- lda Y2+1
- sbc Y1+1
- bpl @DYPOS ;Is y2>=y1?
- lda Y1 ;Otherwise dy=y1-y2
- sec
- sbc Y2
- tay
- ldx #$88 ;DEY
-
-@DYPOS: sty DY ; 8-bit DY -- FIX ME?
- stx YINCDEC
- stx XINCDEC
-
- jsr CALC ; Set up .X,.Y,POINT, and INRANGE
- lda BITCHUNK,X
- sta OLDCHUNK
- sta CHUNK
-
- sei ; Get underneath ROM
- lda #$34
- sta $01
-
- ldx DY
- cpx DX ;Who's bigger: dy or dx?
- bcc STEPINX ;If dx, then...
- lda DX+1
- bne STEPINX
-
-;
-; Big steps in Y
-;
-; To simplify my life, just use PLOT to plot points.
-;
-; No more!
-; Added special plotting routine -- cool!
-;
-; X is now counter, Y is y-coordinate
-;
-; On entry, X=DY=number of loop iterations, and Y=
-; Y1 AND #$07
-STEPINY:
- lda #00
- sta OLDCHUNK ;So plotting routine will work right
- lda CHUNK
- lsr ;Strip the bit
- eor CHUNK
- sta CHUNK
- txa
- bne @CONT ;If dy=0 it's just a point
- inx
-@CONT: lsr ;Init counter to dy/2
-;
-; Main loop
-;
-YLOOP: sta TEMP
-
- lda INRANGE ;Range check
- bne @SKIP
-
- lda (POINT),y ;Otherwise plot
- eor BITMASK
- and CHUNK
- eor (POINT),y
- sta (POINT),y
-@SKIP:
-YINCDEC:
- iny ;Advance Y coordinate
- cpy #8
- bcc @CONT ;No prob if Y=0..7
- jsr FIXY
-@CONT: lda TEMP ;Restore A
- sec
- sbc DX
- bcc YFIXX
-YCONT: dex ;X is counter
- bne YLOOP
-YCONT2: lda (POINT),y ;Plot endpoint
- eor BITMASK
- and CHUNK
- eor (POINT),y
- sta (POINT),y
-YDONE: lda #$36
- sta $01
- cli
- rts
-
-YFIXX: ;x=x+1
- adc DY
- lsr CHUNK
- bne YCONT ;If we pass a column boundary...
- ror CHUNK ;then reset CHUNK to $80
- sta TEMP2
- lda COL
- bmi @C1 ;Skip if column is negative
- cmp #39 ;End if move past end of screen
- bcs YDONE
-@C1: lda POINT ;And add 8 to POINT
- adc #8
- sta POINT
- bcc @CONT
- inc POINT+1
-@CONT: inc COL ;Increment column
- bne @C2
- lda ROW ;Range check
- cmp #25
- bcs @C2
- lda #00 ;Passed into col 0
- sta INRANGE
-@C2: lda TEMP2
- dex
- bne YLOOP
- beq YCONT2
-
-;
-; Big steps in X direction
-;
-; On entry, X=DY=number of loop iterations, and Y=
-; Y1 AND #$07
-
-.bss
-COUNTHI:
- .byte $00 ;Temporary counter
- ;only used once
-.code
-STEPINX:
- ldx DX
- lda DX+1
- sta COUNTHI
- cmp #$80
- ror ;Need bit for initialization
- sta Y1 ;High byte of counter
- txa
- bne @CONT ;Could be $100
- dec COUNTHI
-@CONT: ror
-;
-; Main loop
-;
-XLOOP: lsr CHUNK
- beq XFIXC ;If we pass a column boundary...
-XCONT1: sbc DY
- bcc XFIXY ;Time to step in Y?
-XCONT2: dex
- bne XLOOP
- dec COUNTHI ;High bits set?
- bpl XLOOP
-
-XDONE: lsr CHUNK ;Advance to last point
- jsr LINEPLOT ;Plot the last chunk
-EXIT: lda #$36
- sta $01
- cli
- rts
-;
-; CHUNK has passed a column, so plot and increment pointer
-; and fix up CHUNK, OLDCHUNK.
-;
-XFIXC: sta TEMP
- jsr LINEPLOT
- lda #$FF
- sta CHUNK
- sta OLDCHUNK
- lda COL
- bmi @C1 ;Skip if column is negative
- cmp #39 ;End if move past end of screen
- bcs EXIT
-@C1: lda POINT
- adc #8
- sta POINT
- bcc @CONT
- inc POINT+1
-@CONT: inc COL
- bne @C2
- lda ROW
- cmp #25
- bcs @C2
- lda #00
- sta INRANGE
-@C2: lda TEMP
- sec
- bcs XCONT1
-;
-; Check to make sure there isn't a high bit, plot chunk,
-; and update Y-coordinate.
-;
-XFIXY: dec Y1 ;Maybe high bit set
- bpl XCONT2
- adc DX
- sta TEMP
- lda DX+1
- adc #$FF ;Hi byte
- sta Y1
-
- jsr LINEPLOT ;Plot chunk
- lda CHUNK
- sta OLDCHUNK
-
- lda TEMP
-XINCDEC:
- iny ;Y-coord
- cpy #8 ;0..7 is ok
- bcc XCONT2
- sta TEMP
- jsr FIXY
- lda TEMP
- jmp XCONT2
-
-;
-; Subroutine to plot chunks/points (to save a little
-; room, gray hair, etc.)
-;
-LINEPLOT: ; Plot the line chunk
- lda INRANGE
- bne @SKIP
-
- lda (POINT),Y ; Otherwise plot
- eor BITMASK
- ora CHUNK
- and OLDCHUNK
- eor CHUNK
- eor (POINT),Y
- sta (POINT),Y
-@SKIP: rts
-
-;
-; Subroutine to fix up pointer when Y decreases through
-; zero or increases through 7.
-;
-FIXY: cpy #255 ;Y=255 or Y=8
- beq @DECPTR
-@INCPTR: ;Add 320 to pointer
- ldy #0 ;Y increased through 7
- lda ROW
- bmi @C1 ;If negative, then don't update
- cmp #24
- bcs @TOAST ;If at bottom of screen then quit
-@C1: lda POINT
- adc #<320
- sta POINT
- lda POINT+1
- adc #>320
- sta POINT+1
-@CONT1: inc ROW
- bne @DONE
- lda COL
- bpl @CLEAR
-@DONE: rts
-
-@DECPTR: ;Okay, subtract 320 then
- ldy #7 ;Y decreased through 0
- lda POINT
- sec
- sbc #<320
- sta POINT
- lda POINT+1
- sbc #>320
- sta POINT+1
-@CONT2: dec ROW
- bmi @TOAST
- lda ROW
- cmp #24
- bne @DONE
- lda COL
- bmi @DONE
-@CLEAR: lda #00
- sta INRANGE
- rts
-
-@TOAST: pla ;Remove old return address
- pla
- jmp EXIT ;Restore interrupts, etc.
-
-; ------------------------------------------------------------------------
-; 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
-;
-
-; Note: This function needs optimization. It's just a cheap translation of
-; the original C wrapper and could be written much smaller (besides that,
-; calling LINE is not a good idea either).
-
-BAR: lda Y2
- sta Y2SAVE
- lda Y2+1
- sta Y2SAVE+1
-
- lda X2
- sta X2SAVE
- lda X2+1
- sta X2SAVE+1
-
- lda Y1
- sta Y1SAVE
- lda Y1+1
- sta Y1SAVE+1
-
- lda X1
- sta X1SAVE
- lda X1+1
- sta X1SAVE+1
-
-@L1: lda Y1
- sta Y2
- lda Y1+1
- sta Y2+1
- jsr LINE
-
- lda Y1SAVE
- cmp Y2SAVE
- bne @L2
- lda Y1SAVE
- cmp Y2SAVE
- beq @L4
-
-@L2: inc Y1SAVE
- bne @L3
- inc Y1SAVE+1
-
-@L3: lda Y1SAVE
- sta Y1
- lda Y1SAVE+1
- sta Y1+1
-
- lda X1SAVE
- sta X1
- lda X1SAVE+1
- sta X1+1
-
- lda X2SAVE
- sta X2
- lda X2SAVE+1
- sta X2+1
- jmp @L1
-
-@L4: rts
-
-
-; ------------------------------------------------------------------------
-; 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
- 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:
-
-; Calculate a pointer to the representation of the character in the
-; character ROM
-
- ldx #((>(CHARROM + $0800)) >> 3)
- ldy #0
- lda (TEXT),y
- bmi @L1
- ldx #((>(CHARROM + $0000)) >> 3)
-@L1: stx ptr4+1
- asl a
- rol ptr4+1
- asl a
- rol ptr4+1
- asl a
- rol ptr4+1
- sta ptr4
-
-
-
-
-
- rts
-
-; ------------------------------------------------------------------------
-; Calculate all variables to plot the pixel at X1/Y1. If the point is out
-; of range, a carry is returned and INRANGE is set to a value !0 zero. If
-; the coordinates are valid, INRANGE is zero and the carry clear.
-
-CALC: lda Y1
- sta ROW
- and #7
- tay
- lda Y1+1
- lsr ; Neg is possible
- ror ROW
- lsr
- ror ROW
- lsr
- ror ROW
-
- lda #00
- sta POINT
- lda ROW
- cmp #$80
- ror
- ror POINT
- cmp #$80
- ror
- ror POINT ; row*64
- adc ROW ; +row*256
- clc
- adc #>VBASE ; +bitmap base
- sta POINT+1
-
- lda X1
- tax
- sta COL
- lda X1+1
- lsr
- ror COL
- lsr
- ror COL
- lsr
- ror COL
-
- txa
- and #$F8
- clc
- adc POINT ; +(X AND #$F8)
- sta POINT
- lda X1+1
- adc POINT+1
- sta POINT+1
- txa
- and #7
- tax
-
- lda ROW
- cmp #25
- bcs @L9
- lda COL
- cmp #40
- bcs @L9
- lda #00
-@L9: sta INRANGE
- rts
-
-
+++ /dev/null
-;
-; Extended memory driver for the C256K memory expansion
-; Marco van den Heuvel, 2010-01-27
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-BASE = $4000
-PAGES = 3 * 256
-TARGETLOC = $200 ; Target location for copy/check code
-PIA = $DFC0
-
-; ------------------------------------------------------------------------
-; Data.
-
-.data
-
-
-; This function is used to copy code from and to the extended memory
-.proc copy
-template:
-.org ::TARGETLOC ; Assemble for target location
-entry:
- stx PIA
-stashop = $91 ; 'sta' opcode
-operation := * ; Location and opcode is patched at runtime
-address := *+1
- lda ($00),y
- ldx #$dc
- stx PIA
- rts
-.reloc
-.endproc
-
-; This function is used to check for the existence of the extended memory
-.proc check
-template:
-.org ::TARGETLOC
-entry:
- ldy #$00 ; Assume hardware not present
-
- lda #$fc
- sta PIA
- lda $01
- tax
- and #$f8
- sta $01
- lda $4000
- cmp $c000
- bne done ; Jump if not found
- inc $c000
- cmp $4000
- beq done ; Jump if not found
-
- ; Hardware is present
- iny
-done: stx $01
- ldx #$dc
- stx PIA
- rts
-.reloc
-.endproc
-
-
-
-.bss
-
-curpage: .res 2 ; Current page number
-curbank: .res 1 ; Current bank
-window: .res 256 ; Memory "window"
-
-; Since the functions above are copied to $200, the current contents of this
-; memory area must be saved into backup storage. Allocate enough space.
-backup: .res .max (.sizeof (copy), .sizeof (check))
-
-
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- lda PIA+1 ; Select Peripheral Registers
- ora #4
- sta PIA+1
- tax
- lda PIA+3
- ora #4
- sta PIA+3
- tay
-
- lda #$DC ; Set the default memory bank data
- sta PIA
- lda #$FE
- sta PIA+2
-
- txa ; Select Data Direction Registers
- and #$FB
- sta PIA+1
- tya
- and #$FB
- sta PIA+3
-
- lda #$FF ; Set the ports to output
- sta PIA
- sta PIA+2
-
- txa
- and #$C7
- ora #$30 ; Set CA1 and
- sta PIA+1 ; select Peripheral Registers
- sty PIA+3
-
- jsr backup_and_setup_check_routine
- jsr check::entry
- cli
- ldx #.sizeof (check) - 1
- jsr restore_data
- cpy #$01
- beq @present
- lda #<EM_ERR_NO_DEVICE
- ldx #>EM_ERR_NO_DEVICE
- rts
-
-@present:
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda #<PAGES
- ldx #>PAGES
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP:
- sei
- sta curpage ; Remember the new page
- stx curpage+1
- jsr adjust_page_and_bank
- stx curbank
- clc
- adc #>BASE
- sta ptr1+1
- ldy #0
- sty ptr1
- jsr backup_and_setup_copy_routine
- ldx #<ptr1
- stx copy::address
-@L1:
- ldx curbank
- jsr copy::entry
- ldx ptr1
- sta window,x
- inc ptr1
- bne @L1
-
-; Return the memory window
-
- jsr restore_copy_routine
- lda #<window
- ldx #>window ; Return the window address
- cli
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage ; Remember the page
- stx curpage+1
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT:
- sei
- lda curpage ; Get the current page
- ldx curpage+1
-
- jsr adjust_page_and_bank
- stx curbank
- clc
- adc #>BASE
- sta ptr1+1
- ldy #0
- sty ptr1
- jsr backup_and_setup_copy_routine
- ldx #<ptr1
- stx copy::address
- ldx #<copy::stashop
- stx copy::operation
-@L1:
- ldx ptr1
- lda window,x
- ldx curbank
- jsr copy::entry
- inc ptr1
- bne @L1
-
-; Return the memory window
-
- jsr restore_copy_routine
-done:
- cli
- rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-
-COPYFROM:
- sei
- jsr setup
- jsr backup_and_setup_copy_routine
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - ptr4 contains the page memory buffer plus offset
-; - tmp1 contains zero (to be used for linear memory buffer offset)
-; - tmp2 contains the bank value
-
- lda #<ptr4
- sta copy::address
- jmp @L3
-
-@L1:
- ldx tmp2
- ldy #0
- jsr copy::entry
- ldy tmp1
- sta (ptr2),y
- inc tmp1
- bne @L2
- inc ptr2+1
-@L2:
- inc ptr4
- beq @L4
-
-; Bump count and repeat
-
-@L3:
- inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- jsr restore_copy_routine
- cli
- rts
-
-; Bump page register
-
-@L4:
- inc ptr4+1
- lda ptr4+1
- cmp #$80
- bne @L3
- lda #>BASE
- sta ptr4+1
- lda tmp2
- clc
- adc #$10
- sta tmp2
- jmp @L3
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- sei
- jsr setup
- jsr backup_and_setup_copy_routine
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - ptr4 contains the page memory buffer plus offset
-; - tmp1 contains zero (to be used for linear memory buffer offset)
-; - tmp2 contains the bank value
-
- lda #<ptr4
- sta copy::address
- lda #<copy::stashop
- sta copy::operation
- jmp @L3
-
-@L1:
- ldy tmp1
- lda (ptr2),y
- ldx tmp2
- ldy #0
- jsr copy::entry
- inc tmp1
- bne @L2
- inc ptr2+1
-@L2:
- inc ptr4
- beq @L4
-
-; Bump count and repeat
-
-@L3:
- inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- jsr restore_copy_routine
- cli
- rts
-
-; Bump page register
-
-@L4:
- inc ptr4+1
- lda ptr4+1
- cmp #$80
- bne @L3
- lda #>BASE
- sta ptr4+1
- lda tmp2
- clc
- adc #$10
- sta tmp2
- jmp @L3
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-
-setup:
- sta ptr1
- stx ptr1+1 ; Save passed pointer
-
-; Get the page number from the struct and adjust it so that it may be used
-; with the hardware. That is: ptr4 has the page address and page offset
-; tmp2 will hold the bank value
-
- ldy #EM_COPY::PAGE+1
- lda (ptr1),y
- tax
- ldy #EM_COPY::PAGE
- lda (ptr1),y
- jsr adjust_page_and_bank
- clc
- adc #>BASE
- sta ptr4+1
- stx tmp2
-
-; Get the buffer pointer into ptr2
-
- ldy #EM_COPY::BUF
- lda (ptr1),y
- sta ptr2
- iny
- lda (ptr1),y
- sta ptr2+1
-
-; Get the count, calculate -(count-1) and store it into ptr3
-
- ldy #EM_COPY::COUNT
- lda (ptr1),y
- eor #$FF
- sta ptr3
- iny
- lda (ptr1),y
- eor #$FF
- sta ptr3+1
-
-; Get the page offset into ptr4 and clear tmp1
-
- ldy #EM_COPY::OFFS
- lda (ptr1),y
- sta ptr4
- lda #0
- sta tmp1
-
-; Done
-
- rts
-
-; Helper routines for copying to and from the +256k ram
-
-backup_and_setup_copy_routine:
- ldx #.sizeof (copy) - 1
-@L1:
- lda copy::entry,x
- sta backup,x
- lda copy::template,x
- sta copy::entry,x
- dex
- bpl @L1
- rts
-
-backup_and_setup_check_routine:
- ldx #.sizeof (check) - 1
-@L1:
- lda check::entry,x
- sta backup,x
- lda check::template,x
- sta check::entry,x
- dex
- bpl @L1
- rts
-
-restore_copy_routine:
- ldx #.sizeof (copy) - 1
-restore_data:
- lda backup,x
- sta TARGETLOC,x
- dex
- bpl restore_data
- rts
-
-; Helper routine to correct for the bank and page
-adjust_page_and_bank:
- sta tmp4
- lda #$0C
- sta tmp3
- lda tmp4
- and #$c0
- lsr
- lsr
- ora tmp3
- sta tmp3
- txa
- asl
- asl
- asl
- asl
- asl
- asl
- ora tmp3
- tax
- lda tmp4
- and #$3f
- rts
+++ /dev/null
-;
-; Extended memory driver for the Double Quick Brown Box cartridge
-; Marco van den Heuvel, 2010-01-27
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-BASE = $8000
-PAGES = ($C000 - BASE) / 256
-TARGETLOC = $200 ; Target location for copy/check code
-CONTROL = $DE00
-
-; ------------------------------------------------------------------------
-; Data.
-
-.proc check
-template:
-.org ::TARGETLOC ; Assemble for target location
-entry:
- lda $01
- pha
- lda #$37
- sta $01
- ldx #$14
- ldy #$90
- sty CONTROL
- lda $8000
- stx CONTROL
- cmp $8000
- bne present
- sty CONTROL
- inc $8000
- stx CONTROL
- cmp $8000
- beq present
- dec $8000
- ldy #$00
-
-done: pla
- sta $01
- rts
-
-present:
- sty CONTROL
- ldy #$01
- bne done
-.reloc
-.endproc
-
-
-.proc copy
-template:
-.org ::TARGETLOC ; Assemble for target location
-entry:
-.proc fetch
- stx CONTROL
- ldx $01
- lda #$37
- sta $01
-address := *+1 ; Patched at runtime
- lda ($00),y
- stx $01
- ldx #$90
- stx CONTROL
- rts
-.endproc
-
-.proc stash
- stx CONTROL
- ldx $01
- ldy #$37
- sty $01
- ldy #$00
-address := *+1 ; Patched at runtime
- sta ($00),y
- stx $01
- ldx #$90
- stx CONTROL
- rts
-.endproc
-.reloc
-.endproc
-
-
-.bss
-
-curpage: .res 1 ; Current page number
-window: .res 256 ; Memory "window"
-
-; Since the functions above are copied to $200, the current contents of this
-; memory area must be saved into backup storage. Allocate enough space.
-backup: .res .max (.sizeof (copy), .sizeof (check))
-
-
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- sei
- jsr backup_and_setup_check_routine
- jsr check::entry
- cli
- ldx #.sizeof (check) - 1
- jsr restore_data
- cpy #$01
- beq @present
- lda #<EM_ERR_NO_DEVICE
- ldx #>EM_ERR_NO_DEVICE
- rts
-
-@present:
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda #<PAGES
- ldx #>PAGES
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP:
- sei
- sta curpage ; Remember the new page
- clc
- adc #>BASE
- sta ptr1+1
- ldy #0
- sty ptr1
- jsr backup_and_setup_copy_routine
- ldx #<ptr1
- stx copy::fetch::address
-@L1:
- ldx #$14
- jsr copy::fetch
- ldx ptr1
- sta window,x
- inc ptr1
- bne @L1
-
-; Return the memory window
-
- jsr restore_copy_routine
- lda #<window
- ldx #>window ; Return the window address
- cli
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT:
- sei
- lda curpage ; Get the current page
- clc
- adc #>BASE
- sta ptr1+1
- ldy #0
- sty ptr1
- jsr backup_and_setup_copy_routine
- ldx #<ptr1
- stx copy::stash::address
-@L1:
- ldx ptr1
- lda window,x
- ldx #$14
- jsr copy::stash
- inc ptr1
- bne @L1
-
-; Return the memory window
-
- jsr restore_copy_routine
- cli
- rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-
-COPYFROM:
- sei
- pha
- txa
- pha
- jsr backup_and_setup_copy_routine
- pla
- tax
- pla
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - ptr4 contains the page memory buffer plus offset
-; - tmp1 contains zero (to be used for linear memory buffer offset)
-
- lda #<ptr4
- sta copy::fetch::address
- jmp @L3
-
-@L1:
- ldx #$14
- ldy #0
- jsr copy::fetch
- ldy tmp1
- sta (ptr2),y
- inc tmp1
- bne @L2
- inc ptr2+1
-@L2:
- inc ptr4
- beq @L4
-
-; Bump count and repeat
-
-@L3:
- inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- jsr restore_copy_routine
- cli
- rts
-
-; Bump page register
-
-@L4:
- inc ptr4+1
- jmp @L3
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- sei
- pha
- txa
- pha
- jsr backup_and_setup_copy_routine
- pla
- tax
- pla
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - ptr4 contains the page memory buffer plus offset
-; - tmp1 contains zero (to be used for linear memory buffer offset)
-
- lda #<ptr4
- sta copy::stash::address
- jmp @L3
-
-@L1:
- ldy tmp1
- lda (ptr2),y
- ldx #$14
- ldy #0
- jsr copy::stash
- inc tmp1
- bne @L2
- inc ptr2+1
-@L2:
- inc ptr4
- beq @L4
-
-; Bump count and repeat
-
-@L3:
- inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- jsr restore_copy_routine
- cli
- rts
-
-; Bump page register
-
-@L4:
- inc ptr4+1
- jmp @L3
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-
-setup:
- sta ptr1
- stx ptr1+1 ; Save passed pointer
-
-; Get the page number from the struct and adjust it so that it may be used
-; with the hardware. That is: ptr4 has the page address and page offset
-; tmp2 will hold the bank value
-
- ldy #EM_COPY::PAGE
- lda (ptr1),y
- clc
- adc #>BASE
- sta ptr4+1
-
-; Get the buffer pointer into ptr2
-
- ldy #EM_COPY::BUF
- lda (ptr1),y
- sta ptr2
- iny
- lda (ptr1),y
- sta ptr2+1
-
-; Get the count, calculate -(count-1) and store it into ptr3
-
- ldy #EM_COPY::COUNT
- lda (ptr1),y
- eor #$FF
- sta ptr3
- iny
- lda (ptr1),y
- eor #$FF
- sta ptr3+1
-
-; Get the page offset into ptr4 and clear tmp1
-
- ldy #EM_COPY::OFFS
- lda (ptr1),y
- sta ptr4
- lda #0
- sta tmp1
-
-; Done
-
- rts
-
-; Helper routines for copying to and from the +256k ram
-
-backup_and_setup_copy_routine:
- ldx #.sizeof (copy) - 1
-@L1:
- lda copy::entry,x
- sta backup,x
- lda copy::template,x
- sta copy::entry,x
- dex
- bpl @L1
- rts
-
-backup_and_setup_check_routine:
- ldx #.sizeof (check) - 1
-@L1:
- lda check::entry,x
- sta backup,x
- lda check::template,x
- sta check::entry,x
- dex
- bpl @L1
- rts
-
-restore_copy_routine:
- ldx #.sizeof (copy) - 1
-restore_data:
- lda backup,x
- sta TARGETLOC,x
- dex
- bpl restore_data
- rts
+++ /dev/null
-;
-; Extended memory driver for the GEORAM cartridge. Driver works without
-; problems when statically linked.
-;
-; Ullrich von Bassewitz, 2002-11-29
-;
-; GEORAM page size checking routine by
-; Marco van den Heuvel, 2010-01-21
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-GR_WINDOW = $DE00 ; Address of GEORAM window
-GR_PAGE_LO = $DFFE ; Page register low
-GR_PAGE_HI = $DFFF ; Page register high
-
-; ------------------------------------------------------------------------
-; Data.
-
-.data
-
-pagecount: .res 2 ; Number of available pages
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx GR_WINDOW
- cpx GR_WINDOW
- bne @notpresent
- inc GR_WINDOW
- cpx GR_WINDOW
- beq @notpresent
-
- lda #4
- jsr check
- cpy GR_WINDOW
- beq @has64k
- lda #8
- jsr check
- cpy GR_WINDOW
- beq @has128k
- lda #16
- jsr check
- cpy GR_WINDOW
- beq @has256k
- lda #32
- jsr check
- cpy GR_WINDOW
- beq @has512k
- lda #64
- jsr check
- cpy GR_WINDOW
- beq @has1024k
- lda #128
- jsr check
- cpy GR_WINDOW
- beq @has2048k
- ldx #>16384
- bne @setok
-
-@has64k:
- ldx #>256
- bne @setok
-@has128k:
- ldx #>512
- bne @setok
-@has256k:
- ldx #>1024
- bne @setok
-@has512k:
- ldx #>2048
- bne @setok
-@has1024k:
- ldx #>4096
- bne @setok
-@has2048k:
- ldx #>8192
- bne @setok
-
-@notpresent:
- lda #<EM_ERR_NO_DEVICE
- ldx #>EM_ERR_NO_DEVICE
- rts
-
-@setok:
- lda #0
- sta pagecount
- stx pagecount+1
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
- rts
-
-check:
- ldx #0
- stx GR_PAGE_LO
- stx GR_PAGE_HI
- ldy GR_WINDOW
- iny
- sta GR_PAGE_HI
- sty GR_WINDOW
- ldx #0
- stx GR_PAGE_HI
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-; The GeoRAM cartridge does not copy but actually map the window, so USE is
-; identical to MAP.
-
-USE = MAP
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta tmp1
- txa
- asl tmp1
- rol a
- asl tmp1
- rol a
-
- sta GR_PAGE_HI
- lda tmp1
- lsr a
- lsr a
- sta GR_PAGE_LO
-
- lda #<GR_WINDOW
- ldx #>GR_WINDOW
-
-; Use the RTS from COMMIT below to save a precious byte of storage
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - tmp2 contains the high page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1: lda GR_WINDOW,x
- sta (ptr2),y
- iny
- bne @L2
- inc ptr2+1
-@L2: inx
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4: inc tmp1 ; Bump low page register
- bit tmp1 ; Check for overflow in bit 6
- bvc @L6 ; Jump if no overflow
- inc tmp2
-@L5: lda tmp2
- sta GR_PAGE_HI
-@L6: lda tmp1
- sta GR_PAGE_LO
- jmp @L3
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - tmp2 contains the high page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1: lda (ptr2),y
- sta GR_WINDOW,x
- iny
- bne @L2
- inc ptr2+1
-@L2: inx
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4: inc tmp1 ; Bump low page register
- bit tmp1 ; Check for overflow in bit 6
- bvc @L6 ; Jump if no overflow
- inc tmp2
-@L5: lda tmp2
- sta GR_PAGE_HI
-@L6: lda tmp1
- sta GR_PAGE_LO
- jmp @L3
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-
-setup: sta ptr1
- stx ptr1+1 ; Save passed pointer
-
-; Get the page number from the struct and adjust it so that it may be used
-; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
-
- ldy #EM_COPY::PAGE+1
- lda (ptr1),y
- sta tmp2
- dey
- lda (ptr1),y
- asl a
- rol tmp2
- asl a
- rol tmp2
- lsr a
- lsr a
- sta tmp1
-
-; Get the buffer pointer into ptr2
-
- ldy #EM_COPY::BUF
- lda (ptr1),y
- sta ptr2
- iny
- lda (ptr1),y
- sta ptr2+1
-
-; Get the count, calculate -(count-1) and store it into ptr3
-
- ldy #EM_COPY::COUNT
- lda (ptr1),y
- eor #$FF
- sta ptr3
- iny
- lda (ptr1),y
- eor #$FF
- sta ptr3+1
-
-; Get the page offset into X and clear Y
-
- ldy #EM_COPY::OFFS
- lda (ptr1),y
- tax
- ldy #$00
-
-; Done
-
- rts
-
-
+++ /dev/null
-;
-; DXS/HIT-4 Player joystick driver for the C64
-;
-; Groepaz/Hitmen, 2002-12-23
-; obviously based on Ullrichs driver :)
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "c64.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
- .segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr IRQ
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 4 ; Number of joysticks we support
-
-; ------------------------------------------------------------------------
-; Data. Written in the IRQ, read by the READ routine
-
-.bss
-
-temp3: .byte 0
-temp4: .byte 0
-
-.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
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-; ------------------------------------------------------------------------
-; IRQ entry point. Is called from the C layer as a subroutine in the
-; interrupt. The routine MUST return carry set if the interrupt has been
-; 'handled' - which means that the interrupt source is gone. Otherwise it
-; MUST return carry clear.
-
-IRQ: ; cia 2 setup
-
- ldy #$00 ; port b direction
- sty $dd03 ; => input
-
- sty $dd05 ; cia2 timer a highbyte
- sty $dc05 ; cia1 timer a highbyte
- iny
- sty $dd04 ; cia2 timer a lowbyte
- sty $dc04 ; cia1 timer a lowbyte
-
- lda #%00010001
- sta $dd0e ; control register a
- ; timer: start
- ; continous
- ; forced load
- ; serial port: input
-
- ; cia 1 setup
- lda #%01010001
- sta $dc0e ; control register a
- ; timer: start
- ; continous
- ; forced load
- ; serial port: output
-
- ; read directions 3
- lda $dd01 ;read cia 2 port b
- and #$0f
- sta temp3
-
- ; read button 3
- lda $dd02 ;cia 2 port a
- and #%11111011 ;data direction
- sta $dd02 ;=> bit 2 input
-
- lda $dd00 ;read cia 2 p.A
- and #%00000100 ;check bit 2
- asl a
- asl a
- ora temp3
- sta temp3
-
- ; read directions 4
- lda $dd01 ;read cia 2 port b
- lsr a
- lsr a
- lsr a
- lsr a
- sta temp4
-
- ; read button 4
- ldx #$ff ;serial data register
- stx $dc0c ;=> writing $ff causes
- ;cia to output some
- ;count signals at cnt1
-
- ldx $dd0c ;read cia 2 serial in
- beq fire ;button press if zero
-
- lda temp4
- ora #%00010000
- sta temp4
-
-fire:
- ; Default Value: $40/64 on PAL
- ; $42/66 on NTSC
- lda #$41
- sta $dc05
- ; Default Value: $25/37 on PAL
- ; $95/149 on NTSC
- lda #0
- sta $dc04
-
- ; We do never "handle" the interrupt, we use it just as a timer.
- clc
- rts
-
-; ------------------------------------------------------------------------
-; COUNT: Return the total number of available joysticks in a/x.
-;
-
-COUNT: lda #<JOY_COUNT
- ldx #>JOY_COUNT
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: tax ; Joystick number into X
- bne joy2
-
-; Read joystick 1
-
-joy1: lda #$7F
- sei
- sta CIA1_PRA
- lda CIA1_PRB
- cli
- and #$1F
- eor #$1F
- rts
-
-; Read joystick 2
-
-joy2: dex
- bne joy3
-
- ; ldx #0
- lda #$E0
- ldy #$FF
- sei
- sta CIA1_DDRA
- lda CIA1_PRA
- sty CIA1_DDRA
- cli
- and #$1F
- eor #$1F
- rts
-
- ; Read joystick 3
-
-joy3: dex
- bne joy4
-
- lda temp3
- eor #$1F
- rts
-
- ; Read joystick 4
-
-joy4: lda temp4
- eor #$1F
- ldx #0
- rts
-
+++ /dev/null
-;
-; Extended memory driver for the ISEPIC cartridge.
-; Marco van den Heuvel, 2010-01-24
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-IP_WINDOW = $DF00 ; Address of ISEPIC window
-IP_CTRL_BASE = $DE00
-PAGES = 8
-
-; ------------------------------------------------------------------------
-; 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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- lda #0
- sta IP_CTRL_BASE
- ldx IP_WINDOW
- cpx IP_WINDOW
- bne @notpresent
- inc IP_WINDOW
- cpx IP_WINDOW
- beq @notpresent
- ldx IP_WINDOW
- sta IP_CTRL_BASE+1
- inx
- stx IP_WINDOW
- dex
- sta IP_CTRL_BASE
- cpx IP_WINDOW
- beq @setok
-
-@notpresent:
- lda #<EM_ERR_NO_DEVICE
- ldx #>EM_ERR_NO_DEVICE
- rts
-
-@setok:
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda #<PAGES
- ldx #>PAGES
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-; The Isepic cartridge does not copy but actually map the window, so USE is
-; identical to MAP.
-
-USE := MAP
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP:
- tax
- sta IP_CTRL_BASE,x
- lda #<IP_WINDOW
- ldx #>IP_WINDOW
-
-; Use the RTS from COMMIT below to save a precious byte of storage
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT:
- rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1:
- lda IP_WINDOW,x
- sta (ptr2),y
- iny
- bne @L2
- inc ptr2+1
-@L2:
- inx
- beq @L4
-
-; Bump count and repeat
-
-@L3:
- inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4:
- inc tmp1 ; Bump low page register
-@L5:
- stx tmp2
- ldx tmp1
- sta IP_CTRL_BASE,x
- ldx tmp2
- jmp @L3
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1:
- lda (ptr2),y
- sta IP_WINDOW,x
- iny
- bne @L2
- inc ptr2+1
-@L2:
- inx
- beq @L4
-
-; Bump count and repeat
-
-@L3:
- inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4:
- inc tmp1 ; Bump page register
-@L5:
- stx tmp2
- ldx tmp1
- sta IP_CTRL_BASE,x
- ldx tmp2
- jmp @L3
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-
-setup:
- sta ptr1
- stx ptr1+1 ; Save passed pointer
-
-; Get the page number from the struct and remember it.
-
- ldy #EM_COPY::PAGE
- lda (ptr1),y
- sta tmp1
-
-; Get the buffer pointer into ptr2
-
- ldy #EM_COPY::BUF
- lda (ptr1),y
- sta ptr2
- iny
- lda (ptr1),y
- sta ptr2+1
-
-; Get the count, calculate -(count-1) and store it into ptr3
-
- ldy #EM_COPY::COUNT
- lda (ptr1),y
- eor #$FF
- sta ptr3
- iny
- lda (ptr1),y
- eor #$FF
- sta ptr3+1
-
-; Get the page offset into X and clear Y
-
- ldy #EM_COPY::OFFS
- lda (ptr1),y
- tax
- ldy #0
-
-; Done
-
- rts
+++ /dev/null
-;
-; Driver for a "joystick mouse".
-;
-; Ullrich von Bassewitz, 2004-03-29, 2009-09-26
-; 2010-02-08, Greg King
-;
-; The driver prevents the keyboard from interfering by changing the
-; keyboard's output port into an input port while the driver reads its
-; controller device. That disables a wire that is left active by the
-; Kernal. That wire is used by the STOP-key to break out of BASIC
-; programs -- CC65 programs don't use that feature. The wire is shared
-; by these keys: STOP, "Q", Commodore, Space, "2", CTRL, Left-Arrow, and
-; "1". I listed them, in order, from bit 7 over to bit 0. The
-; rightmost five keys can look like joystick switches.
-;
-; The driver prevents the mouse/joystick from interfering by "blinding"
-; the keyboard scanner while any button/switch is active. It changes
-; the input port into an output port, then stores all zero-bits in that
-; port's latch. Reading from an output port sees the bitwise-AND of the
-; latch and the input signals. Therefore, the scanner thinks that eight
-; keys are being pushed at the same time. It doesn't know what to do
-; about that condition; so, it does nothing. The driver lets the
-; scanner see normally, again, when no buttons/switches are active.
-;
-
- .include "zeropage.inc"
- .include "mouse-kernel.inc"
- .include "c64.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-HEADER:
-
-; Driver signature
-
- .byte $6d, $6f, $75 ; "mou"
- .byte MOUSE_API_VERSION ; Mouse driver API version number
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr HIDE
- .addr SHOW
- .addr SETBOX
- .addr GETBOX
- .addr MOVE
- .addr BUTTONS
- .addr POS
- .addr INFO
- .addr IOCTL
- .addr IRQ
-
-; Mouse driver flags
-
- .byte MOUSE_FLAG_LATE_IRQ
-
-; Callback table, set by the kernel before INSTALL is called
-
-CHIDE: jmp $0000 ; Hide the cursor
-CSHOW: jmp $0000 ; Show the cursor
-CMOVEX: jmp $0000 ; Move the cursor to X coord
-CMOVEY: jmp $0000 ; Move the cursor to Y coord
-
-
-;----------------------------------------------------------------------------
-; Constants
-
-SCREEN_HEIGHT = 200
-SCREEN_WIDTH = 320
-
-.enum JOY
- UP = $01
- DOWN = $02
- LEFT = $04
- RIGHT = $08
- FIRE = $10
-.endenum
-
-;----------------------------------------------------------------------------
-; Global variables. The bounding box values are sorted so that they can be
-; written with the least effort in the SETBOX and GETBOX routines, so don't
-; reorder them.
-
-.bss
-
-Vars:
-YPos: .res 2 ; Current mouse position, Y
-XPos: .res 2 ; Current mouse position, X
-XMin: .res 2 ; X1 value of bounding box
-YMin: .res 2 ; Y1 value of bounding box
-XMax: .res 2 ; X2 value of bounding box
-YMax: .res 2 ; Y2 value of bounding box
-Buttons: .res 1 ; Button mask
-
-; Temporary value used in the int handler
-
-Temp: .res 1
-
-; Default values for above variables
-
-.rodata
-
-.proc DefVars
- .word SCREEN_HEIGHT/2 ; YPos
- .word SCREEN_WIDTH/2 ; XPos
- .word 0 ; XMin
- .word 0 ; YMin
- .word SCREEN_WIDTH ; XMax
- .word SCREEN_HEIGHT ; YMax
- .byte 0 ; Buttons
-.endproc
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an MOUSE_ERR_xx code in a/x.
-
-INSTALL:
-
-; Initialize variables. Just copy the default stuff over
-
- ldx #.sizeof(DefVars)-1
-@L1: lda DefVars,x
- sta Vars,x
- dex
- bpl @L1
-
-; Be sure the mouse cursor is invisible and at the default location. We
-; need to do that here, because our mouse interrupt handler doesn't set the
-; mouse position if it hasn't changed.
-
- sei
- jsr CHIDE
- lda XPos
- ldx XPos+1
- jsr CMOVEX
- lda YPos
- ldx YPos+1
- jsr CMOVEY
- cli
-
-; Done, return zero (= MOUSE_ERR_OK)
-
- ldx #$00
- txa
- rts
-
-;----------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-
-UNINSTALL = HIDE ; Hide cursor on exit
-
-;----------------------------------------------------------------------------
-; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently visible and should get hidden. For most drivers,
-; no special action is required besides hiding the mouse cursor.
-; No return code required.
-
-HIDE: sei
- jsr CHIDE
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently hidden and should become visible. For most drivers,
-; no special action is required besides enabling the mouse cursor.
-; No return code required.
-
-SHOW: sei
- jsr CSHOW
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SETBOX: Set the mouse bounding box. The parameters are passed as they come
-; from the C program, that is, a pointer to a mouse_box struct in a/x.
-; No checks are done if the mouse is currently inside the box, this is the job
-; of the caller. It is not necessary to validate the parameters, trust the
-; caller and save some code here. No return code required.
-
-SETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda (ptr1),y
- sta XMin,y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; GETBOX: Return the mouse bounding box. The parameters are passed as they
-; come from the C program, that is, a pointer to a mouse_box struct in a/x.
-
-GETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
-
-@L1: lda XMin,y
- sta (ptr1),y
- dey
- bpl @L1
-
- rts
-
-;----------------------------------------------------------------------------
-; MOVE: Move the mouse to a new position. The position is passed as it comes
-; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
-; remove the parameter from the stack on return.
-; No checks are done if the new position is valid (within the bounding box or
-; the screen). No return code required.
-;
-
-MOVE: sei ; No interrupts
-
- sta YPos
- stx YPos+1 ; New Y position
- jsr CMOVEY ; Set it
-
- ldy #$01
- lda (sp),y
- sta XPos+1
- tax
- dey
- lda (sp),y
- sta XPos ; New X position
-
- jsr CMOVEX ; Move the cursor
-
- cli ; Allow interrupts
- rts
-
-;----------------------------------------------------------------------------
-; BUTTONS: Return the button mask in a/x.
-
-BUTTONS:
- lda Buttons
- ldx #$00
- rts
-
-;----------------------------------------------------------------------------
-; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
-; No return code required.
-
-POS: ldy #MOUSE_POS::XCOORD ; Structure offset
-
- sei ; Disable interrupts
- lda XPos ; Transfer the position
- sta (ptr1),y
- lda XPos+1
- iny
- sta (ptr1),y
- lda YPos
- iny
- sta (ptr1),y
- lda YPos+1
- cli ; Enable interrupts
-
- iny
- sta (ptr1),y ; Store last byte
-
- rts ; Done
-
-;----------------------------------------------------------------------------
-; INFO: Returns mouse position and current button mask in the MOUSE_INFO
-; struct pointed to by ptr1. No return code required.
-;
-; We're cheating here to keep the code smaller: The first fields of the
-; mouse_info struct are identical to the mouse_pos struct, so we will just
-; call _mouse_pos to initialize the struct pointer and fill the position
-; fields.
-
-INFO: jsr POS
-
-; Fill in the button state
-
- lda Buttons
- ldy #MOUSE_INFO::BUTTONS
- sta (ptr1),y
-
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>MOUSE_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
-; (so be careful). The routine MUST return carry set if the interrupt has been
-; 'handled' - which means that the interrupt source is gone. Otherwise it
-; MUST return carry clear.
-;
-
-; Avoid crosstalk between the keyboard and a joystick.
-
-IRQ: ldy #%00000000 ; Set ports A and B to input
- sty CIA1_DDRB
- sty CIA1_DDRA ; Keyboard won't look like joystick
- lda CIA1_PRB ; Read Control-Port 1
- dec CIA1_DDRA ; Set port A back to output
- eor #%11111111 ; Bit goes up when switch goes down
- beq @Save ;(bze)
- dec CIA1_DDRB ; Joystick won't look like keyboard
- sty CIA1_PRB ; Set "all keys pushed"
-@Save: sta Temp
-
-; Check for a pressed button and place the result into Buttons
-
- ldx #$00 ; Assume no button pressed
- and #JOY::FIRE ; Check fire button
- beq @L0 ; Jump if not pressed
- ldx #MOUSE_BTN_LEFT ; Left (only) button is pressed
-@L0: stx Buttons
-
-; Check left/right
-
- lda Temp ; Read joystick #0
- and #(JOY::LEFT | JOY::RIGHT)
- beq @SkipX ;
-
-; We will cheat here and rely on the fact that either the left, OR the right
-; bit can be active
-
- and #JOY::RIGHT ; Check RIGHT bit
- bne @Right
- lda #$FF
- tax
- bne @AddX ; Branch always
-@Right: lda #$01
- ldx #$00
-
-; Calculate the new X coordinate (--> a/y)
-
-@AddX: add XPos
- tay ; Remember low byte
- txa
- adc XPos+1
- tax
-
-; Limit the X coordinate to the bounding box
-
- cpy XMin
- sbc XMin+1
- bpl @L1
- ldy XMin
- ldx XMin+1
- jmp @L2
-@L1: txa
-
- cpy XMax
- sbc XMax+1
- bmi @L2
- ldy XMax
- ldx XMax+1
-@L2: sty XPos
- stx XPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jsr CMOVEX
-
-; Calculate the Y movement vector
-
-@SkipX: lda Temp ; Read joystick #0
- and #(JOY::UP | JOY::DOWN) ; Check up/down
- beq @SkipY ;
-
-; We will cheat here and rely on the fact that either the up, OR the down
-; bit can be active
-
- lsr a ; Check UP bit
- bcc @Down
- lda #$FF
- tax
- bne @AddY
-@Down: lda #$01
- ldx #$00
-
-; Calculate the new Y coordinate (--> a/y)
-
-@AddY: add YPos
- tay ; Remember low byte
- txa
- adc YPos+1
- tax
-
-; Limit the Y coordinate to the bounding box
-
- cpy YMin
- sbc YMin+1
- bpl @L3
- ldy YMin
- ldx YMin+1
- jmp @L4
-@L3: txa
-
- cpy YMax
- sbc YMax+1
- bmi @L4
- ldy YMax
- ldx YMax+1
-@L4: sty YPos
- stx YPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jsr CMOVEY
-
-; Done
-
-@SkipY: clc ; Interrupt not handled
- rts
-
+++ /dev/null
-;
-; Joystick driver using C128 number pad in 64 mode.
-; May be used multiple times when linked to the statically application.
-;
-; Stefan Haubenthal, 2004-01-26
-; Based on Ullrich von Bassewitz, 2002-12-20
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "c64.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $02 ; JOY_UP "8"
- .byte $10 ; JOY_DOWN "2"
- .byte $20 ; JOY_LEFT "4"
- .byte $08 ; JOY_RIGHT "6"
- .byte $04 ; JOY_FIRE "5" ENTER
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 1 ; Number of joysticks we support
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-
-.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 ; Assume we have a joystick
- ldx VIC_CLK_128 ; Test for a C128
- cpx #$FF
- bne @C128 ; Jump if we have one
- lda #JOY_ERR_NO_DEVICE ; No C128 -> no numpad
-@C128: ldx #0 ; Set high byte
-
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; 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 #0
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: tax ; Clear high byte
- lda #$FD
- ldy #$FE
- sei
- sta VIC_KBD_128
- lda CIA1_PRB
- and #%00110000
- eor #%00110000
- lsr
- lsr
- sty VIC_KBD_128
- eor CIA1_PRB
- iny
- sty VIC_KBD_128 ; Reset to $FF
- cli
- and #%11111110
- eor #%11111110
- rts
-
+++ /dev/null
-;
-; Driver for a potentiometer "mouse" e.g. Koala Pad
-;
-; Ullrich von Bassewitz, 2004-03-29, 2009-09-26
-; Stefan Haubenthal, 2006-08-20
-;
-
- .include "zeropage.inc"
- .include "mouse-kernel.inc"
- .include "c64.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-HEADER:
-
-; Driver signature
-
- .byte $6d, $6f, $75 ; "mou"
- .byte MOUSE_API_VERSION ; Mouse driver API version number
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr HIDE
- .addr SHOW
- .addr SETBOX
- .addr GETBOX
- .addr MOVE
- .addr BUTTONS
- .addr POS
- .addr INFO
- .addr IOCTL
- .addr IRQ
-
-; Callback table, set by the kernel before INSTALL is called
-
-CHIDE: jmp $0000 ; Hide the cursor
-CSHOW: jmp $0000 ; Show the cursor
-CMOVEX: jmp $0000 ; Move the cursor to X coord
-CMOVEY: jmp $0000 ; Move the cursor to Y coord
-
-
-;----------------------------------------------------------------------------
-; Constants
-
-SCREEN_HEIGHT = 200
-SCREEN_WIDTH = 320
-
-.enum JOY
- UP = $01
- DOWN = $02
- LEFT = $04
- RIGHT = $08
- FIRE = $10
-.endenum
-
-;----------------------------------------------------------------------------
-; Global variables. The bounding box values are sorted so that they can be
-; written with the least effort in the SETBOX and GETBOX routines, so don't
-; reorder them.
-
-.bss
-
-Vars:
-YPos: .res 2 ; Current mouse position, Y
-XPos: .res 2 ; Current mouse position, X
-XMin: .res 2 ; X1 value of bounding box
-YMin: .res 2 ; Y1 value of bounding box
-XMax: .res 2 ; X2 value of bounding box
-YMax: .res 2 ; Y2 value of bounding box
-Buttons: .res 1 ; Button mask
-
-; Temporary value used in the int handler
-
-Temp: .res 1
-
-; Default values for above variables
-
-.rodata
-
-.proc DefVars
- .word SCREEN_HEIGHT/2 ; YPos
- .word SCREEN_WIDTH/2 ; XPos
- .word 0 ; XMin
- .word 0 ; YMin
- .word SCREEN_WIDTH ; XMax
- .word SCREEN_HEIGHT ; YMax
- .byte 0 ; Buttons
-.endproc
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an MOUSE_ERR_xx code in a/x.
-
-INSTALL:
-
-; Initialize variables. Just copy the default stuff over
-
- ldx #.sizeof(DefVars)-1
-@L1: lda DefVars,x
- sta Vars,x
- dex
- bpl @L1
-
-; Be sure the mouse cursor is invisible and at the default location. We
-; need to do that here, because our mouse interrupt handler doesn't set the
-; mouse position if it hasn't changed.
-
- sei
- jsr CHIDE
- lda XPos
- ldx XPos+1
- jsr CMOVEX
- lda YPos
- ldx YPos+1
- jsr CMOVEY
- cli
-
-; Done, return zero (= MOUSE_ERR_OK)
-
- ldx #$00
- txa
- rts
-
-;----------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-
-UNINSTALL = HIDE ; Hide cursor on exit
-
-;----------------------------------------------------------------------------
-; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently visible and should get hidden. For most drivers,
-; no special action is required besides hiding the mouse cursor.
-; No return code required.
-
-HIDE: sei
- jsr CHIDE
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
-; a counter for calls to show/hide, and the driver entry point is only called
-; if the mouse is currently hidden and should become visible. For most drivers,
-; no special action is required besides enabling the mouse cursor.
-; No return code required.
-
-SHOW: sei
- jsr CSHOW
- cli
- rts
-
-;----------------------------------------------------------------------------
-; SETBOX: Set the mouse bounding box. The parameters are passed as they come
-; from the C program, that is, a pointer to a mouse_box struct in a/x.
-; No checks are done if the mouse is currently inside the box, this is the job
-; of the caller. It is not necessary to validate the parameters, trust the
-; caller and save some code here. No return code required.
-
-SETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda (ptr1),y
- sta XMin,y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; GETBOX: Return the mouse bounding box. The parameters are passed as they
-; come from the C program, that is, a pointer to a mouse_box struct in a/x.
-
-GETBOX: sta ptr1
- stx ptr1+1 ; Save data pointer
-
- ldy #.sizeof (MOUSE_BOX)-1
- sei
-
-@L1: lda XMin,y
- sta (ptr1),y
- dey
- bpl @L1
-
- cli
- rts
-
-;----------------------------------------------------------------------------
-; MOVE: Move the mouse to a new position. The position is passed as it comes
-; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
-; remove the parameter from the stack on return.
-; No checks are done if the new position is valid (within the bounding box or
-; the screen). No return code required.
-;
-
-MOVE: sei ; No interrupts
-
- sta YPos
- stx YPos+1 ; New Y position
- jsr CMOVEY ; Set it
-
- ldy #$01
- lda (sp),y
- sta XPos+1
- tax
- dey
- lda (sp),y
- sta XPos ; New X position
-
- jsr CMOVEX ; Move the cursor
-
- cli ; Allow interrupts
- rts
-
-;----------------------------------------------------------------------------
-; BUTTONS: Return the button mask in a/x.
-
-BUTTONS:
- lda Buttons
- ldx #$00
- rts
-
-;----------------------------------------------------------------------------
-; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
-; No return code required.
-
-POS: ldy #MOUSE_POS::XCOORD ; Structure offset
-
- sei ; Disable interrupts
- lda XPos ; Transfer the position
- sta (ptr1),y
- lda XPos+1
- iny
- sta (ptr1),y
- lda YPos
- iny
- sta (ptr1),y
- lda YPos+1
- cli ; Enable interrupts
-
- iny
- sta (ptr1),y ; Store last byte
-
- rts ; Done
-
-;----------------------------------------------------------------------------
-; INFO: Returns mouse position and current button mask in the MOUSE_INFO
-; struct pointed to by ptr1. No return code required.
-;
-; We're cheating here to keep the code smaller: The first fields of the
-; mouse_info struct are identical to the mouse_pos struct, so we will just
-; call _mouse_pos to initialize the struct pointer and fill the position
-; fields.
-
-INFO: jsr POS
-
-; Fill in the button state
-
- lda Buttons
- ldy #MOUSE_INFO::BUTTONS
- sta (ptr1),y
-
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>MOUSE_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
-; (so be careful).
-;
-
-IRQ: lda #$7F
- sta CIA1_PRA
- lda CIA1_PRB ; Read port #1
- and #%00001100
- eor #%00001100 ; Make all bits active high
- asl
- sta Buttons
- lsr
- lsr
- lsr
- and #%00000001
- ora Buttons
- sta Buttons
- ldx #%01000000
- stx CIA1_PRA
- ldy #0
-: dey
- bne :-
- ldx SID_ADConv1
- stx XPos
- ldx SID_ADConv2
- stx YPos
-
- lda #$FF
- tax
- bne @AddX ; Branch always
- lda #$01
- ldx #$00
-
-; Calculate the new X coordinate (--> a/y)
-
-@AddX: add XPos
- tay ; Remember low byte
- txa
- adc XPos+1
- tax
-
-; Limit the X coordinate to the bounding box
-
- cpy XMin
- sbc XMin+1
- bpl @L1
- ldy XMin
- ldx XMin+1
- jmp @L2
-@L1: txa
-
- cpy XMax
- sbc XMax+1
- bmi @L2
- ldy XMax
- ldx XMax+1
-@L2: sty XPos
- stx XPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jsr CMOVEX
-
- lda #$FF
- tax
- bne @AddY
-@Down: lda #$01
- ldx #$00
-
-; Calculate the new Y coordinate (--> a/y)
-
-@AddY: add YPos
- tay ; Remember low byte
- txa
- adc YPos+1
- tax
-
-; Limit the Y coordinate to the bounding box
-
- cpy YMin
- sbc YMin+1
- bpl @L3
- ldy YMin
- ldx YMin+1
- jmp @L4
-@L3: txa
-
- cpy YMax
- sbc YMax+1
- bmi @L4
- ldy YMax
- ldx YMax+1
-@L4: sty YPos
- stx YPos+1
-
-; Move the mouse pointer to the new X pos
-
- tya
- jmp CMOVEY
+++ /dev/null
-;
-; PTV-4 Player joystick driver for the C64
-;
-; Groepaz/Hitmen, 2002-12-23
-; obviously based on Ullrichs driver :)
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "c64.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
- .segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 4 ; Number of joysticks we support
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: tax ; Joystick number into X
- bne joy2
-
-; Read joystick 1
-
-joy1: lda #$7F
- sei
- sta CIA1_PRA
- lda CIA1_PRB
- cli
- and #$1F
- eor #$1F
- rts
-
-; Read joystick 2
-
-joy2: dex
- bne joy3
-
- lda #$E0
- ldy #$FF
- sei
- sta CIA1_DDRA
- lda CIA1_PRA
- sty CIA1_DDRA
- cli
- and #$1F
- eor #$1F
- rts
-
-; Read joystick 3
-
-joy3:
- lda #%10000000 ; cia 2 port B Data-Direction
- sta CIA2_DDRB ; bit 7: out bit 6-0: in
-
- dex
- bne joy4
-
- lda #$80 ; cia 2 port B read/write
- sta CIA2_PRB ; (output one at PB7)
-
- lda CIA2_PRB ; cia 2 port B read/write
- and #$1f ; get bit 4-0 (PB4-PB0)
- eor #$1f
- rts
-
-; Read joystick 4
-
-joy4: lda #$00 ; cia 2 port B read/write
- sta CIA2_PRB ; (output zero at PB7)
-
- lda CIA2_PRB ; cia 2 port B read/write
- and #$0f ; get bit 3-0 (PB3-PB0)
- sta tmp1 ; joy 4 directions
-
- lda CIA2_PRB ; cia 2 port B read/write
- and #%00100000 ; get bit 5 (PB5)
- lsr
- ora tmp1
- eor #$1f
-
- ldx #0
- rts
-
+++ /dev/null
-;
-; Extended memory driver for the C64 hidden RAM. Driver works without
-; problems when statically linked.
-;
-; Ullrich von Bassewitz, 2002-12-02
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-BASE = $D000
-PAGES = ($10000 - BASE) / 256
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-curpage: .res 1 ; Current page number
-window: .res 256 ; Memory "window"
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx #$FF
- stx curpage ; Invalidate the current page
- inx ; X = 0
- txa ; A = X = EM_ERR_OK
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda #<PAGES
- ldx #>PAGES
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage ; Remember the new page
-
- clc
- adc #>BASE
- sta ptr1+1
- ldy #$00
- sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
-; Transfer one page
-
- jsr transfer ; Transfer one page
-
-; Return the memory window
-
- lda #<window
- ldx #>window ; Return the window address
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage ; Get the current page
- bmi done ; Jump if no page mapped
-
- clc
- adc #>BASE
- sta ptr2+1
- ldy #$00
- sty ptr2
-
- lda #<window
- sta ptr1
- lda #>window
- sta ptr1+1
-
-; Transfer one page. Y must be zero on entry
-
-transfer:
- ldx $01 ; Remember c64 control port
- txa
- and #$F8 ; Bank out ROMs, I/O
- sei
- sta $01
-
-; Unroll the following loop
-
-loop: .repeat 8
- lda (ptr1),y
- sta (ptr2),y
- iny
- .endrepeat
-
- bne loop
-
-; Restore the old memory configuration, allow interrupts
-
- stx $01 ; Restore the old configuration
- cli
-
-; Done
-
-done: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- clc
- adc #>BASE
- sta ptr1+1 ; From
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; To
-
-common: ldy #EM_COPY::COUNT+1
- lda (ptr3),y ; Get number of pages
- beq @L2 ; Skip if no full pages
- sta tmp1
-
-; Copy full pages allowing interrupts after each page copied
-
- ldy #$00
-@L1: jsr transfer
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- tax
-
- lda $01 ; Remember c64 control port
- pha
- and #$F8 ; Bank out ROMs, I/O
- sei
- sta $01
-
-; Transfer the bytes in the last page
-
- ldy #$00
-@L3: lda (ptr1),y
- sta (ptr2),y
- iny
- dex
- bne @L3
-
-; Restore the old memory configuration, allow interrupts
-
- pla
- sta $01 ; Restore the old configuration
- cli
-
-; Done
-
-@L4: rts
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO: sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr2
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- clc
- adc #>BASE
- sta ptr2+1 ; To
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr1
- iny
- lda (ptr3),y
- sta ptr1+1 ; From
-
- jmp common
-
-
+++ /dev/null
-;
-; Extended memory driver for the RamCart 64/128KB cartridge. Driver works
-; without problems when statically linked.
-; Code is based on GEORAM code by Ullrich von Bassewitz.
-; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
-; 06,22.12.2002
-;
-
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-RAMC_WINDOW = $DF00 ; Address of RamCart window
-RAMC_PAGE_LO = $DE00 ; Page register low
-RAMC_PAGE_HI = $DE01 ; Page register high (only for RC128)
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-
-pagecount: .res 2 ; Number of available pages
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx RAMC_WINDOW
- cpx RAMC_WINDOW
- bne @notpresent
-
- lda #0
- sta RAMC_PAGE_LO
- sta RAMC_PAGE_HI
- ldx RAMC_WINDOW
- cpx RAMC_WINDOW
- bne @notpresent
- lda #2
- sta RAMC_WINDOW
- cmp RAMC_WINDOW
- beq @cont
- cpx RAMC_WINDOW
- beq @readonly
-@cont: ldy #1
- sty RAMC_PAGE_HI
- sty RAMC_WINDOW
- dey
- sty RAMC_PAGE_HI
- iny
- cpy RAMC_WINDOW
- beq @rc64
- ; we're on rc128
- ldx #>512
- bne @setsize
-@rc64: ldx #>256
-@setsize:
- lda #0
- sta pagecount
- stx pagecount+1
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
- rts
-@notpresent:
-@readonly:
- lda #<EM_ERR_NO_DEVICE
- ldx #>EM_ERR_NO_DEVICE
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-; The RamCart cartridge does not copy but actually map the window, so USE is
-; identical to MAP.
-
-USE = MAP
-
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta RAMC_PAGE_LO
- stx RAMC_PAGE_HI
- lda #<RAMC_WINDOW
- ldx #>RAMC_WINDOW
-
-; Use the RTS from COMMIT below to save a precious byte of storage
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - tmp2 contains the high page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1: lda RAMC_WINDOW,x
- sta (ptr2),y
- iny
- bne @L2
- inc ptr2+1
-@L2: inx
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4: inc tmp1
- bne @L5
- inc tmp2
-@L5: lda tmp1
- sta RAMC_PAGE_LO
- lda tmp2
- sta RAMC_PAGE_HI
- jmp @L3
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- jsr setup
-
-; Setup is:
-;
-; - ptr1 contains the struct pointer
-; - ptr2 contains the linear memory buffer
-; - ptr3 contains -(count-1)
-; - tmp1 contains the low page register value
-; - tmp2 contains the high page register value
-; - X contains the page offset
-; - Y contains zero
-
- jmp @L5
-
-@L1: lda (ptr2),y
- sta RAMC_WINDOW,x
- iny
- bne @L2
- inc ptr2+1
-@L2: inx
- beq @L4
-
-; Bump count and repeat
-
-@L3: inc ptr3
- bne @L1
- inc ptr3+1
- bne @L1
- rts
-
-; Bump page register
-
-@L4: inc tmp1
- bne @L5
- inc tmp2
-@L5: lda tmp1
- sta RAMC_PAGE_LO
- lda tmp2
- sta RAMC_PAGE_HI
- jmp @L3
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-
-setup: sta ptr1
- stx ptr1+1 ; Save passed pointer
-
-; Get the page number from the struct and adjust it so that it may be used
-; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
-
- ldy #EM_COPY::PAGE+1
- lda (ptr1),y
- sta tmp2
- dey
- lda (ptr1),y
- sta tmp1
-
-; Get the buffer pointer into ptr2
-
- ldy #EM_COPY::BUF
- lda (ptr1),y
- sta ptr2
- iny
- lda (ptr1),y
- sta ptr2+1
-
-; Get the count, calculate -(count-1) and store it into ptr3
-
- ldy #EM_COPY::COUNT
- lda (ptr1),y
- eor #$FF
- sta ptr3
- iny
- lda (ptr1),y
- eor #$FF
- sta ptr3+1
-
-; Get the page offset into X and clear Y
-
- ldy #EM_COPY::OFFS
- lda (ptr1),y
- tax
- ldy #$00
-
-; Done
-
- rts
-
+++ /dev/null
-;
-; Extended memory driver for the Commodore REU. Driver works without
-; problems when statically linked.
-;
-; Ullrich von Bassewitz, 2002-11-29
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-REU_STATUS = $DF00 ; Status register
-REU_COMMAND = $DF01 ; Command register
-REU_C64ADDR = $DF02 ; C64 base address register
-REU_REUADDR = $DF04 ; REU base address register
-REU_COUNT = $DF07 ; Transfer count register
-REU_IRQMASK = $DF09 ; IRQ mask register
-REU_CONTROL = $DF0A ; Control register
-REU_TRIGGER = $FF00 ; REU command trigger
-
-OP_COPYFROM = $ED
-OP_COPYTO = $EC
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-pagecount: .res 2 ; Number of pages available
-curpage: .res 2 ; Current page number
-
-window: .res 256 ; Memory "window"
-
-reu_params: .word $0000 ; Host address, lo, hi
- .word $0000 ; Exp address, lo, hi
- .byte $00 ; Expansion bank no.
- .word $0000 ; # bytes to move, lo, hi
- .byte $00 ; Interrupt mask reg.
- .byte $00 ; Adress control reg.
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx #$00 ; High byte of return code
- lda #$55
- sta REU_REUADDR
- cmp REU_REUADDR ; Check for presence of REU
- bne nodevice
- asl a ; A = $AA
- sta REU_REUADDR
- cmp REU_REUADDR ; Check for presence of REU
- bne nodevice
-
- ldy #>(128*4) ; Assume 128KB
- lda REU_STATUS
- and #$10 ; Check size bit
- beq @L1
- ldy #>(256*4) ; 256KB when size bit is set
-@L1: sty pagecount+1
-
- ldy #$FF
- sty curpage
- sty curpage+1 ; Invalidate the current page
- txa ; X = A = EM_ERR_OK
- rts
-
-; No REU found
-
-nodevice:
- lda #EM_ERR_NO_DEVICE
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage
- stx curpage+1 ; Remember the new page
-
- ldy #OP_COPYFROM
- jsr common ; Copy the window
-
- lda #<window
- ldx #>window ; Return the window address
-done: rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage
- stx curpage+1 ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage
- ldx curpage+1 ; Do we have a page mapped?
- bmi done ; Jump if no page mapped
-
- ldy #OP_COPYTO
-common: sty tmp1
-
- ldy #<window
- sty REU_C64ADDR
- ldy #>window
- sty REU_C64ADDR+1
-
- ldy #0
- sty REU_REUADDR+0
- sta REU_REUADDR+1
- stx REU_REUADDR+2
-
- sty REU_COUNT+0
- ldy #1
- sty REU_COUNT+1 ; Move 256 bytes
- bne transfer1 ; Transfer 256 bytes into REU
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- ldy #OP_COPYFROM
- .byte $2C
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- ldy #OP_COPYTO
- sty tmp1
-
-; Remember the passed pointer
-
- sta ptr1
- stx ptr1+1 ; Save the pointer
-
-; The structure passed to the functions has the same layout as the registers
-; of the Commodore REU, so register programming is easy.
-
- ldy #7-1
-@L1: lda (ptr1),y
- sta REU_C64ADDR,y
- dey
- bpl @L1
-
-; Invalidate the page in the memory window
-
- sty curpage+1 ; Y = $FF
-
-; Reload the REU command and start the transfer
-
-transfer1:
- ldy tmp1
-
-; Transfer subroutine for the REU. Expects command in Y.
-
-transfer:
- sty REU_COMMAND ; Issue command
-
- ldy $01 ; Save the value of the c64 control port...
- tya ;
- and #$F8 ; Disable ROMs and I/O.
- sei ;
- sta $01
- lda REU_TRIGGER ; Don't change $FF00
- sta REU_TRIGGER ; Start the transfer...
-
- sty $01 ; Restore the old configuration
- cli
- rts
-
+++ /dev/null
-;
-; Standard joystick driver for the C64. May be used multiple times when linked
-; to the statically application.
-;
-; Ullrich von Bassewitz, 2002-12-20
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "c64.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: tax ; Joystick number into X
- bne joy2
-
-; Read joystick 1
-
-joy1: lda #$7F
- sei
- sta CIA1_PRA
- lda CIA1_PRB
- cli
- and #$1F
- eor #$1F
- rts
-
-; Read joystick 2
-
-joy2: ldx #0
- lda #$E0
- ldy #$FF
- sei
- sta CIA1_DDRA
- lda CIA1_PRA
- sty CIA1_DDRA
- cli
- and #$1F
- eor #$1F
- rts
-
-
+++ /dev/null
-;
-; Serial driver for the C64 using a Swiftlink or Turbo-232 cartridge.
-;
-; Ullrich von Bassewitz, 2003-04-18
-;
-; The driver is based on the cc65 rs232 module, which in turn is based on
-; Craig Bruce device driver for the Switftlink/Turbo-232.
-;
-; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
-;
-; This software is Public Domain. It is in Buddy assembler format.
-;
-; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
-; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
-; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
-; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
-;
-; The code assumes that the kernal + I/O are in context. On the C128, call
-; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
-; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
-; interrupt handling assumes that the 65816 is in 6502-emulation mode.
-;
-
- .include "zeropage.inc"
- .include "ser-kernel.inc"
- .include "ser-error.inc"
- .include "c64.inc"
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $73, $65, $72 ; "ser"
- .byte SER_API_VERSION ; Serial API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word OPEN
- .word CLOSE
- .word GET
- .word PUT
- .word STATUS
- .word IOCTL
- .word IRQ
-
-;----------------------------------------------------------------------------
-; I/O definitions
-
-ACIA = $DE00
-ACIA_DATA = ACIA+0 ; Data register
-ACIA_STATUS = ACIA+1 ; Status register
-ACIA_CMD = ACIA+2 ; Command register
-ACIA_CTRL = ACIA+3 ; Control register
-
-;----------------------------------------------------------------------------
-;
-; Global variables
-;
-
-; We reuse the RS232 zero page variables for the driver, since the ROM
-; routines cannot be used together with this driver.
-RecvHead = $B5 ; Head of receive buffer
-RecvTail = $BD ; Tail of receive buffer
-RecvFreeCnt = $F7 ; Number of bytes in receive buffer
-SendHead = $F8 ; Head of send buffer
-SendTail = $F9 ; Tail of send buffer
-SendFreeCnt = $FA ; Number of bytes free in send buffer
-
-.bss
-Stopped: .res 1 ; Flow-stopped flag
-RtsOff: .res 1 ;
-
-; Send and receive buffers: 256 bytes each
-RecvBuf: .res 256
-SendBuf: .res 256
-
-.data
-NmiContinue: .byte $4c ; JMP instruction for NMI save -- continue
-NmiSave: .res 2 ; normal NMI handler
-
-.rodata
-
-; Tables used to translate RS232 params into register values
-
-BaudTable: ; bit7 = 1 means setting is invalid
- .byte $FF ; SER_BAUD_45_5
- .byte $FF ; SER_BAUD_50
- .byte $FF ; SER_BAUD_75
- .byte $FF ; SER_BAUD_110
- .byte $FF ; SER_BAUD_134_5
- .byte $02 ; SER_BAUD_150
- .byte $05 ; SER_BAUD_300
- .byte $06 ; SER_BAUD_600
- .byte $07 ; SER_BAUD_1200
- .byte $FF ; SER_BAUD_1800
- .byte $08 ; SER_BAUD_2400
- .byte $09 ; SER_BAUD_3600
- .byte $0A ; SER_BAUD_4800
- .byte $0B ; SER_BAUD_7200
- .byte $0C ; SER_BAUD_9600
- .byte $0E ; SER_BAUD_19200
- .byte $0F ; SER_BAUD_38400
- .byte $FF ; SER_BAUD_57600
- .byte $FF ; SER_BAUD_115200
- .byte $FF ; SER_BAUD_230400
-
-BitTable:
- .byte $60 ; SER_BITS_5
- .byte $40 ; SER_BITS_6
- .byte $20 ; SER_BITS_7
- .byte $00 ; SER_BITS_8
-
-StopTable:
- .byte $00 ; SER_STOP_1
- .byte $80 ; SER_STOP_2
-
-ParityTable:
- .byte $00 ; SER_PAR_NONE
- .byte $20 ; SER_PAR_ODD
- .byte $60 ; SER_PAR_EVEN
- .byte $A0 ; SER_PAR_MARK
- .byte $E0 ; SER_PAR_SPACE
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an SER_ERR_xx code in a/x.
-
-INSTALL:
-
-; Deactivate DTR and disable 6551 interrupts
-
- lda #%00001010
- sta ACIA_CMD
-
-; Set up the nmi vector
-
- lda NMIVec
- ldy NMIVec+1
- sta NmiSave+0
- sty NmiSave+1
- lda #<NmiHandler
- ldy #>NmiHandler
-SetNMI: sta NMIVec
- sty NMIVec+1
-
-; Done, return an error code
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-;----------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Must return an SER_ERR_xx code in a/x.
-
-UNINSTALL:
-
-; Stop interrupts, drop DTR
-
- lda #%00001010
- sta ACIA_CMD
-
-; Restore NMI vector and return OK
-
- lda NmiSave+0
- ldy NmiSave+1
- jmp SetNMI
-
-;----------------------------------------------------------------------------
-; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-OPEN:
-
-; Check if the handshake setting is valid
-
- ldy #SER_PARAMS::HANDSHAKE ; Handshake
- lda (ptr1),y
- cmp #SER_HS_HW ; This is all we support
- bne InvParam
-
-; Initialize buffers
-
- jsr InitBuffers
-
-; Set the value for the control register, which contains stop bits, word
-; length and the baud rate.
-
- ldy #SER_PARAMS::BAUDRATE
- lda (ptr1),y ; Baudrate index
- tay
- lda BaudTable,y ; Get 6551 value
- bmi InvBaud ; Branch if rate not supported
- sta tmp1
-
- ldy #SER_PARAMS::DATABITS ; Databits
- lda (ptr1),y
- tay
- lda BitTable,y
- ora tmp1
- sta tmp1
-
- ldy #SER_PARAMS::STOPBITS ; Stopbits
- lda (ptr1),y
- tay
- lda StopTable,y
- ora tmp1
- ora #%00010000 ; Receiver clock source = baudrate
- sta ACIA_CTRL
-
-; Set the value for the command register. We remember the base value in
-; RtsOff, since we will have to manipulate ACIA_CMD often.
-
- ldy #SER_PARAMS::PARITY ; Parity
- lda (ptr1),y
- tay
- lda ParityTable,y
- ora #%00000001 ; DTR active
- sta RtsOff
- ora #%00001000 ; Enable receive interrupts
- sta ACIA_CMD
-
-; Done
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-; Invalid parameter
-
-InvParam:
- lda #<SER_ERR_INIT_FAILED
- ldx #>SER_ERR_INIT_FAILED
- rts
-
-; Baud rate not available
-
-InvBaud:
- lda #<SER_ERR_BAUD_UNAVAIL
- ldx #>SER_ERR_BAUD_UNAVAIL
- rts
-
-;----------------------------------------------------------------------------
-; CLOSE: Close the port, disable interrupts and flush the buffer. Called
-; without parameters. Must return an error code in a/x.
-;
-
-CLOSE:
-
-; Stop interrupts, drop DTR
-
- lda #%00001010
- sta ACIA_CMD
-
-; Initalize buffers. Returns zero in a
-
- jsr InitBuffers
-
-; Return OK
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-;----------------------------------------------------------------------------
-; GET: Will fetch a character from the receive buffer and store it into the
-; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
-; return.
-;
-
-GET: ldx SendFreeCnt ; Send data if necessary
- inx ; X == $FF?
- beq @L1
- lda #$00
- jsr TryToSend
-
-; Check for buffer empty
-
-@L1: lda RecvFreeCnt ; (25)
- cmp #$ff
- bne @L2
- lda #<SER_ERR_NO_DATA
- ldx #>SER_ERR_NO_DATA
- rts
-
-; Check for flow stopped & enough free: release flow control
-
-@L2: ldx Stopped ; (34)
- beq @L3
- cmp #63
- bcc @L3
- lda #$00
- sta Stopped
- lda RtsOff
- ora #%00001000
- sta ACIA_CMD
-
-; Get byte from buffer
-
-@L3: ldx RecvHead ; (41)
- lda RecvBuf,x
- inc RecvHead
- inc RecvFreeCnt
- ldx #$00 ; (59)
- sta (ptr1,x)
- txa ; Return code = 0
- rts
-
-;----------------------------------------------------------------------------
-; PUT: Output character in A.
-; Must return an error code in a/x.
-;
-
-PUT:
-
-; Try to send
-
- ldx SendFreeCnt
- inx ; X = $ff?
- beq @L2
- pha
- lda #$00
- jsr TryToSend
- pla
-
-; Put byte into send buffer & send
-
-@L2: ldx SendFreeCnt
- bne @L3
- lda #<SER_ERR_OVERFLOW ; X is already zero
- rts
-
-@L3: ldx SendTail
- sta SendBuf,x
- inc SendTail
- dec SendFreeCnt
- lda #$ff
- jsr TryToSend
- lda #<SER_ERR_OK
- tax
- rts
-
-;----------------------------------------------------------------------------
-; STATUS: Return the status in the variable pointed to by ptr1.
-; Must return an error code in a/x.
-;
-
-STATUS: lda ACIA_STATUS
- ldx #0
- sta (ptr1,x)
- txa ; SER_ERR_OK
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>SER_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Not used on the C64
-;
-
-IRQ = $0000
-
-;----------------------------------------------------------------------------
-;
-; NMI handler
-; C128 NMI overhead=76 cycles: int=7, maxLatency=6, ROMenter=33, ROMexit=30
-; C64 NMI overhead=76 cycles: int=7, maxLatency=6, ROMenter=34, ROMexit=29
-;
-; timing: normal=76+43+9=128 cycles, assertFlow=76+52+9=137 cycles
-;
-; C128 @ 115.2k: 177 cycles avail (fast)
-; C64 @ 57.6k: 177 cycles avail, worstAvail=177-43? = 134
-; SCPU @ 230.4k: 868 cycles avail: for a joke!
-;
-
-NmiHandler:
- pha
- lda ACIA_STATUS ;(4) ;status ;check for byte received
- and #$08 ;(2)
- beq @L9 ;(2*)
- cld
- txa
- pha
- tya
- pha
-@L1: lda ACIA_DATA ;(4) data ;get byte and put into receive buffer
- ldy RecvTail ;(4)
- ldx RecvFreeCnt ;(4)
- beq @L3 ;(2*) Jump if no space in receive buffer
- sta RecvBuf,y ;(5)
- inc RecvTail ;(6)
- dec RecvFreeCnt ;(6)
- cpx #33 ;(2) check for buffer space low
- bcc @L2 ;(2*)
- jmp NMIEXIT ;(3)
-
-; Assert flow control
-
-@L2: lda RtsOff ;(3) assert flow control if buffer space too low
- sta ACIA_CMD ;(4) command
- sta Stopped ;(3)
-@L3: jmp NMIEXIT ;(3)
-
-@L9: pla
- jmp NmiContinue
-
-;----------------------------------------------------------------------------
-; Try to send a byte. Internal routine. A = TryHard
-
-.proc TryToSend
-
- sta tmp1 ; Remember tryHard flag
-@L0: lda SendFreeCnt
- cmp #$ff
- beq @L3 ; Bail out
-
-; Check for flow stopped
-
-@L1: lda Stopped
- bne @L3 ; Bail out
-
-; Check that swiftlink is ready to send
-
-@L2: lda ACIA_STATUS
- and #$10
- bne @L4
- bit tmp1 ;keep trying if must try hard
- bmi @L0
-@L3: rts
-
-; Send byte and try again
-
-@L4: ldx SendHead
- lda SendBuf,x
- sta ACIA_DATA
- inc SendHead
- inc SendFreeCnt
- jmp @L0
-
-.endproc
-
-
-;----------------------------------------------------------------------------
-; Initialize buffers
-
-InitBuffers:
- ldx #0
- stx Stopped
- stx RecvHead
- stx RecvTail
- stx SendHead
- stx SendTail
- dex ; X = 255
- stx RecvFreeCnt
- stx SendFreeCnt
- rts
-
+++ /dev/null
-;
-; Extended memory driver for the VDC RAM available on all C128 machines
-; (based on code by Ullrich von Bassewitz)
-; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
-; 06,20.12.2002
-;
-; VDC test added by
-; Marco van den Heuvel, 2010-01-22
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-VDC_ADDR_REG = $D600 ; VDC address
-VDC_DATA_REG = $D601 ; VDC data
-
-VDC_DATA_HI = 18 ; used registers
-VDC_DATA_LO = 19
-VDC_CSET = 28
-VDC_DATA = 31
-
-; ------------------------------------------------------------------------
-; Data.
-
-.data
-
-pagecount: .word 64 ; $0000-$3fff as 16k default
-curpage: .word $ffff ; currently mapped-in page (invalid)
-
-.bss
-
-window: .res 256 ; memory window
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ldx #0
- ldy #0
- lda #VDC_CSET ; determine size of RAM...
- sta VDC_ADDR_REG
-
-@L0: bit VDC_ADDR_REG
- bmi @present
- inx
- bne @L0
- iny
- bne @L0
- lda #<EM_ERR_NO_DEVICE
- ldx #>EM_ERR_NO_DEVICE
- rts
-
-@present:
- ldx #VDC_CSET ; determine size of RAM...
- jsr vdcgetreg
- sta tmp1
- ora #%00010000
- jsr vdcputreg ; turn on 64k
-
- jsr settestadr1 ; save original value of test byte
- jsr vdcgetbyte
- sta tmp2
-
- lda #$55 ; write $55 here
- ldy #ptr1
- jsr test64k ; read it here and there
- lda #$aa ; write $aa here
- ldy #ptr2
- jsr test64k ; read it here and there
-
- jsr settestadr1
- lda tmp2
- jsr vdcputbyte ; restore original value of test byte
-
- lda ptr1 ; do bytes match?
- cmp ptr1+1
- bne @have64k
- lda ptr2
- cmp ptr2+1
- bne @have64k
-
- ldx #VDC_CSET
- lda tmp1
- jsr vdcputreg ; restore 16/64k flag
- jmp @endok ; and leave default values for 16k
-
-@have64k:
- lda #<256
- ldx #>256
- sta pagecount
- stx pagecount+1
-@endok:
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
- rts
-
-test64k:
- sta tmp1
- sty ptr3
- lda #0
- sta ptr3+1
- jsr settestadr1
- lda tmp1
- jsr vdcputbyte ; write $55
- jsr settestadr1
- jsr vdcgetbyte ; read here
- pha
- jsr settestadr2
- jsr vdcgetbyte ; and there
- ldy #1
- sta (ptr3),y
- pla
- dey
- sta (ptr3),y
- rts
-
-settestadr1:
- ldy #$02 ; test page 2 (here)
- .byte $2c
-settestadr2:
- ldy #$42 ; or page 64+2 (there)
- lda #0
- jmp vdcsetsrcaddr
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- ;on C128 restore font and clear the screen?
- rts
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage
- stx curpage+1
- sta ptr1+1
- ldy #0
- sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
- jsr transferin
-
- lda #<window
- ldx #>window
- rts
-
-; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
-
-transferin:
- lda ptr1
- ldy ptr1+1
- jsr vdcsetsrcaddr ; set source address in VDC
- ldy #0
- ldx #VDC_DATA
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda VDC_DATA_REG ; get 2 bytes at a time to speed-up
- sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config)
- iny
- lda VDC_DATA_REG
- sta (ptr2),y
- iny
- bne @L0
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage
- stx curpage+1 ; Remember the page
- lda #<window
- ldx #>window ; Return the window
-done: rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT:
- lda curpage ; jump if no page mapped
- ldx curpage+1
- bmi done
- sta ptr1+1
- ldy #0
- sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
-; fall through to transferout
-
-; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
-
-transferout:
- lda ptr1
- ldy ptr1+1
- jsr vdcsetsrcaddr ; set source address in VDC
- ldy #0
- ldx #VDC_DATA
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda (ptr2),y ; speedup does not work for writing
- sta VDC_DATA_REG
- iny
- bne @L0
- rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
- beq @L2 ; Skip if no full pages
-
-; Copy full pages
-
-@L1: jsr transferin
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- sta tmp1
-
-; Transfer the bytes in the last page
-
- ldy #0
-@L3: jsr vdcgetbyte
- sta (ptr2),y
- iny
- dec tmp1
- lda tmp1
- bne @L3
-@L4: rts
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- jsr setup
- beq @L2 ; Skip if no full pages
-
-; Copy full pages
-
-@L1: jsr transferout
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- sta tmp1
-
-; Transfer the bytes in the last page
-
- ldy #0
-@L3: lda (ptr2),y
- jsr vdcputbyte
- iny
- dec tmp1
- lda tmp1
- bne @L3
-@L4: rts
-
-;-------------------------------------------------------------------------
-; Helper functions to handle VDC ram
-;
-
-vdcsetsrcaddr:
- ldx #VDC_DATA_LO
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- sta VDC_DATA_REG
- dex
- tya
- stx VDC_ADDR_REG
- sta VDC_DATA_REG
- rts
-
-vdcgetbyte:
- ldx #VDC_DATA
-vdcgetreg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda VDC_DATA_REG
- rts
-
-vdcputbyte:
- ldx #VDC_DATA
-vdcputreg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- sta VDC_DATA_REG
- rts
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-;
-
-setup:
- sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- sta ptr1+1 ; From
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; To
-
- ldy #EM_COPY::COUNT+1
- lda (ptr3),y ; Get number of pages
- sta tmp1
- rts
-
+++ /dev/null
-;
-; Extended memory driver for the C64 D2TV (the second or PAL version).
-; Driver works without problems when statically linked.
-;
-; Ullrich von Bassewitz, 2005-11-27
-;
-
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
- .import _get_ostype
-
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-OP_COPYFROM = %00001101
-OP_COPYTO = %00001111
-
-START_BANK = 2 ; Start at $20000
-PAGES = (2048 - 128) * 4
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-window: .res 256 ; Memory "window"
-
-.data
-
-; The MAP and COMMIT entries will actually call COPYFROM/COPYTO with
-; a pointer to the following data structure:
-
-dma_params: .word window ; Host address
- .byte 0 ; Offset in page
-curpage: .word $0000 ; Page
- .word .sizeof (window); # bytes to move, lo, hi
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
-
-; Check for a DTV
-
- ldx #1
- stx $d03f
- ldx $d040
- cpx $d000
- bne @present
- inc $d000
- cpx $d040
- beq @present
- dec $d000
-
-; DTV not found
-
- lda #<EM_ERR_NO_DEVICE
- ldx #>EM_ERR_NO_DEVICE
- rts
-
-@present:
- ldx #$FF
- stx curpage+1 ; Invalidate curpage
- inx ; X = 0
- txa ; A/X = EM_ERR_OK
-
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda #<PAGES
- ldx #>PAGES
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage
- stx curpage+1 ; Remember the new page
-
- lda #<dma_params
- ldx #>dma_params
- jsr COPYFROM ; Copy data into the window
-
- lda #<window
- ldx #>window ; Return the window address
-done: rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage
- stx curpage+1 ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage+1 ; Do we have a page mapped?
- bmi done ; Jump if no page mapped
-
- lda #<dma_params
- ldx #>dma_params
-
-; Run into COPYTO
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO: sta ptr1
- stx ptr1+1 ; Save the pointer
-
- ldx #OP_COPYTO ; Load the command
- bne transfer
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- sta ptr1
- stx ptr1+1 ; Save the pointer
-
- ldx #OP_COPYFROM
-
-; DTV DMA transfer routine. Expects the command in X.
-; NOTE: We're using knowledge about field order in the EM_COPY struct here!
-
-transfer:
- jsr WAIT ; Wait until DMA is finished
-
-; Modulo disable
-
- ldy #$00
- sty $d31e
-
-; Setup the target address and the source and target steps. Y contains zero,
-; which is EM_COPY::BUF.
-
- sty $d307 ; Source step high = 0
- sty $d309 ; Dest step high = 0
- lda (ptr1),y
- sta $d303 ; Dest address low
- iny ; Y = 1
- sty $d306 ; Source step low = 1
- sty $d308 ; Dest step low = 1
- lda (ptr1),y
- sta $d304
- lda #$40 ; Dest is always RAM, start at $00000
- sta $d305
-
-; Setup the source address. Incrementing Y will make it point to EM_COPY::OFFS.
-; We will allow page numbers higher than PAGES and map them to ROM. This will
-; allow reading the ROM by specifying a page starting with PAGES.
-
- iny ; EM_COPY::OFFS
- lda (ptr1),y
- sta $d300
- iny ; EM_COPY::PAGE
- lda (ptr1),y
- sta $d301
- iny
- lda (ptr1),y
- adc #START_BANK ; Carry clear here from WAIT
- and #$3f
- cmp #>PAGES+START_BANK ; Valid range?
- bcs @L1 ; Jump if no
- ora #$40 ; Address RAM
-@L1: sta $d302
-
-; Length
-
- iny ; EM_COPY::COUNT
- lda (ptr1),y
- sta $d30a
- iny
- lda (ptr1),y
- sta $d30b
-
-; Start DMA
-
- stx $d31f
-
-; Wait until DMA is done
-
-WAIT: lda $d31f
- lsr a
- bcs WAIT
- rts
-
--- /dev/null
+;
+; Extended memory driver for the C256K memory expansion
+; Marco van den Heuvel, 2010-01-27
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BASE = $4000
+PAGES = 3 * 256
+TARGETLOC = $200 ; Target location for copy/check code
+PIA = $DFC0
+
+; ------------------------------------------------------------------------
+; Data.
+
+.data
+
+
+; This function is used to copy code from and to the extended memory
+.proc copy
+template:
+.org ::TARGETLOC ; Assemble for target location
+entry:
+ stx PIA
+stashop = $91 ; 'sta' opcode
+operation := * ; Location and opcode is patched at runtime
+address := *+1
+ lda ($00),y
+ ldx #$dc
+ stx PIA
+ rts
+.reloc
+.endproc
+
+; This function is used to check for the existence of the extended memory
+.proc check
+template:
+.org ::TARGETLOC
+entry:
+ ldy #$00 ; Assume hardware not present
+
+ lda #$fc
+ sta PIA
+ lda $01
+ tax
+ and #$f8
+ sta $01
+ lda $4000
+ cmp $c000
+ bne done ; Jump if not found
+ inc $c000
+ cmp $4000
+ beq done ; Jump if not found
+
+ ; Hardware is present
+ iny
+done: stx $01
+ ldx #$dc
+ stx PIA
+ rts
+.reloc
+.endproc
+
+
+
+.bss
+
+curpage: .res 2 ; Current page number
+curbank: .res 1 ; Current bank
+window: .res 256 ; Memory "window"
+
+; Since the functions above are copied to $200, the current contents of this
+; memory area must be saved into backup storage. Allocate enough space.
+backup: .res .max (.sizeof (copy), .sizeof (check))
+
+
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ lda PIA+1 ; Select Peripheral Registers
+ ora #4
+ sta PIA+1
+ tax
+ lda PIA+3
+ ora #4
+ sta PIA+3
+ tay
+
+ lda #$DC ; Set the default memory bank data
+ sta PIA
+ lda #$FE
+ sta PIA+2
+
+ txa ; Select Data Direction Registers
+ and #$FB
+ sta PIA+1
+ tya
+ and #$FB
+ sta PIA+3
+
+ lda #$FF ; Set the ports to output
+ sta PIA
+ sta PIA+2
+
+ txa
+ and #$C7
+ ora #$30 ; Set CA1 and
+ sta PIA+1 ; select Peripheral Registers
+ sty PIA+3
+
+ jsr backup_and_setup_check_routine
+ jsr check::entry
+ cli
+ ldx #.sizeof (check) - 1
+ jsr restore_data
+ cpy #$01
+ beq @present
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+ rts
+
+@present:
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda #<PAGES
+ ldx #>PAGES
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP:
+ sei
+ sta curpage ; Remember the new page
+ stx curpage+1
+ jsr adjust_page_and_bank
+ stx curbank
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+ jsr backup_and_setup_copy_routine
+ ldx #<ptr1
+ stx copy::address
+@L1:
+ ldx curbank
+ jsr copy::entry
+ ldx ptr1
+ sta window,x
+ inc ptr1
+ bne @L1
+
+; Return the memory window
+
+ jsr restore_copy_routine
+ lda #<window
+ ldx #>window ; Return the window address
+ cli
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage ; Remember the page
+ stx curpage+1
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT:
+ sei
+ lda curpage ; Get the current page
+ ldx curpage+1
+
+ jsr adjust_page_and_bank
+ stx curbank
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+ jsr backup_and_setup_copy_routine
+ ldx #<ptr1
+ stx copy::address
+ ldx #<copy::stashop
+ stx copy::operation
+@L1:
+ ldx ptr1
+ lda window,x
+ ldx curbank
+ jsr copy::entry
+ inc ptr1
+ bne @L1
+
+; Return the memory window
+
+ jsr restore_copy_routine
+done:
+ cli
+ rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+
+COPYFROM:
+ sei
+ jsr setup
+ jsr backup_and_setup_copy_routine
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - ptr4 contains the page memory buffer plus offset
+; - tmp1 contains zero (to be used for linear memory buffer offset)
+; - tmp2 contains the bank value
+
+ lda #<ptr4
+ sta copy::address
+ jmp @L3
+
+@L1:
+ ldx tmp2
+ ldy #0
+ jsr copy::entry
+ ldy tmp1
+ sta (ptr2),y
+ inc tmp1
+ bne @L2
+ inc ptr2+1
+@L2:
+ inc ptr4
+ beq @L4
+
+; Bump count and repeat
+
+@L3:
+ inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ jsr restore_copy_routine
+ cli
+ rts
+
+; Bump page register
+
+@L4:
+ inc ptr4+1
+ lda ptr4+1
+ cmp #$80
+ bne @L3
+ lda #>BASE
+ sta ptr4+1
+ lda tmp2
+ clc
+ adc #$10
+ sta tmp2
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ sei
+ jsr setup
+ jsr backup_and_setup_copy_routine
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - ptr4 contains the page memory buffer plus offset
+; - tmp1 contains zero (to be used for linear memory buffer offset)
+; - tmp2 contains the bank value
+
+ lda #<ptr4
+ sta copy::address
+ lda #<copy::stashop
+ sta copy::operation
+ jmp @L3
+
+@L1:
+ ldy tmp1
+ lda (ptr2),y
+ ldx tmp2
+ ldy #0
+ jsr copy::entry
+ inc tmp1
+ bne @L2
+ inc ptr2+1
+@L2:
+ inc ptr4
+ beq @L4
+
+; Bump count and repeat
+
+@L3:
+ inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ jsr restore_copy_routine
+ cli
+ rts
+
+; Bump page register
+
+@L4:
+ inc ptr4+1
+ lda ptr4+1
+ cmp #$80
+ bne @L3
+ lda #>BASE
+ sta ptr4+1
+ lda tmp2
+ clc
+ adc #$10
+ sta tmp2
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+
+setup:
+ sta ptr1
+ stx ptr1+1 ; Save passed pointer
+
+; Get the page number from the struct and adjust it so that it may be used
+; with the hardware. That is: ptr4 has the page address and page offset
+; tmp2 will hold the bank value
+
+ ldy #EM_COPY::PAGE+1
+ lda (ptr1),y
+ tax
+ ldy #EM_COPY::PAGE
+ lda (ptr1),y
+ jsr adjust_page_and_bank
+ clc
+ adc #>BASE
+ sta ptr4+1
+ stx tmp2
+
+; Get the buffer pointer into ptr2
+
+ ldy #EM_COPY::BUF
+ lda (ptr1),y
+ sta ptr2
+ iny
+ lda (ptr1),y
+ sta ptr2+1
+
+; Get the count, calculate -(count-1) and store it into ptr3
+
+ ldy #EM_COPY::COUNT
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3
+ iny
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3+1
+
+; Get the page offset into ptr4 and clear tmp1
+
+ ldy #EM_COPY::OFFS
+ lda (ptr1),y
+ sta ptr4
+ lda #0
+ sta tmp1
+
+; Done
+
+ rts
+
+; Helper routines for copying to and from the +256k ram
+
+backup_and_setup_copy_routine:
+ ldx #.sizeof (copy) - 1
+@L1:
+ lda copy::entry,x
+ sta backup,x
+ lda copy::template,x
+ sta copy::entry,x
+ dex
+ bpl @L1
+ rts
+
+backup_and_setup_check_routine:
+ ldx #.sizeof (check) - 1
+@L1:
+ lda check::entry,x
+ sta backup,x
+ lda check::template,x
+ sta check::entry,x
+ dex
+ bpl @L1
+ rts
+
+restore_copy_routine:
+ ldx #.sizeof (copy) - 1
+restore_data:
+ lda backup,x
+ sta TARGETLOC,x
+ dex
+ bpl restore_data
+ rts
+
+; Helper routine to correct for the bank and page
+adjust_page_and_bank:
+ sta tmp4
+ lda #$0C
+ sta tmp3
+ lda tmp4
+ and #$c0
+ lsr
+ lsr
+ ora tmp3
+ sta tmp3
+ txa
+ asl
+ asl
+ asl
+ asl
+ asl
+ asl
+ ora tmp3
+ tax
+ lda tmp4
+ and #$3f
+ rts
--- /dev/null
+;
+; Extended memory driver for the Double Quick Brown Box cartridge
+; Marco van den Heuvel, 2010-01-27
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BASE = $8000
+PAGES = ($C000 - BASE) / 256
+TARGETLOC = $200 ; Target location for copy/check code
+CONTROL = $DE00
+
+; ------------------------------------------------------------------------
+; Data.
+
+.proc check
+template:
+.org ::TARGETLOC ; Assemble for target location
+entry:
+ lda $01
+ pha
+ lda #$37
+ sta $01
+ ldx #$14
+ ldy #$90
+ sty CONTROL
+ lda $8000
+ stx CONTROL
+ cmp $8000
+ bne present
+ sty CONTROL
+ inc $8000
+ stx CONTROL
+ cmp $8000
+ beq present
+ dec $8000
+ ldy #$00
+
+done: pla
+ sta $01
+ rts
+
+present:
+ sty CONTROL
+ ldy #$01
+ bne done
+.reloc
+.endproc
+
+
+.proc copy
+template:
+.org ::TARGETLOC ; Assemble for target location
+entry:
+.proc fetch
+ stx CONTROL
+ ldx $01
+ lda #$37
+ sta $01
+address := *+1 ; Patched at runtime
+ lda ($00),y
+ stx $01
+ ldx #$90
+ stx CONTROL
+ rts
+.endproc
+
+.proc stash
+ stx CONTROL
+ ldx $01
+ ldy #$37
+ sty $01
+ ldy #$00
+address := *+1 ; Patched at runtime
+ sta ($00),y
+ stx $01
+ ldx #$90
+ stx CONTROL
+ rts
+.endproc
+.reloc
+.endproc
+
+
+.bss
+
+curpage: .res 1 ; Current page number
+window: .res 256 ; Memory "window"
+
+; Since the functions above are copied to $200, the current contents of this
+; memory area must be saved into backup storage. Allocate enough space.
+backup: .res .max (.sizeof (copy), .sizeof (check))
+
+
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ sei
+ jsr backup_and_setup_check_routine
+ jsr check::entry
+ cli
+ ldx #.sizeof (check) - 1
+ jsr restore_data
+ cpy #$01
+ beq @present
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+ rts
+
+@present:
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda #<PAGES
+ ldx #>PAGES
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP:
+ sei
+ sta curpage ; Remember the new page
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+ jsr backup_and_setup_copy_routine
+ ldx #<ptr1
+ stx copy::fetch::address
+@L1:
+ ldx #$14
+ jsr copy::fetch
+ ldx ptr1
+ sta window,x
+ inc ptr1
+ bne @L1
+
+; Return the memory window
+
+ jsr restore_copy_routine
+ lda #<window
+ ldx #>window ; Return the window address
+ cli
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT:
+ sei
+ lda curpage ; Get the current page
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+ jsr backup_and_setup_copy_routine
+ ldx #<ptr1
+ stx copy::stash::address
+@L1:
+ ldx ptr1
+ lda window,x
+ ldx #$14
+ jsr copy::stash
+ inc ptr1
+ bne @L1
+
+; Return the memory window
+
+ jsr restore_copy_routine
+ cli
+ rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+
+COPYFROM:
+ sei
+ pha
+ txa
+ pha
+ jsr backup_and_setup_copy_routine
+ pla
+ tax
+ pla
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - ptr4 contains the page memory buffer plus offset
+; - tmp1 contains zero (to be used for linear memory buffer offset)
+
+ lda #<ptr4
+ sta copy::fetch::address
+ jmp @L3
+
+@L1:
+ ldx #$14
+ ldy #0
+ jsr copy::fetch
+ ldy tmp1
+ sta (ptr2),y
+ inc tmp1
+ bne @L2
+ inc ptr2+1
+@L2:
+ inc ptr4
+ beq @L4
+
+; Bump count and repeat
+
+@L3:
+ inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ jsr restore_copy_routine
+ cli
+ rts
+
+; Bump page register
+
+@L4:
+ inc ptr4+1
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ sei
+ pha
+ txa
+ pha
+ jsr backup_and_setup_copy_routine
+ pla
+ tax
+ pla
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - ptr4 contains the page memory buffer plus offset
+; - tmp1 contains zero (to be used for linear memory buffer offset)
+
+ lda #<ptr4
+ sta copy::stash::address
+ jmp @L3
+
+@L1:
+ ldy tmp1
+ lda (ptr2),y
+ ldx #$14
+ ldy #0
+ jsr copy::stash
+ inc tmp1
+ bne @L2
+ inc ptr2+1
+@L2:
+ inc ptr4
+ beq @L4
+
+; Bump count and repeat
+
+@L3:
+ inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ jsr restore_copy_routine
+ cli
+ rts
+
+; Bump page register
+
+@L4:
+ inc ptr4+1
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+
+setup:
+ sta ptr1
+ stx ptr1+1 ; Save passed pointer
+
+; Get the page number from the struct and adjust it so that it may be used
+; with the hardware. That is: ptr4 has the page address and page offset
+; tmp2 will hold the bank value
+
+ ldy #EM_COPY::PAGE
+ lda (ptr1),y
+ clc
+ adc #>BASE
+ sta ptr4+1
+
+; Get the buffer pointer into ptr2
+
+ ldy #EM_COPY::BUF
+ lda (ptr1),y
+ sta ptr2
+ iny
+ lda (ptr1),y
+ sta ptr2+1
+
+; Get the count, calculate -(count-1) and store it into ptr3
+
+ ldy #EM_COPY::COUNT
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3
+ iny
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3+1
+
+; Get the page offset into ptr4 and clear tmp1
+
+ ldy #EM_COPY::OFFS
+ lda (ptr1),y
+ sta ptr4
+ lda #0
+ sta tmp1
+
+; Done
+
+ rts
+
+; Helper routines for copying to and from the +256k ram
+
+backup_and_setup_copy_routine:
+ ldx #.sizeof (copy) - 1
+@L1:
+ lda copy::entry,x
+ sta backup,x
+ lda copy::template,x
+ sta copy::entry,x
+ dex
+ bpl @L1
+ rts
+
+backup_and_setup_check_routine:
+ ldx #.sizeof (check) - 1
+@L1:
+ lda check::entry,x
+ sta backup,x
+ lda check::template,x
+ sta check::entry,x
+ dex
+ bpl @L1
+ rts
+
+restore_copy_routine:
+ ldx #.sizeof (copy) - 1
+restore_data:
+ lda backup,x
+ sta TARGETLOC,x
+ dex
+ bpl restore_data
+ rts
--- /dev/null
+;
+; Extended memory driver for the GEORAM cartridge. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2002-11-29
+;
+; GEORAM page size checking routine by
+; Marco van den Heuvel, 2010-01-21
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+GR_WINDOW = $DE00 ; Address of GEORAM window
+GR_PAGE_LO = $DFFE ; Page register low
+GR_PAGE_HI = $DFFF ; Page register high
+
+; ------------------------------------------------------------------------
+; Data.
+
+.data
+
+pagecount: .res 2 ; Number of available pages
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx GR_WINDOW
+ cpx GR_WINDOW
+ bne @notpresent
+ inc GR_WINDOW
+ cpx GR_WINDOW
+ beq @notpresent
+
+ lda #4
+ jsr check
+ cpy GR_WINDOW
+ beq @has64k
+ lda #8
+ jsr check
+ cpy GR_WINDOW
+ beq @has128k
+ lda #16
+ jsr check
+ cpy GR_WINDOW
+ beq @has256k
+ lda #32
+ jsr check
+ cpy GR_WINDOW
+ beq @has512k
+ lda #64
+ jsr check
+ cpy GR_WINDOW
+ beq @has1024k
+ lda #128
+ jsr check
+ cpy GR_WINDOW
+ beq @has2048k
+ ldx #>16384
+ bne @setok
+
+@has64k:
+ ldx #>256
+ bne @setok
+@has128k:
+ ldx #>512
+ bne @setok
+@has256k:
+ ldx #>1024
+ bne @setok
+@has512k:
+ ldx #>2048
+ bne @setok
+@has1024k:
+ ldx #>4096
+ bne @setok
+@has2048k:
+ ldx #>8192
+ bne @setok
+
+@notpresent:
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+ rts
+
+@setok:
+ lda #0
+ sta pagecount
+ stx pagecount+1
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+ rts
+
+check:
+ ldx #0
+ stx GR_PAGE_LO
+ stx GR_PAGE_HI
+ ldy GR_WINDOW
+ iny
+ sta GR_PAGE_HI
+ sty GR_WINDOW
+ ldx #0
+ stx GR_PAGE_HI
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+; The GeoRAM cartridge does not copy but actually map the window, so USE is
+; identical to MAP.
+
+USE = MAP
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta tmp1
+ txa
+ asl tmp1
+ rol a
+ asl tmp1
+ rol a
+
+ sta GR_PAGE_HI
+ lda tmp1
+ lsr a
+ lsr a
+ sta GR_PAGE_LO
+
+ lda #<GR_WINDOW
+ ldx #>GR_WINDOW
+
+; Use the RTS from COMMIT below to save a precious byte of storage
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - tmp2 contains the high page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1: lda GR_WINDOW,x
+ sta (ptr2),y
+ iny
+ bne @L2
+ inc ptr2+1
+@L2: inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4: inc tmp1 ; Bump low page register
+ bit tmp1 ; Check for overflow in bit 6
+ bvc @L6 ; Jump if no overflow
+ inc tmp2
+@L5: lda tmp2
+ sta GR_PAGE_HI
+@L6: lda tmp1
+ sta GR_PAGE_LO
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - tmp2 contains the high page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1: lda (ptr2),y
+ sta GR_WINDOW,x
+ iny
+ bne @L2
+ inc ptr2+1
+@L2: inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4: inc tmp1 ; Bump low page register
+ bit tmp1 ; Check for overflow in bit 6
+ bvc @L6 ; Jump if no overflow
+ inc tmp2
+@L5: lda tmp2
+ sta GR_PAGE_HI
+@L6: lda tmp1
+ sta GR_PAGE_LO
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+
+setup: sta ptr1
+ stx ptr1+1 ; Save passed pointer
+
+; Get the page number from the struct and adjust it so that it may be used
+; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
+
+ ldy #EM_COPY::PAGE+1
+ lda (ptr1),y
+ sta tmp2
+ dey
+ lda (ptr1),y
+ asl a
+ rol tmp2
+ asl a
+ rol tmp2
+ lsr a
+ lsr a
+ sta tmp1
+
+; Get the buffer pointer into ptr2
+
+ ldy #EM_COPY::BUF
+ lda (ptr1),y
+ sta ptr2
+ iny
+ lda (ptr1),y
+ sta ptr2+1
+
+; Get the count, calculate -(count-1) and store it into ptr3
+
+ ldy #EM_COPY::COUNT
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3
+ iny
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3+1
+
+; Get the page offset into X and clear Y
+
+ ldy #EM_COPY::OFFS
+ lda (ptr1),y
+ tax
+ ldy #$00
+
+; Done
+
+ rts
+
+
--- /dev/null
+;
+; Extended memory driver for the ISEPIC cartridge.
+; Marco van den Heuvel, 2010-01-24
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+IP_WINDOW = $DF00 ; Address of ISEPIC window
+IP_CTRL_BASE = $DE00
+PAGES = 8
+
+; ------------------------------------------------------------------------
+; 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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ lda #0
+ sta IP_CTRL_BASE
+ ldx IP_WINDOW
+ cpx IP_WINDOW
+ bne @notpresent
+ inc IP_WINDOW
+ cpx IP_WINDOW
+ beq @notpresent
+ ldx IP_WINDOW
+ sta IP_CTRL_BASE+1
+ inx
+ stx IP_WINDOW
+ dex
+ sta IP_CTRL_BASE
+ cpx IP_WINDOW
+ beq @setok
+
+@notpresent:
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+ rts
+
+@setok:
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda #<PAGES
+ ldx #>PAGES
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+; The Isepic cartridge does not copy but actually map the window, so USE is
+; identical to MAP.
+
+USE := MAP
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP:
+ tax
+ sta IP_CTRL_BASE,x
+ lda #<IP_WINDOW
+ ldx #>IP_WINDOW
+
+; Use the RTS from COMMIT below to save a precious byte of storage
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT:
+ rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1:
+ lda IP_WINDOW,x
+ sta (ptr2),y
+ iny
+ bne @L2
+ inc ptr2+1
+@L2:
+ inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3:
+ inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4:
+ inc tmp1 ; Bump low page register
+@L5:
+ stx tmp2
+ ldx tmp1
+ sta IP_CTRL_BASE,x
+ ldx tmp2
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1:
+ lda (ptr2),y
+ sta IP_WINDOW,x
+ iny
+ bne @L2
+ inc ptr2+1
+@L2:
+ inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3:
+ inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4:
+ inc tmp1 ; Bump page register
+@L5:
+ stx tmp2
+ ldx tmp1
+ sta IP_CTRL_BASE,x
+ ldx tmp2
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+
+setup:
+ sta ptr1
+ stx ptr1+1 ; Save passed pointer
+
+; Get the page number from the struct and remember it.
+
+ ldy #EM_COPY::PAGE
+ lda (ptr1),y
+ sta tmp1
+
+; Get the buffer pointer into ptr2
+
+ ldy #EM_COPY::BUF
+ lda (ptr1),y
+ sta ptr2
+ iny
+ lda (ptr1),y
+ sta ptr2+1
+
+; Get the count, calculate -(count-1) and store it into ptr3
+
+ ldy #EM_COPY::COUNT
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3
+ iny
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3+1
+
+; Get the page offset into X and clear Y
+
+ ldy #EM_COPY::OFFS
+ lda (ptr1),y
+ tax
+ ldy #0
+
+; Done
+
+ rts
--- /dev/null
+;
+; Extended memory driver for the C64 hidden RAM. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2002-12-02
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+BASE = $D000
+PAGES = ($10000 - BASE) / 256
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+curpage: .res 1 ; Current page number
+window: .res 256 ; Memory "window"
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx #$FF
+ stx curpage ; Invalidate the current page
+ inx ; X = 0
+ txa ; A = X = EM_ERR_OK
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda #<PAGES
+ ldx #>PAGES
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage ; Remember the new page
+
+ clc
+ adc #>BASE
+ sta ptr1+1
+ ldy #$00
+ sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+; Transfer one page
+
+ jsr transfer ; Transfer one page
+
+; Return the memory window
+
+ lda #<window
+ ldx #>window ; Return the window address
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage ; Get the current page
+ bmi done ; Jump if no page mapped
+
+ clc
+ adc #>BASE
+ sta ptr2+1
+ ldy #$00
+ sty ptr2
+
+ lda #<window
+ sta ptr1
+ lda #>window
+ sta ptr1+1
+
+; Transfer one page. Y must be zero on entry
+
+transfer:
+ ldx $01 ; Remember c64 control port
+ txa
+ and #$F8 ; Bank out ROMs, I/O
+ sei
+ sta $01
+
+; Unroll the following loop
+
+loop: .repeat 8
+ lda (ptr1),y
+ sta (ptr2),y
+ iny
+ .endrepeat
+
+ bne loop
+
+; Restore the old memory configuration, allow interrupts
+
+ stx $01 ; Restore the old configuration
+ cli
+
+; Done
+
+done: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ clc
+ adc #>BASE
+ sta ptr1+1 ; From
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; To
+
+common: ldy #EM_COPY::COUNT+1
+ lda (ptr3),y ; Get number of pages
+ beq @L2 ; Skip if no full pages
+ sta tmp1
+
+; Copy full pages allowing interrupts after each page copied
+
+ ldy #$00
+@L1: jsr transfer
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ tax
+
+ lda $01 ; Remember c64 control port
+ pha
+ and #$F8 ; Bank out ROMs, I/O
+ sei
+ sta $01
+
+; Transfer the bytes in the last page
+
+ ldy #$00
+@L3: lda (ptr1),y
+ sta (ptr2),y
+ iny
+ dex
+ bne @L3
+
+; Restore the old memory configuration, allow interrupts
+
+ pla
+ sta $01 ; Restore the old configuration
+ cli
+
+; Done
+
+@L4: rts
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO: sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr2
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ clc
+ adc #>BASE
+ sta ptr2+1 ; To
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr1
+ iny
+ lda (ptr3),y
+ sta ptr1+1 ; From
+
+ jmp common
+
+
--- /dev/null
+;
+; Extended memory driver for the RamCart 64/128KB cartridge. Driver works
+; without problems when statically linked.
+; Code is based on GEORAM code by Ullrich von Bassewitz.
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 06,22.12.2002
+;
+
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+RAMC_WINDOW = $DF00 ; Address of RamCart window
+RAMC_PAGE_LO = $DE00 ; Page register low
+RAMC_PAGE_HI = $DE01 ; Page register high (only for RC128)
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+
+pagecount: .res 2 ; Number of available pages
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx RAMC_WINDOW
+ cpx RAMC_WINDOW
+ bne @notpresent
+
+ lda #0
+ sta RAMC_PAGE_LO
+ sta RAMC_PAGE_HI
+ ldx RAMC_WINDOW
+ cpx RAMC_WINDOW
+ bne @notpresent
+ lda #2
+ sta RAMC_WINDOW
+ cmp RAMC_WINDOW
+ beq @cont
+ cpx RAMC_WINDOW
+ beq @readonly
+@cont: ldy #1
+ sty RAMC_PAGE_HI
+ sty RAMC_WINDOW
+ dey
+ sty RAMC_PAGE_HI
+ iny
+ cpy RAMC_WINDOW
+ beq @rc64
+ ; we're on rc128
+ ldx #>512
+ bne @setsize
+@rc64: ldx #>256
+@setsize:
+ lda #0
+ sta pagecount
+ stx pagecount+1
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+ rts
+@notpresent:
+@readonly:
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+; The RamCart cartridge does not copy but actually map the window, so USE is
+; identical to MAP.
+
+USE = MAP
+
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta RAMC_PAGE_LO
+ stx RAMC_PAGE_HI
+ lda #<RAMC_WINDOW
+ ldx #>RAMC_WINDOW
+
+; Use the RTS from COMMIT below to save a precious byte of storage
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - tmp2 contains the high page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1: lda RAMC_WINDOW,x
+ sta (ptr2),y
+ iny
+ bne @L2
+ inc ptr2+1
+@L2: inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4: inc tmp1
+ bne @L5
+ inc tmp2
+@L5: lda tmp1
+ sta RAMC_PAGE_LO
+ lda tmp2
+ sta RAMC_PAGE_HI
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ jsr setup
+
+; Setup is:
+;
+; - ptr1 contains the struct pointer
+; - ptr2 contains the linear memory buffer
+; - ptr3 contains -(count-1)
+; - tmp1 contains the low page register value
+; - tmp2 contains the high page register value
+; - X contains the page offset
+; - Y contains zero
+
+ jmp @L5
+
+@L1: lda (ptr2),y
+ sta RAMC_WINDOW,x
+ iny
+ bne @L2
+ inc ptr2+1
+@L2: inx
+ beq @L4
+
+; Bump count and repeat
+
+@L3: inc ptr3
+ bne @L1
+ inc ptr3+1
+ bne @L1
+ rts
+
+; Bump page register
+
+@L4: inc tmp1
+ bne @L5
+ inc tmp2
+@L5: lda tmp1
+ sta RAMC_PAGE_LO
+ lda tmp2
+ sta RAMC_PAGE_HI
+ jmp @L3
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+
+setup: sta ptr1
+ stx ptr1+1 ; Save passed pointer
+
+; Get the page number from the struct and adjust it so that it may be used
+; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
+
+ ldy #EM_COPY::PAGE+1
+ lda (ptr1),y
+ sta tmp2
+ dey
+ lda (ptr1),y
+ sta tmp1
+
+; Get the buffer pointer into ptr2
+
+ ldy #EM_COPY::BUF
+ lda (ptr1),y
+ sta ptr2
+ iny
+ lda (ptr1),y
+ sta ptr2+1
+
+; Get the count, calculate -(count-1) and store it into ptr3
+
+ ldy #EM_COPY::COUNT
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3
+ iny
+ lda (ptr1),y
+ eor #$FF
+ sta ptr3+1
+
+; Get the page offset into X and clear Y
+
+ ldy #EM_COPY::OFFS
+ lda (ptr1),y
+ tax
+ ldy #$00
+
+; Done
+
+ rts
+
--- /dev/null
+;
+; Extended memory driver for the Commodore REU. Driver works without
+; problems when statically linked.
+;
+; Ullrich von Bassewitz, 2002-11-29
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+REU_STATUS = $DF00 ; Status register
+REU_COMMAND = $DF01 ; Command register
+REU_C64ADDR = $DF02 ; C64 base address register
+REU_REUADDR = $DF04 ; REU base address register
+REU_COUNT = $DF07 ; Transfer count register
+REU_IRQMASK = $DF09 ; IRQ mask register
+REU_CONTROL = $DF0A ; Control register
+REU_TRIGGER = $FF00 ; REU command trigger
+
+OP_COPYFROM = $ED
+OP_COPYTO = $EC
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+pagecount: .res 2 ; Number of pages available
+curpage: .res 2 ; Current page number
+
+window: .res 256 ; Memory "window"
+
+reu_params: .word $0000 ; Host address, lo, hi
+ .word $0000 ; Exp address, lo, hi
+ .byte $00 ; Expansion bank no.
+ .word $0000 ; # bytes to move, lo, hi
+ .byte $00 ; Interrupt mask reg.
+ .byte $00 ; Adress control reg.
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx #$00 ; High byte of return code
+ lda #$55
+ sta REU_REUADDR
+ cmp REU_REUADDR ; Check for presence of REU
+ bne nodevice
+ asl a ; A = $AA
+ sta REU_REUADDR
+ cmp REU_REUADDR ; Check for presence of REU
+ bne nodevice
+
+ ldy #>(128*4) ; Assume 128KB
+ lda REU_STATUS
+ and #$10 ; Check size bit
+ beq @L1
+ ldy #>(256*4) ; 256KB when size bit is set
+@L1: sty pagecount+1
+
+ ldy #$FF
+ sty curpage
+ sty curpage+1 ; Invalidate the current page
+ txa ; X = A = EM_ERR_OK
+ rts
+
+; No REU found
+
+nodevice:
+ lda #EM_ERR_NO_DEVICE
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage
+ stx curpage+1 ; Remember the new page
+
+ ldy #OP_COPYFROM
+ jsr common ; Copy the window
+
+ lda #<window
+ ldx #>window ; Return the window address
+done: rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage
+ stx curpage+1 ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage
+ ldx curpage+1 ; Do we have a page mapped?
+ bmi done ; Jump if no page mapped
+
+ ldy #OP_COPYTO
+common: sty tmp1
+
+ ldy #<window
+ sty REU_C64ADDR
+ ldy #>window
+ sty REU_C64ADDR+1
+
+ ldy #0
+ sty REU_REUADDR+0
+ sta REU_REUADDR+1
+ stx REU_REUADDR+2
+
+ sty REU_COUNT+0
+ ldy #1
+ sty REU_COUNT+1 ; Move 256 bytes
+ bne transfer1 ; Transfer 256 bytes into REU
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ ldy #OP_COPYFROM
+ .byte $2C
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ ldy #OP_COPYTO
+ sty tmp1
+
+; Remember the passed pointer
+
+ sta ptr1
+ stx ptr1+1 ; Save the pointer
+
+; The structure passed to the functions has the same layout as the registers
+; of the Commodore REU, so register programming is easy.
+
+ ldy #7-1
+@L1: lda (ptr1),y
+ sta REU_C64ADDR,y
+ dey
+ bpl @L1
+
+; Invalidate the page in the memory window
+
+ sty curpage+1 ; Y = $FF
+
+; Reload the REU command and start the transfer
+
+transfer1:
+ ldy tmp1
+
+; Transfer subroutine for the REU. Expects command in Y.
+
+transfer:
+ sty REU_COMMAND ; Issue command
+
+ ldy $01 ; Save the value of the c64 control port...
+ tya ;
+ and #$F8 ; Disable ROMs and I/O.
+ sei ;
+ sta $01
+ lda REU_TRIGGER ; Don't change $FF00
+ sta REU_TRIGGER ; Start the transfer...
+
+ sty $01 ; Restore the old configuration
+ cli
+ rts
+
--- /dev/null
+;
+; Extended memory driver for the VDC RAM available on all C128 machines
+; (based on code by Ullrich von Bassewitz)
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 06,20.12.2002
+;
+; VDC test added by
+; Marco van den Heuvel, 2010-01-22
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+VDC_ADDR_REG = $D600 ; VDC address
+VDC_DATA_REG = $D601 ; VDC data
+
+VDC_DATA_HI = 18 ; used registers
+VDC_DATA_LO = 19
+VDC_CSET = 28
+VDC_DATA = 31
+
+; ------------------------------------------------------------------------
+; Data.
+
+.data
+
+pagecount: .word 64 ; $0000-$3fff as 16k default
+curpage: .word $ffff ; currently mapped-in page (invalid)
+
+.bss
+
+window: .res 256 ; memory window
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ldx #0
+ ldy #0
+ lda #VDC_CSET ; determine size of RAM...
+ sta VDC_ADDR_REG
+
+@L0: bit VDC_ADDR_REG
+ bmi @present
+ inx
+ bne @L0
+ iny
+ bne @L0
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+ rts
+
+@present:
+ ldx #VDC_CSET ; determine size of RAM...
+ jsr vdcgetreg
+ sta tmp1
+ ora #%00010000
+ jsr vdcputreg ; turn on 64k
+
+ jsr settestadr1 ; save original value of test byte
+ jsr vdcgetbyte
+ sta tmp2
+
+ lda #$55 ; write $55 here
+ ldy #ptr1
+ jsr test64k ; read it here and there
+ lda #$aa ; write $aa here
+ ldy #ptr2
+ jsr test64k ; read it here and there
+
+ jsr settestadr1
+ lda tmp2
+ jsr vdcputbyte ; restore original value of test byte
+
+ lda ptr1 ; do bytes match?
+ cmp ptr1+1
+ bne @have64k
+ lda ptr2
+ cmp ptr2+1
+ bne @have64k
+
+ ldx #VDC_CSET
+ lda tmp1
+ jsr vdcputreg ; restore 16/64k flag
+ jmp @endok ; and leave default values for 16k
+
+@have64k:
+ lda #<256
+ ldx #>256
+ sta pagecount
+ stx pagecount+1
+@endok:
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+ rts
+
+test64k:
+ sta tmp1
+ sty ptr3
+ lda #0
+ sta ptr3+1
+ jsr settestadr1
+ lda tmp1
+ jsr vdcputbyte ; write $55
+ jsr settestadr1
+ jsr vdcgetbyte ; read here
+ pha
+ jsr settestadr2
+ jsr vdcgetbyte ; and there
+ ldy #1
+ sta (ptr3),y
+ pla
+ dey
+ sta (ptr3),y
+ rts
+
+settestadr1:
+ ldy #$02 ; test page 2 (here)
+ .byte $2c
+settestadr2:
+ ldy #$42 ; or page 64+2 (there)
+ lda #0
+ jmp vdcsetsrcaddr
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ ;on C128 restore font and clear the screen?
+ rts
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage
+ stx curpage+1
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+ jsr transferin
+
+ lda #<window
+ ldx #>window
+ rts
+
+; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
+
+transferin:
+ lda ptr1
+ ldy ptr1+1
+ jsr vdcsetsrcaddr ; set source address in VDC
+ ldy #0
+ ldx #VDC_DATA
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda VDC_DATA_REG ; get 2 bytes at a time to speed-up
+ sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config)
+ iny
+ lda VDC_DATA_REG
+ sta (ptr2),y
+ iny
+ bne @L0
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage
+ stx curpage+1 ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+done: rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT:
+ lda curpage ; jump if no page mapped
+ ldx curpage+1
+ bmi done
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+; fall through to transferout
+
+; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
+
+transferout:
+ lda ptr1
+ ldy ptr1+1
+ jsr vdcsetsrcaddr ; set source address in VDC
+ ldy #0
+ ldx #VDC_DATA
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda (ptr2),y ; speedup does not work for writing
+ sta VDC_DATA_REG
+ iny
+ bne @L0
+ rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+ beq @L2 ; Skip if no full pages
+
+; Copy full pages
+
+@L1: jsr transferin
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+; Transfer the bytes in the last page
+
+ ldy #0
+@L3: jsr vdcgetbyte
+ sta (ptr2),y
+ iny
+ dec tmp1
+ lda tmp1
+ bne @L3
+@L4: rts
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ jsr setup
+ beq @L2 ; Skip if no full pages
+
+; Copy full pages
+
+@L1: jsr transferout
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+; Transfer the bytes in the last page
+
+ ldy #0
+@L3: lda (ptr2),y
+ jsr vdcputbyte
+ iny
+ dec tmp1
+ lda tmp1
+ bne @L3
+@L4: rts
+
+;-------------------------------------------------------------------------
+; Helper functions to handle VDC ram
+;
+
+vdcsetsrcaddr:
+ ldx #VDC_DATA_LO
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ sta VDC_DATA_REG
+ dex
+ tya
+ stx VDC_ADDR_REG
+ sta VDC_DATA_REG
+ rts
+
+vdcgetbyte:
+ ldx #VDC_DATA
+vdcgetreg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda VDC_DATA_REG
+ rts
+
+vdcputbyte:
+ ldx #VDC_DATA
+vdcputreg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ sta VDC_DATA_REG
+ rts
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+;
+
+setup:
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ sta ptr1+1 ; From
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; To
+
+ ldy #EM_COPY::COUNT+1
+ lda (ptr3),y ; Get number of pages
+ sta tmp1
+ rts
+
--- /dev/null
+;
+; Extended memory driver for the C64 D2TV (the second or PAL version).
+; Driver works without problems when statically linked.
+;
+; Ullrich von Bassewitz, 2005-11-27
+;
+
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+ .import _get_ostype
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+OP_COPYFROM = %00001101
+OP_COPYTO = %00001111
+
+START_BANK = 2 ; Start at $20000
+PAGES = (2048 - 128) * 4
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+window: .res 256 ; Memory "window"
+
+.data
+
+; The MAP and COMMIT entries will actually call COPYFROM/COPYTO with
+; a pointer to the following data structure:
+
+dma_params: .word window ; Host address
+ .byte 0 ; Offset in page
+curpage: .word $0000 ; Page
+ .word .sizeof (window); # bytes to move, lo, hi
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+
+; Check for a DTV
+
+ ldx #1
+ stx $d03f
+ ldx $d040
+ cpx $d000
+ bne @present
+ inc $d000
+ cpx $d040
+ beq @present
+ dec $d000
+
+; DTV not found
+
+ lda #<EM_ERR_NO_DEVICE
+ ldx #>EM_ERR_NO_DEVICE
+ rts
+
+@present:
+ ldx #$FF
+ stx curpage+1 ; Invalidate curpage
+ inx ; X = 0
+ txa ; A/X = EM_ERR_OK
+
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda #<PAGES
+ ldx #>PAGES
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage
+ stx curpage+1 ; Remember the new page
+
+ lda #<dma_params
+ ldx #>dma_params
+ jsr COPYFROM ; Copy data into the window
+
+ lda #<window
+ ldx #>window ; Return the window address
+done: rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage
+ stx curpage+1 ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage+1 ; Do we have a page mapped?
+ bmi done ; Jump if no page mapped
+
+ lda #<dma_params
+ ldx #>dma_params
+
+; Run into COPYTO
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO: sta ptr1
+ stx ptr1+1 ; Save the pointer
+
+ ldx #OP_COPYTO ; Load the command
+ bne transfer
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ sta ptr1
+ stx ptr1+1 ; Save the pointer
+
+ ldx #OP_COPYFROM
+
+; DTV DMA transfer routine. Expects the command in X.
+; NOTE: We're using knowledge about field order in the EM_COPY struct here!
+
+transfer:
+ jsr WAIT ; Wait until DMA is finished
+
+; Modulo disable
+
+ ldy #$00
+ sty $d31e
+
+; Setup the target address and the source and target steps. Y contains zero,
+; which is EM_COPY::BUF.
+
+ sty $d307 ; Source step high = 0
+ sty $d309 ; Dest step high = 0
+ lda (ptr1),y
+ sta $d303 ; Dest address low
+ iny ; Y = 1
+ sty $d306 ; Source step low = 1
+ sty $d308 ; Dest step low = 1
+ lda (ptr1),y
+ sta $d304
+ lda #$40 ; Dest is always RAM, start at $00000
+ sta $d305
+
+; Setup the source address. Incrementing Y will make it point to EM_COPY::OFFS.
+; We will allow page numbers higher than PAGES and map them to ROM. This will
+; allow reading the ROM by specifying a page starting with PAGES.
+
+ iny ; EM_COPY::OFFS
+ lda (ptr1),y
+ sta $d300
+ iny ; EM_COPY::PAGE
+ lda (ptr1),y
+ sta $d301
+ iny
+ lda (ptr1),y
+ adc #START_BANK ; Carry clear here from WAIT
+ and #$3f
+ cmp #>PAGES+START_BANK ; Valid range?
+ bcs @L1 ; Jump if no
+ ora #$40 ; Address RAM
+@L1: sta $d302
+
+; Length
+
+ iny ; EM_COPY::COUNT
+ lda (ptr1),y
+ sta $d30a
+ iny
+ lda (ptr1),y
+ sta $d30b
+
+; Start DMA
+
+ stx $d31f
+
+; Wait until DMA is done
+
+WAIT: lda $d31f
+ lsr a
+ bcs WAIT
+ rts
+
--- /dev/null
+;
+; DXS/HIT-4 Player joystick driver for the C64
+;
+; Groepaz/Hitmen, 2002-12-23
+; obviously based on Ullrichs driver :)
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "c64.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ .segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr IRQ
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 4 ; Number of joysticks we support
+
+; ------------------------------------------------------------------------
+; Data. Written in the IRQ, read by the READ routine
+
+.bss
+
+temp3: .byte 0
+temp4: .byte 0
+
+.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
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+; ------------------------------------------------------------------------
+; IRQ entry point. Is called from the C layer as a subroutine in the
+; interrupt. The routine MUST return carry set if the interrupt has been
+; 'handled' - which means that the interrupt source is gone. Otherwise it
+; MUST return carry clear.
+
+IRQ: ; cia 2 setup
+
+ ldy #$00 ; port b direction
+ sty $dd03 ; => input
+
+ sty $dd05 ; cia2 timer a highbyte
+ sty $dc05 ; cia1 timer a highbyte
+ iny
+ sty $dd04 ; cia2 timer a lowbyte
+ sty $dc04 ; cia1 timer a lowbyte
+
+ lda #%00010001
+ sta $dd0e ; control register a
+ ; timer: start
+ ; continous
+ ; forced load
+ ; serial port: input
+
+ ; cia 1 setup
+ lda #%01010001
+ sta $dc0e ; control register a
+ ; timer: start
+ ; continous
+ ; forced load
+ ; serial port: output
+
+ ; read directions 3
+ lda $dd01 ;read cia 2 port b
+ and #$0f
+ sta temp3
+
+ ; read button 3
+ lda $dd02 ;cia 2 port a
+ and #%11111011 ;data direction
+ sta $dd02 ;=> bit 2 input
+
+ lda $dd00 ;read cia 2 p.A
+ and #%00000100 ;check bit 2
+ asl a
+ asl a
+ ora temp3
+ sta temp3
+
+ ; read directions 4
+ lda $dd01 ;read cia 2 port b
+ lsr a
+ lsr a
+ lsr a
+ lsr a
+ sta temp4
+
+ ; read button 4
+ ldx #$ff ;serial data register
+ stx $dc0c ;=> writing $ff causes
+ ;cia to output some
+ ;count signals at cnt1
+
+ ldx $dd0c ;read cia 2 serial in
+ beq fire ;button press if zero
+
+ lda temp4
+ ora #%00010000
+ sta temp4
+
+fire:
+ ; Default Value: $40/64 on PAL
+ ; $42/66 on NTSC
+ lda #$41
+ sta $dc05
+ ; Default Value: $25/37 on PAL
+ ; $95/149 on NTSC
+ lda #0
+ sta $dc04
+
+ ; We do never "handle" the interrupt, we use it just as a timer.
+ clc
+ rts
+
+; ------------------------------------------------------------------------
+; COUNT: Return the total number of available joysticks in a/x.
+;
+
+COUNT: lda #<JOY_COUNT
+ ldx #>JOY_COUNT
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: tax ; Joystick number into X
+ bne joy2
+
+; Read joystick 1
+
+joy1: lda #$7F
+ sei
+ sta CIA1_PRA
+ lda CIA1_PRB
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+; Read joystick 2
+
+joy2: dex
+ bne joy3
+
+ ; ldx #0
+ lda #$E0
+ ldy #$FF
+ sei
+ sta CIA1_DDRA
+ lda CIA1_PRA
+ sty CIA1_DDRA
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+ ; Read joystick 3
+
+joy3: dex
+ bne joy4
+
+ lda temp3
+ eor #$1F
+ rts
+
+ ; Read joystick 4
+
+joy4: lda temp4
+ eor #$1F
+ ldx #0
+ rts
+
--- /dev/null
+;
+; Joystick driver using C128 number pad in 64 mode.
+; May be used multiple times when linked to the statically application.
+;
+; Stefan Haubenthal, 2004-01-26
+; Based on Ullrich von Bassewitz, 2002-12-20
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "c64.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $02 ; JOY_UP "8"
+ .byte $10 ; JOY_DOWN "2"
+ .byte $20 ; JOY_LEFT "4"
+ .byte $08 ; JOY_RIGHT "6"
+ .byte $04 ; JOY_FIRE "5" ENTER
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 1 ; Number of joysticks we support
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+
+.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 ; Assume we have a joystick
+ ldx VIC_CLK_128 ; Test for a C128
+ cpx #$FF
+ bne @C128 ; Jump if we have one
+ lda #JOY_ERR_NO_DEVICE ; No C128 -> no numpad
+@C128: ldx #0 ; Set high byte
+
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; 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 #0
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: tax ; Clear high byte
+ lda #$FD
+ ldy #$FE
+ sei
+ sta VIC_KBD_128
+ lda CIA1_PRB
+ and #%00110000
+ eor #%00110000
+ lsr
+ lsr
+ sty VIC_KBD_128
+ eor CIA1_PRB
+ iny
+ sty VIC_KBD_128 ; Reset to $FF
+ cli
+ and #%11111110
+ eor #%11111110
+ rts
+
--- /dev/null
+;
+; PTV-4 Player joystick driver for the C64
+;
+; Groepaz/Hitmen, 2002-12-23
+; obviously based on Ullrichs driver :)
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "c64.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ .segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 4 ; Number of joysticks we support
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: tax ; Joystick number into X
+ bne joy2
+
+; Read joystick 1
+
+joy1: lda #$7F
+ sei
+ sta CIA1_PRA
+ lda CIA1_PRB
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+; Read joystick 2
+
+joy2: dex
+ bne joy3
+
+ lda #$E0
+ ldy #$FF
+ sei
+ sta CIA1_DDRA
+ lda CIA1_PRA
+ sty CIA1_DDRA
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+; Read joystick 3
+
+joy3:
+ lda #%10000000 ; cia 2 port B Data-Direction
+ sta CIA2_DDRB ; bit 7: out bit 6-0: in
+
+ dex
+ bne joy4
+
+ lda #$80 ; cia 2 port B read/write
+ sta CIA2_PRB ; (output one at PB7)
+
+ lda CIA2_PRB ; cia 2 port B read/write
+ and #$1f ; get bit 4-0 (PB4-PB0)
+ eor #$1f
+ rts
+
+; Read joystick 4
+
+joy4: lda #$00 ; cia 2 port B read/write
+ sta CIA2_PRB ; (output zero at PB7)
+
+ lda CIA2_PRB ; cia 2 port B read/write
+ and #$0f ; get bit 3-0 (PB3-PB0)
+ sta tmp1 ; joy 4 directions
+
+ lda CIA2_PRB ; cia 2 port B read/write
+ and #%00100000 ; get bit 5 (PB5)
+ lsr
+ ora tmp1
+ eor #$1f
+
+ ldx #0
+ rts
+
--- /dev/null
+;
+; Standard joystick driver for the C64. May be used multiple times when linked
+; to the statically application.
+;
+; Ullrich von Bassewitz, 2002-12-20
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "c64.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: tax ; Joystick number into X
+ bne joy2
+
+; Read joystick 1
+
+joy1: lda #$7F
+ sei
+ sta CIA1_PRA
+ lda CIA1_PRB
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+; Read joystick 2
+
+joy2: ldx #0
+ lda #$E0
+ ldy #$FF
+ sei
+ sta CIA1_DDRA
+ lda CIA1_PRA
+ sty CIA1_DDRA
+ cli
+ and #$1F
+ eor #$1F
+ rts
+
+
--- /dev/null
+;
+; Driver for the 1351 proportional mouse. Parts of the code are from
+; the Commodore 1351 mouse users guide.
+;
+; 2009-09-26, Ullrich von Bassewitz
+; 2010-02-06, Greg King
+;
+; The driver prevents the keyboard from interfering by changing the
+; keyboard's output port into an input port while the driver reads its
+; controller device. That disables a wire that is left active by the
+; Kernal. That wire is used by the STOP-key to break out of BASIC
+; programs -- CC65 programs don't use that feature. The wire is shared
+; by these keys: STOP, "Q", Commodore, Space, "2", CTRL, Left-Arrow, and
+; "1". I listed them, in order, from bit 7 over to bit 0. The
+; rightmost five keys can look like joystick switches.
+;
+; The driver prevents the mouse/joystick from interfering by "blinding"
+; the keyboard scanner while any button/switch is active. It changes
+; the input port into an output port, then stores all zero-bits in that
+; port's latch. Reading from an output port sees the bitwise-AND of the
+; latch and the input signals. Therefore, the scanner thinks that eight
+; keys are being pushed at the same time. It doesn't know what to do
+; about that condition; so, it does nothing. The driver lets the
+; scanner see normally, again, when no buttons/switches are active.
+;
+
+ .include "zeropage.inc"
+ .include "mouse-kernel.inc"
+ .include "c64.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+HEADER:
+
+; Driver signature
+
+ .byte $6d, $6f, $75 ; "mou"
+ .byte MOUSE_API_VERSION ; Mouse driver API version number
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr HIDE
+ .addr SHOW
+ .addr SETBOX
+ .addr GETBOX
+ .addr MOVE
+ .addr BUTTONS
+ .addr POS
+ .addr INFO
+ .addr IOCTL
+ .addr IRQ
+
+; Mouse driver flags
+
+ .byte MOUSE_FLAG_LATE_IRQ
+
+; Callback table, set by the kernel before INSTALL is called
+
+CHIDE: jmp $0000 ; Hide the cursor
+CSHOW: jmp $0000 ; Show the cursor
+CMOVEX: jmp $0000 ; Move the cursor to X coord
+CMOVEY: jmp $0000 ; Move the cursor to Y coord
+
+
+;----------------------------------------------------------------------------
+; Constants
+
+SCREEN_HEIGHT = YSIZE * 8 - 1 ; (origin is zero)
+SCREEN_WIDTH = XSIZE * 8 - 1
+
+;----------------------------------------------------------------------------
+; Global variables. The bounding box values are sorted so that they can be
+; written with the least effort in the SETBOX and GETBOX routines, so don't
+; reorder them.
+
+.bss
+
+Vars:
+OldPotX: .res 1 ; Old hw counter values
+OldPotY: .res 1
+
+XPos: .res 2 ; Current mouse position, X
+YPos: .res 2 ; Current mouse position, Y
+XMin: .res 2 ; X1 value of bounding box
+YMin: .res 2 ; Y1 value of bounding box
+XMax: .res 2 ; X2 value of bounding box
+YMax: .res 2 ; Y2 value of bounding box
+Buttons: .res 1 ; button status bits
+
+OldValue: .res 1 ; Temp for MoveCheck routine
+NewValue: .res 1 ; Temp for MoveCheck routine
+
+; Default values for above variables
+
+.rodata
+
+; (We use ".proc" because we want to define both a label and a scope.)
+
+.proc DefVars
+ .byte 0, 0 ; OldPotX/OldPotY
+ .word SCREEN_WIDTH/2 ; XPos
+ .word SCREEN_HEIGHT/2 ; YPos
+ .word 0 ; XMin
+ .word 0 ; YMin
+ .word SCREEN_WIDTH ; XMax
+ .word SCREEN_HEIGHT ; YMax
+ .byte %00000000 ; Buttons
+.endproc
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an MOUSE_ERR_xx code in a/x.
+
+INSTALL:
+
+; Initialize variables. Just copy the default stuff over
+
+ ldx #.sizeof(DefVars)-1
+@L1: lda DefVars,x
+ sta Vars,x
+ dex
+ bpl @L1
+
+; Be sure the mouse cursor is invisible and at the default location. We
+; need to do that here, because our mouse interrupt handler doesn't set the
+; mouse position if it hasn't changed.
+
+ sei
+ jsr CHIDE
+ lda XPos
+ ldx XPos+1
+ jsr CMOVEX
+ lda YPos
+ ldx YPos+1
+ jsr CMOVEY
+ cli
+
+; Done, return zero (= MOUSE_ERR_OK)
+
+ ldx #$00
+ txa
+ rts
+
+;----------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+
+UNINSTALL = HIDE ; Hide cursor on exit
+
+;----------------------------------------------------------------------------
+; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently visible and should get hidden. For most drivers,
+; no special action is required besides hiding the mouse cursor.
+; No return code required.
+
+HIDE: sei
+ jsr CHIDE
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently hidden and should become visible. For most drivers,
+; no special action is required besides enabling the mouse cursor.
+; No return code required.
+
+SHOW: sei
+ jsr CSHOW
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SETBOX: Set the mouse bounding box. The parameters are passed as they come
+; from the C program, that is, a pointer to a mouse_box struct in a/x.
+; No checks are done if the mouse is currently inside the box, this is the job
+; of the caller. It is not necessary to validate the parameters, trust the
+; caller and save some code here. No return code required.
+
+SETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda (ptr1),y
+ sta XMin,y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; GETBOX: Return the mouse bounding box. The parameters are passed as they
+; come from the C program, that is, a pointer to a mouse_box struct in a/x.
+
+GETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+@L1: lda XMin,y
+ sta (ptr1),y
+ dey
+ bpl @L1
+ rts
+
+;----------------------------------------------------------------------------
+; MOVE: Move the mouse to a new position. The position is passed as it comes
+; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
+; remove the parameter from the stack on return.
+; No checks are done if the new position is valid (within the bounding box or
+; the screen). No return code required.
+;
+
+MOVE: sei ; No interrupts
+
+ sta YPos
+ stx YPos+1 ; New Y position
+ jsr CMOVEY ; Set it
+
+ ldy #$01
+ lda (sp),y
+ sta XPos+1
+ tax
+ dey
+ lda (sp),y
+ sta XPos ; New X position
+
+ jsr CMOVEX ; Move the cursor
+
+ cli ; Allow interrupts
+ rts
+
+;----------------------------------------------------------------------------
+; BUTTONS: Return the button mask in a/x.
+
+BUTTONS:
+ lda Buttons
+ ldx #0
+ and #$1F
+ rts
+
+;----------------------------------------------------------------------------
+; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
+; No return code required.
+
+POS: ldy #MOUSE_POS::XCOORD ; Structure offset
+
+ sei ; Disable interrupts
+ lda XPos ; Transfer the position
+ sta (ptr1),y
+ lda XPos+1
+ iny
+ sta (ptr1),y
+ lda YPos
+ iny
+ sta (ptr1),y
+ lda YPos+1
+ cli ; Enable interrupts
+
+ iny
+ sta (ptr1),y ; Store last byte
+
+ rts ; Done
+
+;----------------------------------------------------------------------------
+; INFO: Returns mouse position and current button mask in the MOUSE_INFO
+; struct pointed to by ptr1. No return code required.
+;
+; We're cheating here to keep the code smaller: The first fields of the
+; mouse_info struct are identical to the mouse_pos struct, so we will just
+; call _mouse_pos to initialize the struct pointer and fill the position
+; fields.
+
+INFO: jsr POS
+
+; Fill in the button state
+
+ jsr BUTTONS ; Will not touch ptr1
+ ldy #MOUSE_INFO::BUTTONS
+ sta (ptr1),y
+
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>MOUSE_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
+; (so be careful). The routine MUST return carry set if the interrupt has been
+; 'handled' - which means that the interrupt source is gone. Otherwise it
+; MUST return carry clear.
+;
+
+IRQ:
+
+; Record the state of the buttons.
+; Avoid crosstalk between the keyboard and the mouse.
+
+ ldy #%00000000 ; Set ports A and B to input
+ sty CIA1_DDRB
+ sty CIA1_DDRA ; Keyboard won't look like mouse
+ lda CIA1_PRB ; Read Control-Port 1
+ dec CIA1_DDRA ; Set port A back to output
+ eor #%11111111 ; Bit goes up when button goes down
+ sta Buttons
+ beq @L0 ;(bze)
+ dec CIA1_DDRB ; Mouse won't look like keyboard
+ sty CIA1_PRB ; Set "all keys pushed"
+
+@L0: lda SID_ADConv1 ; Get mouse X movement
+ ldy OldPotX
+ jsr MoveCheck ; Calculate movement vector
+
+; Skip processing if nothing has changed
+
+ bcc @SkipX
+ sty OldPotX
+
+; Calculate the new X coordinate (--> a/y)
+
+ add XPos
+ tay ; Remember low byte
+ txa
+ adc XPos+1
+ tax
+
+; Limit the X coordinate to the bounding box
+
+ cpy XMin
+ sbc XMin+1
+ bpl @L1
+ ldy XMin
+ ldx XMin+1
+ jmp @L2
+@L1: txa
+
+ cpy XMax
+ sbc XMax+1
+ bmi @L2
+ ldy XMax
+ ldx XMax+1
+@L2: sty XPos
+ stx XPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jsr CMOVEX
+
+; Calculate the Y movement vector
+
+@SkipX: lda SID_ADConv2 ; Get mouse Y movement
+ ldy OldPotY
+ jsr MoveCheck ; Calculate movement
+
+; Skip processing if nothing has changed
+
+ bcc @SkipY
+ sty OldPotY
+
+; Calculate the new Y coordinate (--> a/y)
+
+ sta OldValue
+ lda YPos
+ sub OldValue
+ tay
+ stx OldValue
+ lda YPos+1
+ sbc OldValue
+ tax
+
+; Limit the Y coordinate to the bounding box
+
+ cpy YMin
+ sbc YMin+1
+ bpl @L3
+ ldy YMin
+ ldx YMin+1
+ jmp @L4
+@L3: txa
+
+ cpy YMax
+ sbc YMax+1
+ bmi @L4
+ ldy YMax
+ ldx YMax+1
+@L4: sty YPos
+ stx YPos+1
+
+; Move the mouse pointer to the new Y pos
+
+ tya
+ jsr CMOVEY
+
+; Done
+
+ clc ; Interrupt not "handled"
+@SkipY: rts
+
+; --------------------------------------------------------------------------
+;
+; Move check routine, called for both coordinates.
+;
+; Entry: y = old value of pot register
+; a = current value of pot register
+; Exit: y = value to use for old value
+; x/a = delta value for position
+;
+
+MoveCheck:
+ sty OldValue
+ sta NewValue
+ ldx #$00
+
+ sub OldValue ; a = mod64 (new - old)
+ and #%01111111
+ cmp #%01000000 ; if (a > 0)
+ bcs @L1 ;
+ lsr a ; a /= 2;
+ beq @L2 ; if (a != 0)
+ ldy NewValue ; y = NewValue
+ sec
+ rts ; return
+
+@L1: ora #%11000000 ; else, "or" in high-order bits
+ cmp #$FF ; if (a != -1)
+ beq @L2
+ sec
+ ror a ; a /= 2
+ dex ; high byte = -1 (X = $FF)
+ ldy NewValue
+ sec
+ rts
+
+@L2: txa ; A = $00
+ clc
+ rts
+
--- /dev/null
+;
+; Driver for a "joystick mouse".
+;
+; Ullrich von Bassewitz, 2004-03-29, 2009-09-26
+; 2010-02-08, Greg King
+;
+; The driver prevents the keyboard from interfering by changing the
+; keyboard's output port into an input port while the driver reads its
+; controller device. That disables a wire that is left active by the
+; Kernal. That wire is used by the STOP-key to break out of BASIC
+; programs -- CC65 programs don't use that feature. The wire is shared
+; by these keys: STOP, "Q", Commodore, Space, "2", CTRL, Left-Arrow, and
+; "1". I listed them, in order, from bit 7 over to bit 0. The
+; rightmost five keys can look like joystick switches.
+;
+; The driver prevents the mouse/joystick from interfering by "blinding"
+; the keyboard scanner while any button/switch is active. It changes
+; the input port into an output port, then stores all zero-bits in that
+; port's latch. Reading from an output port sees the bitwise-AND of the
+; latch and the input signals. Therefore, the scanner thinks that eight
+; keys are being pushed at the same time. It doesn't know what to do
+; about that condition; so, it does nothing. The driver lets the
+; scanner see normally, again, when no buttons/switches are active.
+;
+
+ .include "zeropage.inc"
+ .include "mouse-kernel.inc"
+ .include "c64.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+HEADER:
+
+; Driver signature
+
+ .byte $6d, $6f, $75 ; "mou"
+ .byte MOUSE_API_VERSION ; Mouse driver API version number
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr HIDE
+ .addr SHOW
+ .addr SETBOX
+ .addr GETBOX
+ .addr MOVE
+ .addr BUTTONS
+ .addr POS
+ .addr INFO
+ .addr IOCTL
+ .addr IRQ
+
+; Mouse driver flags
+
+ .byte MOUSE_FLAG_LATE_IRQ
+
+; Callback table, set by the kernel before INSTALL is called
+
+CHIDE: jmp $0000 ; Hide the cursor
+CSHOW: jmp $0000 ; Show the cursor
+CMOVEX: jmp $0000 ; Move the cursor to X coord
+CMOVEY: jmp $0000 ; Move the cursor to Y coord
+
+
+;----------------------------------------------------------------------------
+; Constants
+
+SCREEN_HEIGHT = 200
+SCREEN_WIDTH = 320
+
+.enum JOY
+ UP = $01
+ DOWN = $02
+ LEFT = $04
+ RIGHT = $08
+ FIRE = $10
+.endenum
+
+;----------------------------------------------------------------------------
+; Global variables. The bounding box values are sorted so that they can be
+; written with the least effort in the SETBOX and GETBOX routines, so don't
+; reorder them.
+
+.bss
+
+Vars:
+YPos: .res 2 ; Current mouse position, Y
+XPos: .res 2 ; Current mouse position, X
+XMin: .res 2 ; X1 value of bounding box
+YMin: .res 2 ; Y1 value of bounding box
+XMax: .res 2 ; X2 value of bounding box
+YMax: .res 2 ; Y2 value of bounding box
+Buttons: .res 1 ; Button mask
+
+; Temporary value used in the int handler
+
+Temp: .res 1
+
+; Default values for above variables
+
+.rodata
+
+.proc DefVars
+ .word SCREEN_HEIGHT/2 ; YPos
+ .word SCREEN_WIDTH/2 ; XPos
+ .word 0 ; XMin
+ .word 0 ; YMin
+ .word SCREEN_WIDTH ; XMax
+ .word SCREEN_HEIGHT ; YMax
+ .byte 0 ; Buttons
+.endproc
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an MOUSE_ERR_xx code in a/x.
+
+INSTALL:
+
+; Initialize variables. Just copy the default stuff over
+
+ ldx #.sizeof(DefVars)-1
+@L1: lda DefVars,x
+ sta Vars,x
+ dex
+ bpl @L1
+
+; Be sure the mouse cursor is invisible and at the default location. We
+; need to do that here, because our mouse interrupt handler doesn't set the
+; mouse position if it hasn't changed.
+
+ sei
+ jsr CHIDE
+ lda XPos
+ ldx XPos+1
+ jsr CMOVEX
+ lda YPos
+ ldx YPos+1
+ jsr CMOVEY
+ cli
+
+; Done, return zero (= MOUSE_ERR_OK)
+
+ ldx #$00
+ txa
+ rts
+
+;----------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+
+UNINSTALL = HIDE ; Hide cursor on exit
+
+;----------------------------------------------------------------------------
+; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently visible and should get hidden. For most drivers,
+; no special action is required besides hiding the mouse cursor.
+; No return code required.
+
+HIDE: sei
+ jsr CHIDE
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently hidden and should become visible. For most drivers,
+; no special action is required besides enabling the mouse cursor.
+; No return code required.
+
+SHOW: sei
+ jsr CSHOW
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SETBOX: Set the mouse bounding box. The parameters are passed as they come
+; from the C program, that is, a pointer to a mouse_box struct in a/x.
+; No checks are done if the mouse is currently inside the box, this is the job
+; of the caller. It is not necessary to validate the parameters, trust the
+; caller and save some code here. No return code required.
+
+SETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda (ptr1),y
+ sta XMin,y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; GETBOX: Return the mouse bounding box. The parameters are passed as they
+; come from the C program, that is, a pointer to a mouse_box struct in a/x.
+
+GETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+
+@L1: lda XMin,y
+ sta (ptr1),y
+ dey
+ bpl @L1
+
+ rts
+
+;----------------------------------------------------------------------------
+; MOVE: Move the mouse to a new position. The position is passed as it comes
+; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
+; remove the parameter from the stack on return.
+; No checks are done if the new position is valid (within the bounding box or
+; the screen). No return code required.
+;
+
+MOVE: sei ; No interrupts
+
+ sta YPos
+ stx YPos+1 ; New Y position
+ jsr CMOVEY ; Set it
+
+ ldy #$01
+ lda (sp),y
+ sta XPos+1
+ tax
+ dey
+ lda (sp),y
+ sta XPos ; New X position
+
+ jsr CMOVEX ; Move the cursor
+
+ cli ; Allow interrupts
+ rts
+
+;----------------------------------------------------------------------------
+; BUTTONS: Return the button mask in a/x.
+
+BUTTONS:
+ lda Buttons
+ ldx #$00
+ rts
+
+;----------------------------------------------------------------------------
+; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
+; No return code required.
+
+POS: ldy #MOUSE_POS::XCOORD ; Structure offset
+
+ sei ; Disable interrupts
+ lda XPos ; Transfer the position
+ sta (ptr1),y
+ lda XPos+1
+ iny
+ sta (ptr1),y
+ lda YPos
+ iny
+ sta (ptr1),y
+ lda YPos+1
+ cli ; Enable interrupts
+
+ iny
+ sta (ptr1),y ; Store last byte
+
+ rts ; Done
+
+;----------------------------------------------------------------------------
+; INFO: Returns mouse position and current button mask in the MOUSE_INFO
+; struct pointed to by ptr1. No return code required.
+;
+; We're cheating here to keep the code smaller: The first fields of the
+; mouse_info struct are identical to the mouse_pos struct, so we will just
+; call _mouse_pos to initialize the struct pointer and fill the position
+; fields.
+
+INFO: jsr POS
+
+; Fill in the button state
+
+ lda Buttons
+ ldy #MOUSE_INFO::BUTTONS
+ sta (ptr1),y
+
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>MOUSE_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
+; (so be careful). The routine MUST return carry set if the interrupt has been
+; 'handled' - which means that the interrupt source is gone. Otherwise it
+; MUST return carry clear.
+;
+
+; Avoid crosstalk between the keyboard and a joystick.
+
+IRQ: ldy #%00000000 ; Set ports A and B to input
+ sty CIA1_DDRB
+ sty CIA1_DDRA ; Keyboard won't look like joystick
+ lda CIA1_PRB ; Read Control-Port 1
+ dec CIA1_DDRA ; Set port A back to output
+ eor #%11111111 ; Bit goes up when switch goes down
+ beq @Save ;(bze)
+ dec CIA1_DDRB ; Joystick won't look like keyboard
+ sty CIA1_PRB ; Set "all keys pushed"
+@Save: sta Temp
+
+; Check for a pressed button and place the result into Buttons
+
+ ldx #$00 ; Assume no button pressed
+ and #JOY::FIRE ; Check fire button
+ beq @L0 ; Jump if not pressed
+ ldx #MOUSE_BTN_LEFT ; Left (only) button is pressed
+@L0: stx Buttons
+
+; Check left/right
+
+ lda Temp ; Read joystick #0
+ and #(JOY::LEFT | JOY::RIGHT)
+ beq @SkipX ;
+
+; We will cheat here and rely on the fact that either the left, OR the right
+; bit can be active
+
+ and #JOY::RIGHT ; Check RIGHT bit
+ bne @Right
+ lda #$FF
+ tax
+ bne @AddX ; Branch always
+@Right: lda #$01
+ ldx #$00
+
+; Calculate the new X coordinate (--> a/y)
+
+@AddX: add XPos
+ tay ; Remember low byte
+ txa
+ adc XPos+1
+ tax
+
+; Limit the X coordinate to the bounding box
+
+ cpy XMin
+ sbc XMin+1
+ bpl @L1
+ ldy XMin
+ ldx XMin+1
+ jmp @L2
+@L1: txa
+
+ cpy XMax
+ sbc XMax+1
+ bmi @L2
+ ldy XMax
+ ldx XMax+1
+@L2: sty XPos
+ stx XPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jsr CMOVEX
+
+; Calculate the Y movement vector
+
+@SkipX: lda Temp ; Read joystick #0
+ and #(JOY::UP | JOY::DOWN) ; Check up/down
+ beq @SkipY ;
+
+; We will cheat here and rely on the fact that either the up, OR the down
+; bit can be active
+
+ lsr a ; Check UP bit
+ bcc @Down
+ lda #$FF
+ tax
+ bne @AddY
+@Down: lda #$01
+ ldx #$00
+
+; Calculate the new Y coordinate (--> a/y)
+
+@AddY: add YPos
+ tay ; Remember low byte
+ txa
+ adc YPos+1
+ tax
+
+; Limit the Y coordinate to the bounding box
+
+ cpy YMin
+ sbc YMin+1
+ bpl @L3
+ ldy YMin
+ ldx YMin+1
+ jmp @L4
+@L3: txa
+
+ cpy YMax
+ sbc YMax+1
+ bmi @L4
+ ldy YMax
+ ldx YMax+1
+@L4: sty YPos
+ stx YPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jsr CMOVEY
+
+; Done
+
+@SkipY: clc ; Interrupt not handled
+ rts
+
--- /dev/null
+;
+; Driver for a potentiometer "mouse" e.g. Koala Pad
+;
+; Ullrich von Bassewitz, 2004-03-29, 2009-09-26
+; Stefan Haubenthal, 2006-08-20
+;
+
+ .include "zeropage.inc"
+ .include "mouse-kernel.inc"
+ .include "c64.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+HEADER:
+
+; Driver signature
+
+ .byte $6d, $6f, $75 ; "mou"
+ .byte MOUSE_API_VERSION ; Mouse driver API version number
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr HIDE
+ .addr SHOW
+ .addr SETBOX
+ .addr GETBOX
+ .addr MOVE
+ .addr BUTTONS
+ .addr POS
+ .addr INFO
+ .addr IOCTL
+ .addr IRQ
+
+; Callback table, set by the kernel before INSTALL is called
+
+CHIDE: jmp $0000 ; Hide the cursor
+CSHOW: jmp $0000 ; Show the cursor
+CMOVEX: jmp $0000 ; Move the cursor to X coord
+CMOVEY: jmp $0000 ; Move the cursor to Y coord
+
+
+;----------------------------------------------------------------------------
+; Constants
+
+SCREEN_HEIGHT = 200
+SCREEN_WIDTH = 320
+
+.enum JOY
+ UP = $01
+ DOWN = $02
+ LEFT = $04
+ RIGHT = $08
+ FIRE = $10
+.endenum
+
+;----------------------------------------------------------------------------
+; Global variables. The bounding box values are sorted so that they can be
+; written with the least effort in the SETBOX and GETBOX routines, so don't
+; reorder them.
+
+.bss
+
+Vars:
+YPos: .res 2 ; Current mouse position, Y
+XPos: .res 2 ; Current mouse position, X
+XMin: .res 2 ; X1 value of bounding box
+YMin: .res 2 ; Y1 value of bounding box
+XMax: .res 2 ; X2 value of bounding box
+YMax: .res 2 ; Y2 value of bounding box
+Buttons: .res 1 ; Button mask
+
+; Temporary value used in the int handler
+
+Temp: .res 1
+
+; Default values for above variables
+
+.rodata
+
+.proc DefVars
+ .word SCREEN_HEIGHT/2 ; YPos
+ .word SCREEN_WIDTH/2 ; XPos
+ .word 0 ; XMin
+ .word 0 ; YMin
+ .word SCREEN_WIDTH ; XMax
+ .word SCREEN_HEIGHT ; YMax
+ .byte 0 ; Buttons
+.endproc
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an MOUSE_ERR_xx code in a/x.
+
+INSTALL:
+
+; Initialize variables. Just copy the default stuff over
+
+ ldx #.sizeof(DefVars)-1
+@L1: lda DefVars,x
+ sta Vars,x
+ dex
+ bpl @L1
+
+; Be sure the mouse cursor is invisible and at the default location. We
+; need to do that here, because our mouse interrupt handler doesn't set the
+; mouse position if it hasn't changed.
+
+ sei
+ jsr CHIDE
+ lda XPos
+ ldx XPos+1
+ jsr CMOVEX
+ lda YPos
+ ldx YPos+1
+ jsr CMOVEY
+ cli
+
+; Done, return zero (= MOUSE_ERR_OK)
+
+ ldx #$00
+ txa
+ rts
+
+;----------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+
+UNINSTALL = HIDE ; Hide cursor on exit
+
+;----------------------------------------------------------------------------
+; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently visible and should get hidden. For most drivers,
+; no special action is required besides hiding the mouse cursor.
+; No return code required.
+
+HIDE: sei
+ jsr CHIDE
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
+; a counter for calls to show/hide, and the driver entry point is only called
+; if the mouse is currently hidden and should become visible. For most drivers,
+; no special action is required besides enabling the mouse cursor.
+; No return code required.
+
+SHOW: sei
+ jsr CSHOW
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; SETBOX: Set the mouse bounding box. The parameters are passed as they come
+; from the C program, that is, a pointer to a mouse_box struct in a/x.
+; No checks are done if the mouse is currently inside the box, this is the job
+; of the caller. It is not necessary to validate the parameters, trust the
+; caller and save some code here. No return code required.
+
+SETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda (ptr1),y
+ sta XMin,y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; GETBOX: Return the mouse bounding box. The parameters are passed as they
+; come from the C program, that is, a pointer to a mouse_box struct in a/x.
+
+GETBOX: sta ptr1
+ stx ptr1+1 ; Save data pointer
+
+ ldy #.sizeof (MOUSE_BOX)-1
+ sei
+
+@L1: lda XMin,y
+ sta (ptr1),y
+ dey
+ bpl @L1
+
+ cli
+ rts
+
+;----------------------------------------------------------------------------
+; MOVE: Move the mouse to a new position. The position is passed as it comes
+; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
+; remove the parameter from the stack on return.
+; No checks are done if the new position is valid (within the bounding box or
+; the screen). No return code required.
+;
+
+MOVE: sei ; No interrupts
+
+ sta YPos
+ stx YPos+1 ; New Y position
+ jsr CMOVEY ; Set it
+
+ ldy #$01
+ lda (sp),y
+ sta XPos+1
+ tax
+ dey
+ lda (sp),y
+ sta XPos ; New X position
+
+ jsr CMOVEX ; Move the cursor
+
+ cli ; Allow interrupts
+ rts
+
+;----------------------------------------------------------------------------
+; BUTTONS: Return the button mask in a/x.
+
+BUTTONS:
+ lda Buttons
+ ldx #$00
+ rts
+
+;----------------------------------------------------------------------------
+; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
+; No return code required.
+
+POS: ldy #MOUSE_POS::XCOORD ; Structure offset
+
+ sei ; Disable interrupts
+ lda XPos ; Transfer the position
+ sta (ptr1),y
+ lda XPos+1
+ iny
+ sta (ptr1),y
+ lda YPos
+ iny
+ sta (ptr1),y
+ lda YPos+1
+ cli ; Enable interrupts
+
+ iny
+ sta (ptr1),y ; Store last byte
+
+ rts ; Done
+
+;----------------------------------------------------------------------------
+; INFO: Returns mouse position and current button mask in the MOUSE_INFO
+; struct pointed to by ptr1. No return code required.
+;
+; We're cheating here to keep the code smaller: The first fields of the
+; mouse_info struct are identical to the mouse_pos struct, so we will just
+; call _mouse_pos to initialize the struct pointer and fill the position
+; fields.
+
+INFO: jsr POS
+
+; Fill in the button state
+
+ lda Buttons
+ ldy #MOUSE_INFO::BUTTONS
+ sta (ptr1),y
+
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>MOUSE_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
+; (so be careful).
+;
+
+IRQ: lda #$7F
+ sta CIA1_PRA
+ lda CIA1_PRB ; Read port #1
+ and #%00001100
+ eor #%00001100 ; Make all bits active high
+ asl
+ sta Buttons
+ lsr
+ lsr
+ lsr
+ and #%00000001
+ ora Buttons
+ sta Buttons
+ ldx #%01000000
+ stx CIA1_PRA
+ ldy #0
+: dey
+ bne :-
+ ldx SID_ADConv1
+ stx XPos
+ ldx SID_ADConv2
+ stx YPos
+
+ lda #$FF
+ tax
+ bne @AddX ; Branch always
+ lda #$01
+ ldx #$00
+
+; Calculate the new X coordinate (--> a/y)
+
+@AddX: add XPos
+ tay ; Remember low byte
+ txa
+ adc XPos+1
+ tax
+
+; Limit the X coordinate to the bounding box
+
+ cpy XMin
+ sbc XMin+1
+ bpl @L1
+ ldy XMin
+ ldx XMin+1
+ jmp @L2
+@L1: txa
+
+ cpy XMax
+ sbc XMax+1
+ bmi @L2
+ ldy XMax
+ ldx XMax+1
+@L2: sty XPos
+ stx XPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jsr CMOVEX
+
+ lda #$FF
+ tax
+ bne @AddY
+@Down: lda #$01
+ ldx #$00
+
+; Calculate the new Y coordinate (--> a/y)
+
+@AddY: add YPos
+ tay ; Remember low byte
+ txa
+ adc YPos+1
+ tax
+
+; Limit the Y coordinate to the bounding box
+
+ cpy YMin
+ sbc YMin+1
+ bpl @L3
+ ldy YMin
+ ldx YMin+1
+ jmp @L4
+@L3: txa
+
+ cpy YMax
+ sbc YMax+1
+ bmi @L4
+ ldy YMax
+ ldx YMax+1
+@L4: sty YPos
+ stx YPos+1
+
+; Move the mouse pointer to the new X pos
+
+ tya
+ jmp CMOVEY
--- /dev/null
+;
+; Serial driver for the C64 using a Swiftlink or Turbo-232 cartridge.
+;
+; Ullrich von Bassewitz, 2003-04-18
+;
+; The driver is based on the cc65 rs232 module, which in turn is based on
+; Craig Bruce device driver for the Switftlink/Turbo-232.
+;
+; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
+;
+; This software is Public Domain. It is in Buddy assembler format.
+;
+; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
+; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
+; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
+; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
+;
+; The code assumes that the kernal + I/O are in context. On the C128, call
+; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
+; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
+; interrupt handling assumes that the 65816 is in 6502-emulation mode.
+;
+
+ .include "zeropage.inc"
+ .include "ser-kernel.inc"
+ .include "ser-error.inc"
+ .include "c64.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $73, $65, $72 ; "ser"
+ .byte SER_API_VERSION ; Serial API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word OPEN
+ .word CLOSE
+ .word GET
+ .word PUT
+ .word STATUS
+ .word IOCTL
+ .word IRQ
+
+;----------------------------------------------------------------------------
+; I/O definitions
+
+ACIA = $DE00
+ACIA_DATA = ACIA+0 ; Data register
+ACIA_STATUS = ACIA+1 ; Status register
+ACIA_CMD = ACIA+2 ; Command register
+ACIA_CTRL = ACIA+3 ; Control register
+
+;----------------------------------------------------------------------------
+;
+; Global variables
+;
+
+; We reuse the RS232 zero page variables for the driver, since the ROM
+; routines cannot be used together with this driver.
+RecvHead = $B5 ; Head of receive buffer
+RecvTail = $BD ; Tail of receive buffer
+RecvFreeCnt = $F7 ; Number of bytes in receive buffer
+SendHead = $F8 ; Head of send buffer
+SendTail = $F9 ; Tail of send buffer
+SendFreeCnt = $FA ; Number of bytes free in send buffer
+
+.bss
+Stopped: .res 1 ; Flow-stopped flag
+RtsOff: .res 1 ;
+
+; Send and receive buffers: 256 bytes each
+RecvBuf: .res 256
+SendBuf: .res 256
+
+.data
+NmiContinue: .byte $4c ; JMP instruction for NMI save -- continue
+NmiSave: .res 2 ; normal NMI handler
+
+.rodata
+
+; Tables used to translate RS232 params into register values
+
+BaudTable: ; bit7 = 1 means setting is invalid
+ .byte $FF ; SER_BAUD_45_5
+ .byte $FF ; SER_BAUD_50
+ .byte $FF ; SER_BAUD_75
+ .byte $FF ; SER_BAUD_110
+ .byte $FF ; SER_BAUD_134_5
+ .byte $02 ; SER_BAUD_150
+ .byte $05 ; SER_BAUD_300
+ .byte $06 ; SER_BAUD_600
+ .byte $07 ; SER_BAUD_1200
+ .byte $FF ; SER_BAUD_1800
+ .byte $08 ; SER_BAUD_2400
+ .byte $09 ; SER_BAUD_3600
+ .byte $0A ; SER_BAUD_4800
+ .byte $0B ; SER_BAUD_7200
+ .byte $0C ; SER_BAUD_9600
+ .byte $0E ; SER_BAUD_19200
+ .byte $0F ; SER_BAUD_38400
+ .byte $FF ; SER_BAUD_57600
+ .byte $FF ; SER_BAUD_115200
+ .byte $FF ; SER_BAUD_230400
+
+BitTable:
+ .byte $60 ; SER_BITS_5
+ .byte $40 ; SER_BITS_6
+ .byte $20 ; SER_BITS_7
+ .byte $00 ; SER_BITS_8
+
+StopTable:
+ .byte $00 ; SER_STOP_1
+ .byte $80 ; SER_STOP_2
+
+ParityTable:
+ .byte $00 ; SER_PAR_NONE
+ .byte $20 ; SER_PAR_ODD
+ .byte $60 ; SER_PAR_EVEN
+ .byte $A0 ; SER_PAR_MARK
+ .byte $E0 ; SER_PAR_SPACE
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an SER_ERR_xx code in a/x.
+
+INSTALL:
+
+; Deactivate DTR and disable 6551 interrupts
+
+ lda #%00001010
+ sta ACIA_CMD
+
+; Set up the nmi vector
+
+ lda NMIVec
+ ldy NMIVec+1
+ sta NmiSave+0
+ sty NmiSave+1
+ lda #<NmiHandler
+ ldy #>NmiHandler
+SetNMI: sta NMIVec
+ sty NMIVec+1
+
+; Done, return an error code
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+;----------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Must return an SER_ERR_xx code in a/x.
+
+UNINSTALL:
+
+; Stop interrupts, drop DTR
+
+ lda #%00001010
+ sta ACIA_CMD
+
+; Restore NMI vector and return OK
+
+ lda NmiSave+0
+ ldy NmiSave+1
+ jmp SetNMI
+
+;----------------------------------------------------------------------------
+; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+OPEN:
+
+; Check if the handshake setting is valid
+
+ ldy #SER_PARAMS::HANDSHAKE ; Handshake
+ lda (ptr1),y
+ cmp #SER_HS_HW ; This is all we support
+ bne InvParam
+
+; Initialize buffers
+
+ jsr InitBuffers
+
+; Set the value for the control register, which contains stop bits, word
+; length and the baud rate.
+
+ ldy #SER_PARAMS::BAUDRATE
+ lda (ptr1),y ; Baudrate index
+ tay
+ lda BaudTable,y ; Get 6551 value
+ bmi InvBaud ; Branch if rate not supported
+ sta tmp1
+
+ ldy #SER_PARAMS::DATABITS ; Databits
+ lda (ptr1),y
+ tay
+ lda BitTable,y
+ ora tmp1
+ sta tmp1
+
+ ldy #SER_PARAMS::STOPBITS ; Stopbits
+ lda (ptr1),y
+ tay
+ lda StopTable,y
+ ora tmp1
+ ora #%00010000 ; Receiver clock source = baudrate
+ sta ACIA_CTRL
+
+; Set the value for the command register. We remember the base value in
+; RtsOff, since we will have to manipulate ACIA_CMD often.
+
+ ldy #SER_PARAMS::PARITY ; Parity
+ lda (ptr1),y
+ tay
+ lda ParityTable,y
+ ora #%00000001 ; DTR active
+ sta RtsOff
+ ora #%00001000 ; Enable receive interrupts
+ sta ACIA_CMD
+
+; Done
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+; Invalid parameter
+
+InvParam:
+ lda #<SER_ERR_INIT_FAILED
+ ldx #>SER_ERR_INIT_FAILED
+ rts
+
+; Baud rate not available
+
+InvBaud:
+ lda #<SER_ERR_BAUD_UNAVAIL
+ ldx #>SER_ERR_BAUD_UNAVAIL
+ rts
+
+;----------------------------------------------------------------------------
+; CLOSE: Close the port, disable interrupts and flush the buffer. Called
+; without parameters. Must return an error code in a/x.
+;
+
+CLOSE:
+
+; Stop interrupts, drop DTR
+
+ lda #%00001010
+ sta ACIA_CMD
+
+; Initalize buffers. Returns zero in a
+
+ jsr InitBuffers
+
+; Return OK
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+;----------------------------------------------------------------------------
+; GET: Will fetch a character from the receive buffer and store it into the
+; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; return.
+;
+
+GET: ldx SendFreeCnt ; Send data if necessary
+ inx ; X == $FF?
+ beq @L1
+ lda #$00
+ jsr TryToSend
+
+; Check for buffer empty
+
+@L1: lda RecvFreeCnt ; (25)
+ cmp #$ff
+ bne @L2
+ lda #<SER_ERR_NO_DATA
+ ldx #>SER_ERR_NO_DATA
+ rts
+
+; Check for flow stopped & enough free: release flow control
+
+@L2: ldx Stopped ; (34)
+ beq @L3
+ cmp #63
+ bcc @L3
+ lda #$00
+ sta Stopped
+ lda RtsOff
+ ora #%00001000
+ sta ACIA_CMD
+
+; Get byte from buffer
+
+@L3: ldx RecvHead ; (41)
+ lda RecvBuf,x
+ inc RecvHead
+ inc RecvFreeCnt
+ ldx #$00 ; (59)
+ sta (ptr1,x)
+ txa ; Return code = 0
+ rts
+
+;----------------------------------------------------------------------------
+; PUT: Output character in A.
+; Must return an error code in a/x.
+;
+
+PUT:
+
+; Try to send
+
+ ldx SendFreeCnt
+ inx ; X = $ff?
+ beq @L2
+ pha
+ lda #$00
+ jsr TryToSend
+ pla
+
+; Put byte into send buffer & send
+
+@L2: ldx SendFreeCnt
+ bne @L3
+ lda #<SER_ERR_OVERFLOW ; X is already zero
+ rts
+
+@L3: ldx SendTail
+ sta SendBuf,x
+ inc SendTail
+ dec SendFreeCnt
+ lda #$ff
+ jsr TryToSend
+ lda #<SER_ERR_OK
+ tax
+ rts
+
+;----------------------------------------------------------------------------
+; STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an error code in a/x.
+;
+
+STATUS: lda ACIA_STATUS
+ ldx #0
+ sta (ptr1,x)
+ txa ; SER_ERR_OK
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>SER_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Not used on the C64
+;
+
+IRQ = $0000
+
+;----------------------------------------------------------------------------
+;
+; NMI handler
+; C128 NMI overhead=76 cycles: int=7, maxLatency=6, ROMenter=33, ROMexit=30
+; C64 NMI overhead=76 cycles: int=7, maxLatency=6, ROMenter=34, ROMexit=29
+;
+; timing: normal=76+43+9=128 cycles, assertFlow=76+52+9=137 cycles
+;
+; C128 @ 115.2k: 177 cycles avail (fast)
+; C64 @ 57.6k: 177 cycles avail, worstAvail=177-43? = 134
+; SCPU @ 230.4k: 868 cycles avail: for a joke!
+;
+
+NmiHandler:
+ pha
+ lda ACIA_STATUS ;(4) ;status ;check for byte received
+ and #$08 ;(2)
+ beq @L9 ;(2*)
+ cld
+ txa
+ pha
+ tya
+ pha
+@L1: lda ACIA_DATA ;(4) data ;get byte and put into receive buffer
+ ldy RecvTail ;(4)
+ ldx RecvFreeCnt ;(4)
+ beq @L3 ;(2*) Jump if no space in receive buffer
+ sta RecvBuf,y ;(5)
+ inc RecvTail ;(6)
+ dec RecvFreeCnt ;(6)
+ cpx #33 ;(2) check for buffer space low
+ bcc @L2 ;(2*)
+ jmp NMIEXIT ;(3)
+
+; Assert flow control
+
+@L2: lda RtsOff ;(3) assert flow control if buffer space too low
+ sta ACIA_CMD ;(4) command
+ sta Stopped ;(3)
+@L3: jmp NMIEXIT ;(3)
+
+@L9: pla
+ jmp NmiContinue
+
+;----------------------------------------------------------------------------
+; Try to send a byte. Internal routine. A = TryHard
+
+.proc TryToSend
+
+ sta tmp1 ; Remember tryHard flag
+@L0: lda SendFreeCnt
+ cmp #$ff
+ beq @L3 ; Bail out
+
+; Check for flow stopped
+
+@L1: lda Stopped
+ bne @L3 ; Bail out
+
+; Check that swiftlink is ready to send
+
+@L2: lda ACIA_STATUS
+ and #$10
+ bne @L4
+ bit tmp1 ;keep trying if must try hard
+ bmi @L0
+@L3: rts
+
+; Send byte and try again
+
+@L4: ldx SendHead
+ lda SendBuf,x
+ sta ACIA_DATA
+ inc SendHead
+ inc SendFreeCnt
+ jmp @L0
+
+.endproc
+
+
+;----------------------------------------------------------------------------
+; Initialize buffers
+
+InitBuffers:
+ ldx #0
+ stx Stopped
+ stx RecvHead
+ stx RecvTail
+ stx SendHead
+ stx SendTail
+ dex ; X = 255
+ stx RecvFreeCnt
+ stx SendFreeCnt
+ rts
+
--- /dev/null
+;
+; Graphics driver for the 320x200x2 mode on the C64.
+;
+; Based on Stephen L. Judds GRLIB code
+;
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; 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
+ .word 320 ; X resolution
+ .word 200 ; Y resolution
+ .byte 2 ; Number of drawing colors
+ .byte 1 ; Number of screens available
+ .byte 8 ; System font X size
+ .byte 8 ; System font Y size
+ .word $00D4 ; Aspect ratio (based on 4/3 display)
+ .byte 0 ; TGI driver flags
+
+; Next comes the jump table. With the exception of IRQ, 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 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
+TEXT := ptr3
+
+ROW := tmp2 ; Bitmap row...
+COL := tmp3 ; ...and column, both set by PLOT
+TEMP := tmp4
+TEMP2 := sreg
+POINT := regsave
+INRANGE := regsave+2 ; PLOT variable, $00 = coordinates in range
+
+CHUNK := X2 ; Used in the line routine
+OLDCHUNK := X2+1 ; Dito
+
+; Absolute variables used in the code
+
+.bss
+
+ERROR: .res 1 ; Error code
+PALETTE: .res 2 ; The current palette
+
+BITMASK: .res 1 ; $00 = clear, $FF = set pixels
+
+; INIT/DONE
+OLDD018: .res 1 ; Old register value
+
+; Line routine stuff
+DX: .res 2
+DY: .res 2
+
+; BAR variables
+X1SAVE: .res 2
+Y1SAVE: .res 2
+X2SAVE: .res 2
+Y2SAVE: .res 2
+
+; Text output stuff
+TEXTMAGX: .res 1
+TEXTMAGY: .res 1
+TEXTDIR: .res 1
+
+; Constants and tables
+
+.rodata
+
+DEFPALETTE: .byte $00, $01 ; White on black
+PALETTESIZE = * - DEFPALETTE
+
+BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01
+BITCHUNK: .byte $FF,$7F,$3F,$1F,$0F,$07,$03,$01
+
+CHARROM := $D000 ; Character rom base address
+CBASE := $D000 ; Color memory base address
+VBASE := $E000 ; Video memory base address
+
+
+.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:
+ rts
+
+
+; ------------------------------------------------------------------------
+; 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:
+
+; Initialize variables
+
+ ldx #$FF
+ stx BITMASK
+
+; Switch into graphics mode
+
+ lda $DD02 ; Set the data direction regs
+ ora #3
+ sta $DD02
+ lda $DD00
+ and #$FC ; Switch to bank 3
+ sta $DD00
+
+ lda $D018
+ sta OLDD018
+ lda #$48 ; Set color map to $D000, screen to $E000
+ sta $D018
+
+ lda $D011 ; And turn on bitmap
+ ora #$20
+DONE1: sta $D011
+
+; 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: lda $DD02 ; Set the data direction regs
+ ora #3
+ sta $DD02
+ lda $DD00
+ ora #$03 ; Bank 0
+ sta $DD00
+
+ lda OLDD018 ; Screen mem --> $0400
+ sta $D018
+
+ lda $D011
+ and #<~$20
+ sta $D011
+ rts
+
+; ------------------------------------------------------------------------
+; 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: ldy #$00
+ tya
+@L1: sta VBASE+$0000,y
+ sta VBASE+$0100,y
+ sta VBASE+$0200,y
+ sta VBASE+$0300,y
+ sta VBASE+$0400,y
+ sta VBASE+$0500,y
+ sta VBASE+$0600,y
+ sta VBASE+$0700,y
+ sta VBASE+$0800,y
+ sta VBASE+$0900,y
+ sta VBASE+$0A00,y
+ sta VBASE+$0B00,y
+ sta VBASE+$0C00,y
+ sta VBASE+$0D00,y
+ sta VBASE+$0E00,y
+ sta VBASE+$0F00,y
+ sta VBASE+$1000,y
+ sta VBASE+$1100,y
+ sta VBASE+$1200,y
+ sta VBASE+$1300,y
+ sta VBASE+$1400,y
+ sta VBASE+$1500,y
+ sta VBASE+$1600,y
+ sta VBASE+$1700,y
+ sta VBASE+$1800,y
+ sta VBASE+$1900,y
+ sta VBASE+$1A00,y
+ sta VBASE+$1B00,y
+ sta VBASE+$1C00,y
+ sta VBASE+$1D00,y
+ sta VBASE+$1E00,y
+ sta VBASE+$1F00,y
+ iny
+ bne @L1
+ 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:
+ 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:
+ 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
+ beq @L1
+ lda #$FF
+@L1: sta BITMASK
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ ldy #PALETTESIZE - 1
+@L1: lda (ptr1),y ; Copy the palette
+ and #$0F ; Make a valid color
+ sta PALETTE,y
+ dey
+ bpl @L1
+
+; Get the color entries from the palette
+
+ lda PALETTE+1 ; Foreground color
+ asl a
+ asl a
+ asl a
+ asl a
+ ora PALETTE ; Background color
+ tax
+
+; Initialize the color map with the new color settings (it is below the
+; I/O area)
+
+ ldy #$00
+ sei
+ lda $01 ; Get ROM config
+ pha ; Save it
+ and #%11111100 ; Clear bit 0 and 1
+ sta $01
+ txa ; Load color code
+@L2: sta CBASE+$0000,y
+ sta CBASE+$0100,y
+ sta CBASE+$0200,y
+ sta CBASE+$0300,y
+ iny
+ bne @L2
+ pla
+ sta $01
+ cli
+
+; Done, reset the error code
+
+ lda #TGI_ERR_OK
+ 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:
+ lda #<PALETTE
+ ldx #>PALETTE
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ jsr CALC ; Calculate coordinates
+
+ sei ; Get underneath ROM
+ lda $01
+ pha
+ lda #$34
+ sta $01
+
+ lda (POINT),Y
+ eor BITMASK
+ and BITTAB,X
+ eor (POINT),Y
+ sta (POINT),Y
+
+ pla
+ sta $01
+ cli
+
+@L9: 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:
+ jsr CALC ; Calculate coordinates
+
+ sei ; Get underneath ROM
+ lda $01
+ pha
+ lda #$34
+ sta $01
+
+ lda (POINT),Y
+ ldy #$00
+ and BITTAB,X
+ beq @L1
+ iny
+
+@L1: pla
+ sta $01
+ cli
+
+ tya ; Get color value into A
+ ldx #$00 ; Clear high byte
+ 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.
+;
+; To deal with off-screen coordinates, the current row
+; and column (40x25) is kept track of. These are set
+; negative when the point is off the screen, and made
+; positive when the point is within the visible screen.
+;
+; X1,X2 etc. are set up above (x2=LINNUM in particular)
+; Format is LINE x2,y2,x1,y1
+;
+; Must set an error code: NO
+;
+
+LINE:
+
+@CHECK: lda X2 ;Make sure x1<x2
+ sec
+ sbc X1
+ tax
+ lda X2+1
+ sbc X1+1
+ bpl @CONT
+ lda Y2 ;If not, swap P1 and P2
+ ldy Y1
+ sta Y1
+ sty Y2
+ lda Y2+1
+ ldy Y1+1
+ sta Y1+1
+ sty Y2+1
+ lda X1
+ ldy X2
+ sty X1
+ sta X2
+ lda X2+1
+ ldy X1+1
+ sta X1+1
+ sty X2+1
+ bcc @CHECK
+
+@CONT: sta DX+1
+ stx DX
+
+ ldx #$C8 ;INY
+ lda Y2 ;Calculate dy
+ sec
+ sbc Y1
+ tay
+ lda Y2+1
+ sbc Y1+1
+ bpl @DYPOS ;Is y2>=y1?
+ lda Y1 ;Otherwise dy=y1-y2
+ sec
+ sbc Y2
+ tay
+ ldx #$88 ;DEY
+
+@DYPOS: sty DY ; 8-bit DY -- FIX ME?
+ stx YINCDEC
+ stx XINCDEC
+
+ jsr CALC ; Set up .X,.Y,POINT, and INRANGE
+ lda BITCHUNK,X
+ sta OLDCHUNK
+ sta CHUNK
+
+ sei ; Get underneath ROM
+ lda #$34
+ sta $01
+
+ ldx DY
+ cpx DX ;Who's bigger: dy or dx?
+ bcc STEPINX ;If dx, then...
+ lda DX+1
+ bne STEPINX
+
+;
+; Big steps in Y
+;
+; To simplify my life, just use PLOT to plot points.
+;
+; No more!
+; Added special plotting routine -- cool!
+;
+; X is now counter, Y is y-coordinate
+;
+; On entry, X=DY=number of loop iterations, and Y=
+; Y1 AND #$07
+STEPINY:
+ lda #00
+ sta OLDCHUNK ;So plotting routine will work right
+ lda CHUNK
+ lsr ;Strip the bit
+ eor CHUNK
+ sta CHUNK
+ txa
+ bne @CONT ;If dy=0 it's just a point
+ inx
+@CONT: lsr ;Init counter to dy/2
+;
+; Main loop
+;
+YLOOP: sta TEMP
+
+ lda INRANGE ;Range check
+ bne @SKIP
+
+ lda (POINT),y ;Otherwise plot
+ eor BITMASK
+ and CHUNK
+ eor (POINT),y
+ sta (POINT),y
+@SKIP:
+YINCDEC:
+ iny ;Advance Y coordinate
+ cpy #8
+ bcc @CONT ;No prob if Y=0..7
+ jsr FIXY
+@CONT: lda TEMP ;Restore A
+ sec
+ sbc DX
+ bcc YFIXX
+YCONT: dex ;X is counter
+ bne YLOOP
+YCONT2: lda (POINT),y ;Plot endpoint
+ eor BITMASK
+ and CHUNK
+ eor (POINT),y
+ sta (POINT),y
+YDONE: lda #$36
+ sta $01
+ cli
+ rts
+
+YFIXX: ;x=x+1
+ adc DY
+ lsr CHUNK
+ bne YCONT ;If we pass a column boundary...
+ ror CHUNK ;then reset CHUNK to $80
+ sta TEMP2
+ lda COL
+ bmi @C1 ;Skip if column is negative
+ cmp #39 ;End if move past end of screen
+ bcs YDONE
+@C1: lda POINT ;And add 8 to POINT
+ adc #8
+ sta POINT
+ bcc @CONT
+ inc POINT+1
+@CONT: inc COL ;Increment column
+ bne @C2
+ lda ROW ;Range check
+ cmp #25
+ bcs @C2
+ lda #00 ;Passed into col 0
+ sta INRANGE
+@C2: lda TEMP2
+ dex
+ bne YLOOP
+ beq YCONT2
+
+;
+; Big steps in X direction
+;
+; On entry, X=DY=number of loop iterations, and Y=
+; Y1 AND #$07
+
+.bss
+COUNTHI:
+ .byte $00 ;Temporary counter
+ ;only used once
+.code
+STEPINX:
+ ldx DX
+ lda DX+1
+ sta COUNTHI
+ cmp #$80
+ ror ;Need bit for initialization
+ sta Y1 ;High byte of counter
+ txa
+ bne @CONT ;Could be $100
+ dec COUNTHI
+@CONT: ror
+;
+; Main loop
+;
+XLOOP: lsr CHUNK
+ beq XFIXC ;If we pass a column boundary...
+XCONT1: sbc DY
+ bcc XFIXY ;Time to step in Y?
+XCONT2: dex
+ bne XLOOP
+ dec COUNTHI ;High bits set?
+ bpl XLOOP
+
+XDONE: lsr CHUNK ;Advance to last point
+ jsr LINEPLOT ;Plot the last chunk
+EXIT: lda #$36
+ sta $01
+ cli
+ rts
+;
+; CHUNK has passed a column, so plot and increment pointer
+; and fix up CHUNK, OLDCHUNK.
+;
+XFIXC: sta TEMP
+ jsr LINEPLOT
+ lda #$FF
+ sta CHUNK
+ sta OLDCHUNK
+ lda COL
+ bmi @C1 ;Skip if column is negative
+ cmp #39 ;End if move past end of screen
+ bcs EXIT
+@C1: lda POINT
+ adc #8
+ sta POINT
+ bcc @CONT
+ inc POINT+1
+@CONT: inc COL
+ bne @C2
+ lda ROW
+ cmp #25
+ bcs @C2
+ lda #00
+ sta INRANGE
+@C2: lda TEMP
+ sec
+ bcs XCONT1
+;
+; Check to make sure there isn't a high bit, plot chunk,
+; and update Y-coordinate.
+;
+XFIXY: dec Y1 ;Maybe high bit set
+ bpl XCONT2
+ adc DX
+ sta TEMP
+ lda DX+1
+ adc #$FF ;Hi byte
+ sta Y1
+
+ jsr LINEPLOT ;Plot chunk
+ lda CHUNK
+ sta OLDCHUNK
+
+ lda TEMP
+XINCDEC:
+ iny ;Y-coord
+ cpy #8 ;0..7 is ok
+ bcc XCONT2
+ sta TEMP
+ jsr FIXY
+ lda TEMP
+ jmp XCONT2
+
+;
+; Subroutine to plot chunks/points (to save a little
+; room, gray hair, etc.)
+;
+LINEPLOT: ; Plot the line chunk
+ lda INRANGE
+ bne @SKIP
+
+ lda (POINT),Y ; Otherwise plot
+ eor BITMASK
+ ora CHUNK
+ and OLDCHUNK
+ eor CHUNK
+ eor (POINT),Y
+ sta (POINT),Y
+@SKIP: rts
+
+;
+; Subroutine to fix up pointer when Y decreases through
+; zero or increases through 7.
+;
+FIXY: cpy #255 ;Y=255 or Y=8
+ beq @DECPTR
+@INCPTR: ;Add 320 to pointer
+ ldy #0 ;Y increased through 7
+ lda ROW
+ bmi @C1 ;If negative, then don't update
+ cmp #24
+ bcs @TOAST ;If at bottom of screen then quit
+@C1: lda POINT
+ adc #<320
+ sta POINT
+ lda POINT+1
+ adc #>320
+ sta POINT+1
+@CONT1: inc ROW
+ bne @DONE
+ lda COL
+ bpl @CLEAR
+@DONE: rts
+
+@DECPTR: ;Okay, subtract 320 then
+ ldy #7 ;Y decreased through 0
+ lda POINT
+ sec
+ sbc #<320
+ sta POINT
+ lda POINT+1
+ sbc #>320
+ sta POINT+1
+@CONT2: dec ROW
+ bmi @TOAST
+ lda ROW
+ cmp #24
+ bne @DONE
+ lda COL
+ bmi @DONE
+@CLEAR: lda #00
+ sta INRANGE
+ rts
+
+@TOAST: pla ;Remove old return address
+ pla
+ jmp EXIT ;Restore interrupts, etc.
+
+; ------------------------------------------------------------------------
+; 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
+;
+
+; Note: This function needs optimization. It's just a cheap translation of
+; the original C wrapper and could be written much smaller (besides that,
+; calling LINE is not a good idea either).
+
+BAR: lda Y2
+ sta Y2SAVE
+ lda Y2+1
+ sta Y2SAVE+1
+
+ lda X2
+ sta X2SAVE
+ lda X2+1
+ sta X2SAVE+1
+
+ lda Y1
+ sta Y1SAVE
+ lda Y1+1
+ sta Y1SAVE+1
+
+ lda X1
+ sta X1SAVE
+ lda X1+1
+ sta X1SAVE+1
+
+@L1: lda Y1
+ sta Y2
+ lda Y1+1
+ sta Y2+1
+ jsr LINE
+
+ lda Y1SAVE
+ cmp Y2SAVE
+ bne @L2
+ lda Y1SAVE
+ cmp Y2SAVE
+ beq @L4
+
+@L2: inc Y1SAVE
+ bne @L3
+ inc Y1SAVE+1
+
+@L3: lda Y1SAVE
+ sta Y1
+ lda Y1SAVE+1
+ sta Y1+1
+
+ lda X1SAVE
+ sta X1
+ lda X1SAVE+1
+ sta X1+1
+
+ lda X2SAVE
+ sta X2
+ lda X2SAVE+1
+ sta X2+1
+ jmp @L1
+
+@L4: rts
+
+
+; ------------------------------------------------------------------------
+; 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
+ 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:
+
+; Calculate a pointer to the representation of the character in the
+; character ROM
+
+ ldx #((>(CHARROM + $0800)) >> 3)
+ ldy #0
+ lda (TEXT),y
+ bmi @L1
+ ldx #((>(CHARROM + $0000)) >> 3)
+@L1: stx ptr4+1
+ asl a
+ rol ptr4+1
+ asl a
+ rol ptr4+1
+ asl a
+ rol ptr4+1
+ sta ptr4
+
+
+
+
+
+ rts
+
+; ------------------------------------------------------------------------
+; Calculate all variables to plot the pixel at X1/Y1. If the point is out
+; of range, a carry is returned and INRANGE is set to a value !0 zero. If
+; the coordinates are valid, INRANGE is zero and the carry clear.
+
+CALC: lda Y1
+ sta ROW
+ and #7
+ tay
+ lda Y1+1
+ lsr ; Neg is possible
+ ror ROW
+ lsr
+ ror ROW
+ lsr
+ ror ROW
+
+ lda #00
+ sta POINT
+ lda ROW
+ cmp #$80
+ ror
+ ror POINT
+ cmp #$80
+ ror
+ ror POINT ; row*64
+ adc ROW ; +row*256
+ clc
+ adc #>VBASE ; +bitmap base
+ sta POINT+1
+
+ lda X1
+ tax
+ sta COL
+ lda X1+1
+ lsr
+ ror COL
+ lsr
+ ror COL
+ lsr
+ ror COL
+
+ txa
+ and #$F8
+ clc
+ adc POINT ; +(X AND #$F8)
+ sta POINT
+ lda X1+1
+ adc POINT+1
+ sta POINT+1
+ txa
+ and #7
+ tax
+
+ lda ROW
+ cmp #25
+ bcs @L9
+ lda COL
+ cmp #40
+ bcs @L9
+ lda #00
+@L9: sta INRANGE
+ rts
+
+
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS = cbm_dir.o \
- cbm_load.o \
- cbm_save.o \
- opendir.o \
- readdir.o \
- seekdir.o
-
-S_OBJS = c_acptr.o \
- c_basin.o \
- c_bsout.o \
- c_chkin.o \
- c_ciout.o \
- c_ckout.o \
- c_clall.o \
- c_close.o \
- c_clrch.o \
- c_getin.o \
- c_iobase.o \
- c_listen.o \
- c_load.o \
- c_open.o \
- c_readst.o \
- c_save.o \
- c_setlfs.o \
- c_setnam.o \
- c_talk.o \
- c_unlsn.o \
- c_untlk.o \
- cbm_close.o \
- cbm_filetype.o \
- cbm_open.o \
- cbm_read.o \
- cbm_write.o \
- cclear.o \
- chline.o \
- clock.o \
- close.o \
- closedir.o \
- ctype.o \
- curdevice.o \
- cvline.o \
- devicedir.o \
- dir.o \
- diskcmd.o \
- diskinit.o \
- exehdr.o \
- filedes.o \
- filename.o \
- filetype.o \
- filevars.o \
- getdevice.o \
- gotox.o \
- gotoxy.o \
- gotoy.o \
- initcwd.o \
- loadaddr.o \
- open.o \
- oserrlist.o \
- oserror.o \
- read.o \
- rewinddir.o \
- rwcommon.o \
- scratch.o \
- syschdir.o \
- sysremove.o \
- sysrename.o \
- telldir.o \
- toascii.o \
- wherex.o \
- wherey.o \
- write.o
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @$(RM) *~ *.bck $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS)
-
-zap: clean
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = cbm510
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- banking.o \
- break.o \
- cgetc.o \
- clrscr.o \
- color.o \
- cputc.o \
- crt0.o \
- devnum.o \
- extzp.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- kclose.o \
- kernal.o \
- kiobase.o \
- kopen.o \
- krdtim.o \
- kreadst.o \
- kscnkey.o \
- kscreen.o \
- ksetnam.o \
- ksettim.o \
- kudtim.o \
- mainargs.o \
- peeksys.o \
- pokesys.o \
- randomize.o \
- revers.o \
- systime.o \
- sysuname.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS = cbm510-ram.emd
-
-JOYS = cbm510-stdjoy.joy
-
-SERS = cbm510-stdser.ser
-
-TGIS =
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS)
-
+++ /dev/null
-;
-; Extended memory driver for the CBM510 additional RAM banks. Driver works
-; without problems when linked statically.
-;
-; Ullrich von Bassewitz, 2002-12-09, 2003-12-27
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
- .include "cbm510.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-RAMBANK = 1
-OFFS = 2
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-curpage: .res 1 ; Current page number
-
-window: .res 256 ; Memory "window"
-pagecount: .res 1 ; Number of available pages
-
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- lda #$FF
- sta curpage ; Invalidate the current page
- sta pagecount ; Assume all memory available
-
- sec
- jsr $FF99 ; MEMTOP
-
- cmp #RAMBANK ; Top of memory in bank 2?
- bne @L1 ; No: We can use all the memory
- txa
- sub #OFFS
- tya
- sbc #$00
- sta pagecount
-
-@L1: lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx #0
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage ; Remember the new page
-
- sta ptr1+1
- lda #OFFS
- sta ptr1
-
-; Transfer one page
-
- ldx IndReg
- lda #RAMBANK
- sta IndReg
-
- ldy #$00
-@L1: .repeat 2
- lda (ptr1),y
- sta window,y
- iny
- .endrepeat
- bne @L1
-
- stx IndReg
-
-; Return the memory window
-
- lda #<window
- ldx #>window ; Return the window address
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage ; Get the current page
- cmp #$FF
- beq done ; Jump if no page mapped
-
- sta ptr1+1
- lda #OFFS
- sta ptr1
-
-; Transfer one page
-
- ldx IndReg
- lda #RAMBANK
- sta IndReg
-
- ldy #$00
-@L1: .repeat 2
- lda window,y
- sta (ptr1),y
- iny
- .endrepeat
- bne @L1
-
- stx IndReg
-
-; Done
-
-done: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
-
-; Setup the buffer address in this bank.
-
- sta copyfrom_buf
- stx copyfrom_buf+1
-
-; Check if we must copy full pages
-
- ldx ptr2+1
- beq @L2
-
-; Copy full pages
-
- ldx #$00
-@L1: jsr copyfrom
- inc ptr1+1
- inc copyfrom_buf+1
-@L2: dec ptr2+1
- bne @L1
-
-; Copy the remaining page
-
- ldx ptr2
- beq @L3
-
- jsr copyfrom
-
-; Restore the indirect segment
-
-@L3: lda ExecReg
- sta IndReg
-
-; Done
-
- rts
-
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO: jsr setup
-
-; Setup the buffer address in this bank.
-
- sta copyto_buf
- stx copyto_buf+1
-
-; Check if we must copy full pages
-
- ldx ptr2+1
- beq @L2
-
-; Copy full pages
-
- ldx #$00
-@L1: jsr copyto
- inc ptr1+1
- inc copyto_buf+1
-@L2: dec ptr2+1
- bne @L1
-
-; Copy the remaining page
-
- ldx ptr2
- beq @L3
-
- jsr copyto
-
-; Restore the indirect segment
-
-@L3: lda ExecReg
- sta IndReg
-
-; Done
-
- rts
-
-; ------------------------------------------------------------------------
-; setup: Helper function for COPYFROM and COPYTO, will setup parameters.
-;
-
-setup: sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- add #OFFS
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- adc #$00
- sta ptr1+1
-
- ldy #EM_COPY::COUNT
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; Get count into ptr2
-
- ldy #EM_COPY::BUF+1
- lda (ptr3),y
- tax
- dey
- lda (ptr3),y ; Get the buffer pointer into a/x
-
- ldy #RAMBANK
- sty IndReg
-
- ldy #$00
-
- rts
-
-; ------------------------------------------------------------------------
-; copyfrom
-
-.data
-copyfrom:
- lda (ptr1),y
-copyfrom_buf = * + 1
- sta $0000,y
- iny
- dex
- bne copyfrom
- rts
-
-; ------------------------------------------------------------------------
-; copyto
-
-.data
-copyto:
-copyto_buf = * + 1
- lda $0000,y
- sta (ptr1),y
- iny
- dex
- bne copyto
- rts
-
+++ /dev/null
-;
-; Standard joystick driver for the Commodore 510 (aka P500). May be used
-; multiple times when linked to the statically application.
-;
-; Ullrich von Bassewitz, 2003-02-16
-;
-
- .include "zeropage.inc"
- .include "extzp.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "cbm510.inc"
- .include "extzp.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: ldx #$0F ; Switch to the system bank
- stx IndReg
- tax ; Save joystick number
-
-; Get the direction bits
-
- ldy #CIA::PRB
- lda (cia2),y ; Read joystick inputs
- sta tmp1
-
-; Get the fire bits
-
- ldy #CIA::PRA
- lda (cia2),y
-
-; Make the result value
-
- cpx #$00 ; Joystick 0?
- bne @L1 ; Jump if no
-
-; Joystick 1, fire is in bit 6, direction in bit 0-3
-
- asl a
- jmp @L2
-
-; Joystick 2, fire is in bit 7, direction in bit 5-7
-
-@L1: ldx #$00 ; High byte of return value
- lsr tmp1
- lsr tmp1
- lsr tmp1
- lsr tmp1
-
-; Mask the relavant bits, get the fire bit
-
-@L2: asl a ; Fire bit into carry
- lda tmp1
- and #$0F
- bcc @L3
- ora #$10
-@L3: eor #$1F ; All bits are inverted
-
-; Switch back to the execution bank and return the joystick mask in a/x
-
- ldy ExecReg
- sty IndReg
- rts
-
+++ /dev/null
-;
-; Serial driver for the builtin 6551 ACIA of the Commodore 510.
-;
-; Ullrich von Bassewitz, 2003-12-18
-;
-; The driver is based on the cc65 rs232 module, which in turn is based on
-; Craig Bruce device driver for the Switftlink/Turbo-232.
-;
-; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
-;
-; This software is Public Domain. It is in Buddy assembler format.
-;
-; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
-; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
-; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
-; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
-;
-; The code assumes that the kernal + I/O are in context. On the C128, call
-; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
-; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
-; interrupt handling assumes that the 65816 is in 6502-emulation mode.
-;
-
- .include "zeropage.inc"
- .include "extzp.inc"
- .include "ser-kernel.inc"
- .include "ser-error.inc"
- .include "cbm510.inc"
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $73, $65, $72 ; "ser"
- .byte SER_API_VERSION ; Serial API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word OPEN
- .word CLOSE
- .word GET
- .word PUT
- .word STATUS
- .word IOCTL
- .word IRQ
-
-;----------------------------------------------------------------------------
-;
-; Global variables
-;
-
-.bss
-RecvHead: .res 1 ; Head of receive buffer
-RecvTail: .res 1 ; Tail of receive buffer
-RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
-SendHead: .res 1 ; Head of send buffer
-SendTail: .res 1 ; Tail of send buffer
-SendFreeCnt: .res 1 ; Number of bytes in send buffer
-
-Stopped: .res 1 ; Flow-stopped flag
-RtsOff: .res 1 ;
-
-; Send and receive buffers: 256 bytes each
-RecvBuf: .res 256
-SendBuf: .res 256
-
-.rodata
-
-; Tables used to translate RS232 params into register values
-
-BaudTable: ; bit7 = 1 means setting is invalid
- .byte $FF ; SER_BAUD_45_5
- .byte $01 ; SER_BAUD_50
- .byte $02 ; SER_BAUD_75
- .byte $03 ; SER_BAUD_110
- .byte $04 ; SER_BAUD_134_5
- .byte $05 ; SER_BAUD_150
- .byte $06 ; SER_BAUD_300
- .byte $07 ; SER_BAUD_600
- .byte $08 ; SER_BAUD_1200
- .byte $09 ; SER_BAUD_1800
- .byte $0A ; SER_BAUD_2400
- .byte $0B ; SER_BAUD_3600
- .byte $0C ; SER_BAUD_4800
- .byte $0D ; SER_BAUD_7200
- .byte $0E ; SER_BAUD_9600
- .byte $0F ; SER_BAUD_19200
- .byte $FF ; SER_BAUD_38400
- .byte $FF ; SER_BAUD_57600
- .byte $FF ; SER_BAUD_115200
- .byte $FF ; SER_BAUD_230400
-
-BitTable:
- .byte $60 ; SER_BITS_5
- .byte $40 ; SER_BITS_6
- .byte $20 ; SER_BITS_7
- .byte $00 ; SER_BITS_8
-
-StopTable:
- .byte $00 ; SER_STOP_1
- .byte $80 ; SER_STOP_2
-
-ParityTable:
- .byte $00 ; SER_PAR_NONE
- .byte $20 ; SER_PAR_ODD
- .byte $60 ; SER_PAR_EVEN
- .byte $A0 ; SER_PAR_MARK
- .byte $E0 ; SER_PAR_SPACE
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an SER_ERR_xx code in a/x.
-;
-; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
-; the same as:
-;
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Must return an SER_ERR_xx code in a/x.
-; and:
-;
-; CLOSE: Close the port, disable interrupts and flush the buffer. Called
-; without parameters. Must return an error code in a/x.
-;
-
-INSTALL:
-UNINSTALL:
-CLOSE:
-
-; Deactivate DTR and disable 6551 interrupts
-
- lda #%00001010
- jsr write_cmd
-
-; Done, return an error code
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-;----------------------------------------------------------------------------
-; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-OPEN:
-
-; Check if the handshake setting is valid
-
- ldy #SER_PARAMS::HANDSHAKE ; Handshake
- lda (ptr1),y
- cmp #SER_HS_HW ; This is all we support
- bne InvParam
-
-; Initialize buffers
-
- ldx #0
- stx Stopped
- stx RecvHead
- stx RecvTail
- stx SendHead
- stx SendTail
- dex ; X = 255
- stx RecvFreeCnt
- stx SendFreeCnt
-
-; Set the value for the control register, which contains stop bits, word
-; length and the baud rate.
-
- ldy #SER_PARAMS::BAUDRATE
- lda (ptr1),y ; Baudrate index
- tay
- lda BaudTable,y ; Get 6551 value
- bmi InvBaud ; Branch if rate not supported
- sta tmp1
-
- ldy #SER_PARAMS::DATABITS ; Databits
- lda (ptr1),y
- tay
- lda BitTable,y
- ora tmp1
- sta tmp1
-
- ldy #SER_PARAMS::STOPBITS ; Stopbits
- lda (ptr1),y
- tay
- lda StopTable,y
- ora tmp1
- ora #%00010000 ; Receiver clock source = baudrate
- ldy #ACIA::CTRL
- jsr write
-
-; Set the value for the command register. We remember the base value in
-; RtsOff, since we will have to manipulate ACIA_CMD often.
-
- ldy #SER_PARAMS::PARITY ; Parity
- lda (ptr1),y
- tay
- lda ParityTable,y
- ora #%00000001 ; DTR active
- sta RtsOff
- ora #%00001000 ; Enable receive interrupts
- jsr write_cmd
-
-; Done
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-; Invalid parameter
-
-InvParam:
- lda #<SER_ERR_INIT_FAILED
- ldx #>SER_ERR_INIT_FAILED
- rts
-
-; Baud rate not available
-
-InvBaud:
- lda #<SER_ERR_BAUD_UNAVAIL
- ldx #>SER_ERR_BAUD_UNAVAIL
- rts
-
-;----------------------------------------------------------------------------
-; GET: Will fetch a character from the receive buffer and store it into the
-; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
-; return.
-;
-
-GET: ldx SendFreeCnt ; Send data if necessary
- inx ; X == $FF?
- beq @L1
- lda #$00
- jsr TryToSend
-
-; Check for buffer empty
-
-@L1: lda RecvFreeCnt
- cmp #$ff
- bne @L2
- lda #<SER_ERR_NO_DATA
- ldx #>SER_ERR_NO_DATA
- rts
-
-; Check for flow stopped & enough free: release flow control
-
-@L2: ldx Stopped
- beq @L3
- cmp #63
- bcc @L3
- lda #$00
- sta Stopped
- lda RtsOff
- ora #%00001000
- jsr write_cmd
-
-; Get byte from buffer
-
-@L3: ldx RecvHead
- lda RecvBuf,x
- inc RecvHead
- inc RecvFreeCnt
- ldx #$00
- sta (ptr1,x)
- txa ; Return code = 0
- rts
-
-;----------------------------------------------------------------------------
-; PUT: Output character in A.
-; Must return an error code in a/x.
-;
-
-PUT:
-
-; Try to send
-
- ldx SendFreeCnt
- inx ; X = $ff?
- beq @L2
- pha
- lda #$00
- jsr TryToSend
- pla
-
-; Put byte into send buffer & send
-
-@L2: ldx SendFreeCnt
- bne @L3
- lda #<SER_ERR_OVERFLOW ; X is already zero
- rts
-
-@L3: ldx SendTail
- sta SendBuf,x
- inc SendTail
- dec SendFreeCnt
- lda #$ff
- jsr TryToSend
- lda #<SER_ERR_OK
- tax
- rts
-
-;----------------------------------------------------------------------------
-; STATUS: Return the status in the variable pointed to by ptr1.
-; Must return an error code in a/x.
-;
-
-STATUS: lda #$0F
- sta IndReg
- ldy #ACIA::STATUS
- lda (acia),y
- ldx #0
- sta (ptr1,x)
- lda IndReg
- sta ExecReg
- txa ; SER_ERR_OK
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>SER_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
-; registers are already save, no parameters are passed, but the carry flag
-; is clear on entry. The routine must return with carry set if the interrupt
-; was handled, otherwise with carry clear.
-;
-
-IRQ: lda #$0F
- sta IndReg ; Switch to the system bank
- ldy #ACIA::STATUS
- lda (acia),y ; Check ACIA status for receive interrupt
- and #$08
- beq @L9 ; Jump if no ACIA interrupt (carry still clear)
- ldy #ACIA::DATA
- lda (acia),y ; Get byte from ACIA
- ldx RecvFreeCnt ; Check if we have free space left
- beq @L1 ; Jump if no space in receive buffer
- ldy RecvTail ; Load buffer pointer
- sta RecvBuf,y ; Store received byte in buffer
- inc RecvTail ; Increment buffer pointer
- dec RecvFreeCnt ; Decrement free space counter
- cpx #33 ; Check for buffer space low
- bcs @L9 ; Assert flow control if buffer space low
-
-; Assert flow control if buffer space too low
-
-@L1: lda RtsOff
- ldy #ACIA::CMD
- sta (acia),y
- sta Stopped
- sec ; Interrupt handled
-
-; Done, switch back to the execution segment
-
-@L9: lda ExecReg
- sta IndReg
- rts
-
-;----------------------------------------------------------------------------
-; Try to send a byte. Internal routine. A = TryHard
-
-.proc TryToSend
-
- sta tmp1 ; Remember tryHard flag
- lda #$0F
- sta IndReg ; Switch to the system bank
-@L0: lda SendFreeCnt
- cmp #$ff
- beq @L3 ; Bail out
-
-; Check for flow stopped
-
-@L1: lda Stopped
- bne @L3 ; Bail out
-
-; Check that swiftlink is ready to send
-
-@L2: ldy #ACIA::STATUS
- lda (acia),y
- and #$10
- bne @L4
- bit tmp1 ; Keep trying if must try hard
- bmi @L0
-
-; Switch back the bank and return
-
-@L3: lda ExecReg
- sta IndReg
- rts
-
-; Send byte and try again
-
-@L4: ldx SendHead
- lda SendBuf,x
- ldy #ACIA::DATA
- sta (acia),y
- inc SendHead
- inc SendFreeCnt
- jmp @L0
-
-.endproc
-
-
-;----------------------------------------------------------------------------
-; Write to the ACIA changing the indirect segment. Offset is in Y, value in A.
-
-write_cmd:
- ldy #ACIA::CMD
-write: pha
- lda #$0F
- sta IndReg
- pla
- sta (acia),y
- lda ExecReg
- sta IndReg
- rts
-
--- /dev/null
+;
+; Extended memory driver for the CBM510 additional RAM banks. Driver works
+; without problems when linked statically.
+;
+; Ullrich von Bassewitz, 2002-12-09, 2003-12-27
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+ .include "cbm510.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+RAMBANK = 1
+OFFS = 2
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+curpage: .res 1 ; Current page number
+
+window: .res 256 ; Memory "window"
+pagecount: .res 1 ; Number of available pages
+
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ lda #$FF
+ sta curpage ; Invalidate the current page
+ sta pagecount ; Assume all memory available
+
+ sec
+ jsr $FF99 ; MEMTOP
+
+ cmp #RAMBANK ; Top of memory in bank 2?
+ bne @L1 ; No: We can use all the memory
+ txa
+ sub #OFFS
+ tya
+ sbc #$00
+ sta pagecount
+
+@L1: lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx #0
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage ; Remember the new page
+
+ sta ptr1+1
+ lda #OFFS
+ sta ptr1
+
+; Transfer one page
+
+ ldx IndReg
+ lda #RAMBANK
+ sta IndReg
+
+ ldy #$00
+@L1: .repeat 2
+ lda (ptr1),y
+ sta window,y
+ iny
+ .endrepeat
+ bne @L1
+
+ stx IndReg
+
+; Return the memory window
+
+ lda #<window
+ ldx #>window ; Return the window address
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage ; Get the current page
+ cmp #$FF
+ beq done ; Jump if no page mapped
+
+ sta ptr1+1
+ lda #OFFS
+ sta ptr1
+
+; Transfer one page
+
+ ldx IndReg
+ lda #RAMBANK
+ sta IndReg
+
+ ldy #$00
+@L1: .repeat 2
+ lda window,y
+ sta (ptr1),y
+ iny
+ .endrepeat
+ bne @L1
+
+ stx IndReg
+
+; Done
+
+done: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+
+; Setup the buffer address in this bank.
+
+ sta copyfrom_buf
+ stx copyfrom_buf+1
+
+; Check if we must copy full pages
+
+ ldx ptr2+1
+ beq @L2
+
+; Copy full pages
+
+ ldx #$00
+@L1: jsr copyfrom
+ inc ptr1+1
+ inc copyfrom_buf+1
+@L2: dec ptr2+1
+ bne @L1
+
+; Copy the remaining page
+
+ ldx ptr2
+ beq @L3
+
+ jsr copyfrom
+
+; Restore the indirect segment
+
+@L3: lda ExecReg
+ sta IndReg
+
+; Done
+
+ rts
+
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO: jsr setup
+
+; Setup the buffer address in this bank.
+
+ sta copyto_buf
+ stx copyto_buf+1
+
+; Check if we must copy full pages
+
+ ldx ptr2+1
+ beq @L2
+
+; Copy full pages
+
+ ldx #$00
+@L1: jsr copyto
+ inc ptr1+1
+ inc copyto_buf+1
+@L2: dec ptr2+1
+ bne @L1
+
+; Copy the remaining page
+
+ ldx ptr2
+ beq @L3
+
+ jsr copyto
+
+; Restore the indirect segment
+
+@L3: lda ExecReg
+ sta IndReg
+
+; Done
+
+ rts
+
+; ------------------------------------------------------------------------
+; setup: Helper function for COPYFROM and COPYTO, will setup parameters.
+;
+
+setup: sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ add #OFFS
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ adc #$00
+ sta ptr1+1
+
+ ldy #EM_COPY::COUNT
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; Get count into ptr2
+
+ ldy #EM_COPY::BUF+1
+ lda (ptr3),y
+ tax
+ dey
+ lda (ptr3),y ; Get the buffer pointer into a/x
+
+ ldy #RAMBANK
+ sty IndReg
+
+ ldy #$00
+
+ rts
+
+; ------------------------------------------------------------------------
+; copyfrom
+
+.data
+copyfrom:
+ lda (ptr1),y
+copyfrom_buf = * + 1
+ sta $0000,y
+ iny
+ dex
+ bne copyfrom
+ rts
+
+; ------------------------------------------------------------------------
+; copyto
+
+.data
+copyto:
+copyto_buf = * + 1
+ lda $0000,y
+ sta (ptr1),y
+ iny
+ dex
+ bne copyto
+ rts
+
--- /dev/null
+;
+; Standard joystick driver for the Commodore 510 (aka P500). May be used
+; multiple times when linked to the statically application.
+;
+; Ullrich von Bassewitz, 2003-02-16
+;
+
+ .include "zeropage.inc"
+ .include "../extzp.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "cbm510.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: ldx #$0F ; Switch to the system bank
+ stx IndReg
+ tax ; Save joystick number
+
+; Get the direction bits
+
+ ldy #CIA::PRB
+ lda (cia2),y ; Read joystick inputs
+ sta tmp1
+
+; Get the fire bits
+
+ ldy #CIA::PRA
+ lda (cia2),y
+
+; Make the result value
+
+ cpx #$00 ; Joystick 0?
+ bne @L1 ; Jump if no
+
+; Joystick 1, fire is in bit 6, direction in bit 0-3
+
+ asl a
+ jmp @L2
+
+; Joystick 2, fire is in bit 7, direction in bit 5-7
+
+@L1: ldx #$00 ; High byte of return value
+ lsr tmp1
+ lsr tmp1
+ lsr tmp1
+ lsr tmp1
+
+; Mask the relavant bits, get the fire bit
+
+@L2: asl a ; Fire bit into carry
+ lda tmp1
+ and #$0F
+ bcc @L3
+ ora #$10
+@L3: eor #$1F ; All bits are inverted
+
+; Switch back to the execution bank and return the joystick mask in a/x
+
+ ldy ExecReg
+ sty IndReg
+ rts
+
--- /dev/null
+;
+; Serial driver for the builtin 6551 ACIA of the Commodore 510.
+;
+; Ullrich von Bassewitz, 2003-12-18
+;
+; The driver is based on the cc65 rs232 module, which in turn is based on
+; Craig Bruce device driver for the Switftlink/Turbo-232.
+;
+; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
+;
+; This software is Public Domain. It is in Buddy assembler format.
+;
+; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
+; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
+; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
+; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
+;
+; The code assumes that the kernal + I/O are in context. On the C128, call
+; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
+; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
+; interrupt handling assumes that the 65816 is in 6502-emulation mode.
+;
+
+ .include "zeropage.inc"
+ .include "../extzp.inc"
+ .include "ser-kernel.inc"
+ .include "ser-error.inc"
+ .include "cbm510.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $73, $65, $72 ; "ser"
+ .byte SER_API_VERSION ; Serial API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word OPEN
+ .word CLOSE
+ .word GET
+ .word PUT
+ .word STATUS
+ .word IOCTL
+ .word IRQ
+
+;----------------------------------------------------------------------------
+;
+; Global variables
+;
+
+.bss
+RecvHead: .res 1 ; Head of receive buffer
+RecvTail: .res 1 ; Tail of receive buffer
+RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
+SendHead: .res 1 ; Head of send buffer
+SendTail: .res 1 ; Tail of send buffer
+SendFreeCnt: .res 1 ; Number of bytes in send buffer
+
+Stopped: .res 1 ; Flow-stopped flag
+RtsOff: .res 1 ;
+
+; Send and receive buffers: 256 bytes each
+RecvBuf: .res 256
+SendBuf: .res 256
+
+.rodata
+
+; Tables used to translate RS232 params into register values
+
+BaudTable: ; bit7 = 1 means setting is invalid
+ .byte $FF ; SER_BAUD_45_5
+ .byte $01 ; SER_BAUD_50
+ .byte $02 ; SER_BAUD_75
+ .byte $03 ; SER_BAUD_110
+ .byte $04 ; SER_BAUD_134_5
+ .byte $05 ; SER_BAUD_150
+ .byte $06 ; SER_BAUD_300
+ .byte $07 ; SER_BAUD_600
+ .byte $08 ; SER_BAUD_1200
+ .byte $09 ; SER_BAUD_1800
+ .byte $0A ; SER_BAUD_2400
+ .byte $0B ; SER_BAUD_3600
+ .byte $0C ; SER_BAUD_4800
+ .byte $0D ; SER_BAUD_7200
+ .byte $0E ; SER_BAUD_9600
+ .byte $0F ; SER_BAUD_19200
+ .byte $FF ; SER_BAUD_38400
+ .byte $FF ; SER_BAUD_57600
+ .byte $FF ; SER_BAUD_115200
+ .byte $FF ; SER_BAUD_230400
+
+BitTable:
+ .byte $60 ; SER_BITS_5
+ .byte $40 ; SER_BITS_6
+ .byte $20 ; SER_BITS_7
+ .byte $00 ; SER_BITS_8
+
+StopTable:
+ .byte $00 ; SER_STOP_1
+ .byte $80 ; SER_STOP_2
+
+ParityTable:
+ .byte $00 ; SER_PAR_NONE
+ .byte $20 ; SER_PAR_ODD
+ .byte $60 ; SER_PAR_EVEN
+ .byte $A0 ; SER_PAR_MARK
+ .byte $E0 ; SER_PAR_SPACE
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an SER_ERR_xx code in a/x.
+;
+; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
+; the same as:
+;
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Must return an SER_ERR_xx code in a/x.
+; and:
+;
+; CLOSE: Close the port, disable interrupts and flush the buffer. Called
+; without parameters. Must return an error code in a/x.
+;
+
+INSTALL:
+UNINSTALL:
+CLOSE:
+
+; Deactivate DTR and disable 6551 interrupts
+
+ lda #%00001010
+ jsr write_cmd
+
+; Done, return an error code
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+;----------------------------------------------------------------------------
+; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+OPEN:
+
+; Check if the handshake setting is valid
+
+ ldy #SER_PARAMS::HANDSHAKE ; Handshake
+ lda (ptr1),y
+ cmp #SER_HS_HW ; This is all we support
+ bne InvParam
+
+; Initialize buffers
+
+ ldx #0
+ stx Stopped
+ stx RecvHead
+ stx RecvTail
+ stx SendHead
+ stx SendTail
+ dex ; X = 255
+ stx RecvFreeCnt
+ stx SendFreeCnt
+
+; Set the value for the control register, which contains stop bits, word
+; length and the baud rate.
+
+ ldy #SER_PARAMS::BAUDRATE
+ lda (ptr1),y ; Baudrate index
+ tay
+ lda BaudTable,y ; Get 6551 value
+ bmi InvBaud ; Branch if rate not supported
+ sta tmp1
+
+ ldy #SER_PARAMS::DATABITS ; Databits
+ lda (ptr1),y
+ tay
+ lda BitTable,y
+ ora tmp1
+ sta tmp1
+
+ ldy #SER_PARAMS::STOPBITS ; Stopbits
+ lda (ptr1),y
+ tay
+ lda StopTable,y
+ ora tmp1
+ ora #%00010000 ; Receiver clock source = baudrate
+ ldy #ACIA::CTRL
+ jsr write
+
+; Set the value for the command register. We remember the base value in
+; RtsOff, since we will have to manipulate ACIA_CMD often.
+
+ ldy #SER_PARAMS::PARITY ; Parity
+ lda (ptr1),y
+ tay
+ lda ParityTable,y
+ ora #%00000001 ; DTR active
+ sta RtsOff
+ ora #%00001000 ; Enable receive interrupts
+ jsr write_cmd
+
+; Done
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+; Invalid parameter
+
+InvParam:
+ lda #<SER_ERR_INIT_FAILED
+ ldx #>SER_ERR_INIT_FAILED
+ rts
+
+; Baud rate not available
+
+InvBaud:
+ lda #<SER_ERR_BAUD_UNAVAIL
+ ldx #>SER_ERR_BAUD_UNAVAIL
+ rts
+
+;----------------------------------------------------------------------------
+; GET: Will fetch a character from the receive buffer and store it into the
+; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; return.
+;
+
+GET: ldx SendFreeCnt ; Send data if necessary
+ inx ; X == $FF?
+ beq @L1
+ lda #$00
+ jsr TryToSend
+
+; Check for buffer empty
+
+@L1: lda RecvFreeCnt
+ cmp #$ff
+ bne @L2
+ lda #<SER_ERR_NO_DATA
+ ldx #>SER_ERR_NO_DATA
+ rts
+
+; Check for flow stopped & enough free: release flow control
+
+@L2: ldx Stopped
+ beq @L3
+ cmp #63
+ bcc @L3
+ lda #$00
+ sta Stopped
+ lda RtsOff
+ ora #%00001000
+ jsr write_cmd
+
+; Get byte from buffer
+
+@L3: ldx RecvHead
+ lda RecvBuf,x
+ inc RecvHead
+ inc RecvFreeCnt
+ ldx #$00
+ sta (ptr1,x)
+ txa ; Return code = 0
+ rts
+
+;----------------------------------------------------------------------------
+; PUT: Output character in A.
+; Must return an error code in a/x.
+;
+
+PUT:
+
+; Try to send
+
+ ldx SendFreeCnt
+ inx ; X = $ff?
+ beq @L2
+ pha
+ lda #$00
+ jsr TryToSend
+ pla
+
+; Put byte into send buffer & send
+
+@L2: ldx SendFreeCnt
+ bne @L3
+ lda #<SER_ERR_OVERFLOW ; X is already zero
+ rts
+
+@L3: ldx SendTail
+ sta SendBuf,x
+ inc SendTail
+ dec SendFreeCnt
+ lda #$ff
+ jsr TryToSend
+ lda #<SER_ERR_OK
+ tax
+ rts
+
+;----------------------------------------------------------------------------
+; STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an error code in a/x.
+;
+
+STATUS: lda #$0F
+ sta IndReg
+ ldy #ACIA::STATUS
+ lda (acia),y
+ ldx #0
+ sta (ptr1,x)
+ lda IndReg
+ sta ExecReg
+ txa ; SER_ERR_OK
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>SER_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
+; registers are already save, no parameters are passed, but the carry flag
+; is clear on entry. The routine must return with carry set if the interrupt
+; was handled, otherwise with carry clear.
+;
+
+IRQ: lda #$0F
+ sta IndReg ; Switch to the system bank
+ ldy #ACIA::STATUS
+ lda (acia),y ; Check ACIA status for receive interrupt
+ and #$08
+ beq @L9 ; Jump if no ACIA interrupt (carry still clear)
+ ldy #ACIA::DATA
+ lda (acia),y ; Get byte from ACIA
+ ldx RecvFreeCnt ; Check if we have free space left
+ beq @L1 ; Jump if no space in receive buffer
+ ldy RecvTail ; Load buffer pointer
+ sta RecvBuf,y ; Store received byte in buffer
+ inc RecvTail ; Increment buffer pointer
+ dec RecvFreeCnt ; Decrement free space counter
+ cpx #33 ; Check for buffer space low
+ bcs @L9 ; Assert flow control if buffer space low
+
+; Assert flow control if buffer space too low
+
+@L1: lda RtsOff
+ ldy #ACIA::CMD
+ sta (acia),y
+ sta Stopped
+ sec ; Interrupt handled
+
+; Done, switch back to the execution segment
+
+@L9: lda ExecReg
+ sta IndReg
+ rts
+
+;----------------------------------------------------------------------------
+; Try to send a byte. Internal routine. A = TryHard
+
+.proc TryToSend
+
+ sta tmp1 ; Remember tryHard flag
+ lda #$0F
+ sta IndReg ; Switch to the system bank
+@L0: lda SendFreeCnt
+ cmp #$ff
+ beq @L3 ; Bail out
+
+; Check for flow stopped
+
+@L1: lda Stopped
+ bne @L3 ; Bail out
+
+; Check that swiftlink is ready to send
+
+@L2: ldy #ACIA::STATUS
+ lda (acia),y
+ and #$10
+ bne @L4
+ bit tmp1 ; Keep trying if must try hard
+ bmi @L0
+
+; Switch back the bank and return
+
+@L3: lda ExecReg
+ sta IndReg
+ rts
+
+; Send byte and try again
+
+@L4: ldx SendHead
+ lda SendBuf,x
+ ldy #ACIA::DATA
+ sta (acia),y
+ inc SendHead
+ inc SendFreeCnt
+ jmp @L0
+
+.endproc
+
+
+;----------------------------------------------------------------------------
+; Write to the ACIA changing the indirect segment. Offset is in Y, value in A.
+
+write_cmd:
+ ldy #ACIA::CMD
+write: pha
+ lda #$0F
+ sta IndReg
+ pla
+ sta (acia),y
+ lda ExecReg
+ sta IndReg
+ rts
+
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = cbm610
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- banking.o \
- break.o \
- cgetc.o \
- clrscr.o \
- color.o \
- cputc.o \
- crt0.o \
- crtc.o \
- devnum.o \
- extzp.o \
- get_tv.o \
- irq.o \
- kbhit.o \
- kclose.o \
- kernal.o \
- kiobase.o \
- kopen.o \
- krdtim.o \
- kreadst.o \
- kscnkey.o \
- kscreen.o \
- ksetnam.o \
- ksettim.o \
- kudtim.o \
- mainargs.o \
- peeksys.o \
- pokesys.o \
- randomize.o \
- revers.o \
- systime.o \
- sysuname.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS = cbm610-ram.emd
-
-JOYS =
-
-SERS = cbm610-stdser.ser
-
-TGIS =
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS)
+++ /dev/null
-;
-; Extended memory driver for the CBM610 additional RAM banks. Driver works
-; without problems when linked statically.
-;
-; Ullrich von Bassewitz, 2002-12-09, 2003-12-20
-;
-
- .include "zeropage.inc"
-
- .include "em-kernel.inc"
- .include "em-error.inc"
- .include "cbm610.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-RAMBANK = 2
-OFFS = 2
-
-; ------------------------------------------------------------------------
-; Data.
-
-.bss
-curpage: .res 1 ; Current page number
-
-window: .res 256 ; Memory "window"
-pagecount: .res 1 ; Number of available pages
-
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- lda #$FF
- sta curpage ; Invalidate the current page
- sta pagecount ; Assume all memory available
-
- sec
- jsr $FF99 ; MEMTOP
-
- cmp #RAMBANK ; Top of memory in bank 2?
- bne @L1 ; No: We can use all the memory
- txa
- sub #OFFS
- tya
- sbc #$00
- sta pagecount
-
-@L1: lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- rts
-
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx #0
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage ; Remember the new page
-
- sta ptr1+1
- lda #OFFS
- sta ptr1
-
-; Transfer one page
-
- ldx IndReg
- lda #RAMBANK
- sta IndReg
-
- ldy #$00
-@L1: .repeat 2
- lda (ptr1),y
- sta window,y
- iny
- .endrepeat
- bne @L1
-
- stx IndReg
-
-; Return the memory window
-
- lda #<window
- ldx #>window ; Return the window address
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage ; Remember the page
- lda #<window
- ldx #>window ; Return the window
- rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT: lda curpage ; Get the current page
- cmp #$FF
- beq done ; Jump if no page mapped
-
- sta ptr1+1
- lda #OFFS
- sta ptr1
-
-; Transfer one page
-
- ldx IndReg
- lda #RAMBANK
- sta IndReg
-
- ldy #$00
-@L1: .repeat 2
- lda window,y
- sta (ptr1),y
- iny
- .endrepeat
- bne @L1
-
- stx IndReg
-
-; Done
-
-done: rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
-
-; Setup the buffer address in this bank.
-
- sta copyfrom_buf
- stx copyfrom_buf+1
-
-; Check if we must copy full pages
-
- ldx ptr2+1
- beq @L2
-
-; Copy full pages
-
- ldx #$00
-@L1: jsr copyfrom
- inc ptr1+1
- inc copyfrom_buf+1
-@L2: dec ptr2+1
- bne @L1
-
-; Copy the remaining page
-
- ldx ptr2
- beq @L3
-
- jsr copyfrom
-
-; Restore the indirect segment
-
-@L3: lda ExecReg
- sta IndReg
-
-; Done
-
- rts
-
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO: jsr setup
-
-; Setup the buffer address in this bank.
-
- sta copyto_buf
- stx copyto_buf+1
-
-; Check if we must copy full pages
-
- ldx ptr2+1
- beq @L2
-
-; Copy full pages
-
- ldx #$00
-@L1: jsr copyto
- inc ptr1+1
- inc copyto_buf+1
-@L2: dec ptr2+1
- bne @L1
-
-; Copy the remaining page
-
- ldx ptr2
- beq @L3
-
- jsr copyto
-
-; Restore the indirect segment
-
-@L3: lda ExecReg
- sta IndReg
-
-; Done
-
- rts
-
-; ------------------------------------------------------------------------
-; setup: Helper function for COPYFROM and COPYTO, will setup parameters.
-;
-
-setup: sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- add #OFFS
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- adc #$00
- sta ptr1+1
-
- ldy #EM_COPY::COUNT
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; Get count into ptr2
-
- ldy #EM_COPY::BUF+1
- lda (ptr3),y
- tax
- dey
- lda (ptr3),y ; Get the buffer pointer into a/x
-
- ldy #RAMBANK
- sty IndReg
-
- ldy #$00
-
- rts
-
-; ------------------------------------------------------------------------
-; copyfrom
-
-.data
-copyfrom:
- lda (ptr1),y
-copyfrom_buf = * + 1
- sta $0000,y
- iny
- dex
- bne copyfrom
- rts
-
-; ------------------------------------------------------------------------
-; copyto
-
-.data
-copyto:
-copyto_buf = * + 1
- lda $0000,y
- sta (ptr1),y
- iny
- dex
- bne copyto
- rts
-
+++ /dev/null
-;
-; Serial driver for the builtin 6551 ACIA of the Commodore 610.
-;
-; Ullrich von Bassewitz, 2003-12-18
-;
-; The driver is based on the cc65 rs232 module, which in turn is based on
-; Craig Bruce device driver for the Switftlink/Turbo-232.
-;
-; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
-;
-; This software is Public Domain. It is in Buddy assembler format.
-;
-; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
-; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
-; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
-; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
-;
-; The code assumes that the kernal + I/O are in context. On the C128, call
-; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
-; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
-; interrupt handling assumes that the 65816 is in 6502-emulation mode.
-;
-
- .include "zeropage.inc"
- .include "extzp.inc"
- .include "ser-kernel.inc"
- .include "ser-error.inc"
- .include "cbm610.inc"
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $73, $65, $72 ; "ser"
- .byte SER_API_VERSION ; Serial API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word OPEN
- .word CLOSE
- .word GET
- .word PUT
- .word STATUS
- .word IOCTL
- .word IRQ
-
-;----------------------------------------------------------------------------
-;
-; Global variables
-;
-
-.bss
-RecvHead: .res 1 ; Head of receive buffer
-RecvTail: .res 1 ; Tail of receive buffer
-RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
-SendHead: .res 1 ; Head of send buffer
-SendTail: .res 1 ; Tail of send buffer
-SendFreeCnt: .res 1 ; Number of bytes in send buffer
-
-Stopped: .res 1 ; Flow-stopped flag
-RtsOff: .res 1 ;
-
-; Send and receive buffers: 256 bytes each
-RecvBuf: .res 256
-SendBuf: .res 256
-
-.rodata
-
-; Tables used to translate RS232 params into register values
-
-BaudTable: ; bit7 = 1 means setting is invalid
- .byte $FF ; SER_BAUD_45_5
- .byte $01 ; SER_BAUD_50
- .byte $02 ; SER_BAUD_75
- .byte $03 ; SER_BAUD_110
- .byte $04 ; SER_BAUD_134_5
- .byte $05 ; SER_BAUD_150
- .byte $06 ; SER_BAUD_300
- .byte $07 ; SER_BAUD_600
- .byte $08 ; SER_BAUD_1200
- .byte $09 ; SER_BAUD_1800
- .byte $0A ; SER_BAUD_2400
- .byte $0B ; SER_BAUD_3600
- .byte $0C ; SER_BAUD_4800
- .byte $0D ; SER_BAUD_7200
- .byte $0E ; SER_BAUD_9600
- .byte $0F ; SER_BAUD_19200
- .byte $FF ; SER_BAUD_38400
- .byte $FF ; SER_BAUD_57600
- .byte $FF ; SER_BAUD_115200
- .byte $FF ; SER_BAUD_230400
-
-BitTable:
- .byte $60 ; SER_BITS_5
- .byte $40 ; SER_BITS_6
- .byte $20 ; SER_BITS_7
- .byte $00 ; SER_BITS_8
-
-StopTable:
- .byte $00 ; SER_STOP_1
- .byte $80 ; SER_STOP_2
-
-ParityTable:
- .byte $00 ; SER_PAR_NONE
- .byte $20 ; SER_PAR_ODD
- .byte $60 ; SER_PAR_EVEN
- .byte $A0 ; SER_PAR_MARK
- .byte $E0 ; SER_PAR_SPACE
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an SER_ERR_xx code in a/x.
-;
-; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
-; the same as:
-;
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Must return an SER_ERR_xx code in a/x.
-;
-; and:
-;
-; CLOSE: Close the port, disable interrupts and flush the buffer. Called
-; without parameters. Must return an error code in a/x.
-;
-
-INSTALL:
-UNINSTALL:
-CLOSE:
-
-; Deactivate DTR and disable 6551 interrupts
-
- lda #%00001010
- jsr write_cmd
-
-; Done, return an error code
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-;----------------------------------------------------------------------------
-; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-OPEN:
-
-; Check if the handshake setting is valid
-
- ldy #SER_PARAMS::HANDSHAKE ; Handshake
- lda (ptr1),y
- cmp #SER_HS_HW ; This is all we support
- bne InvParam
-
-; Initialize buffers
-
- ldx #0
- stx Stopped
- stx RecvHead
- stx RecvTail
- stx SendHead
- stx SendTail
- dex ; X = 255
- stx RecvFreeCnt
- stx SendFreeCnt
-
-; Set the value for the control register, which contains stop bits, word
-; length and the baud rate.
-
- ldy #SER_PARAMS::BAUDRATE
- lda (ptr1),y ; Baudrate index
- tay
- lda BaudTable,y ; Get 6551 value
- bmi InvBaud ; Branch if rate not supported
- sta tmp1
-
- ldy #SER_PARAMS::DATABITS ; Databits
- lda (ptr1),y
- tay
- lda BitTable,y
- ora tmp1
- sta tmp1
-
- ldy #SER_PARAMS::STOPBITS ; Stopbits
- lda (ptr1),y
- tay
- lda StopTable,y
- ora tmp1
- ora #%00010000 ; Receiver clock source = baudrate
- ldy #ACIA::CTRL
- jsr write
-
-; Set the value for the command register. We remember the base value in
-; RtsOff, since we will have to manipulate ACIA_CMD often.
-
- ldy #SER_PARAMS::PARITY ; Parity
- lda (ptr1),y
- tay
- lda ParityTable,y
- ora #%00000001 ; DTR active
- sta RtsOff
- ora #%00001000 ; Enable receive interrupts
- jsr write_cmd
-
-; Done
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-; Invalid parameter
-
-InvParam:
- lda #<SER_ERR_INIT_FAILED
- ldx #>SER_ERR_INIT_FAILED
- rts
-
-; Baud rate not available
-
-InvBaud:
- lda #<SER_ERR_BAUD_UNAVAIL
- ldx #>SER_ERR_BAUD_UNAVAIL
- rts
-
-;----------------------------------------------------------------------------
-; GET: Will fetch a character from the receive buffer and store it into the
-; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
-; return.
-;
-
-GET: ldx SendFreeCnt ; Send data if necessary
- inx ; X == $FF?
- beq @L1
- lda #$00
- jsr TryToSend
-
-; Check for buffer empty
-
-@L1: lda RecvFreeCnt
- cmp #$ff
- bne @L2
- lda #<SER_ERR_NO_DATA
- ldx #>SER_ERR_NO_DATA
- rts
-
-; Check for flow stopped & enough free: release flow control
-
-@L2: ldx Stopped
- beq @L3
- cmp #63
- bcc @L3
- lda #$00
- sta Stopped
- lda RtsOff
- ora #%00001000
- jsr write_cmd
-
-; Get byte from buffer
-
-@L3: ldx RecvHead
- lda RecvBuf,x
- inc RecvHead
- inc RecvFreeCnt
- ldx #$00
- sta (ptr1,x)
- txa ; Return code = 0
- rts
-
-;----------------------------------------------------------------------------
-; PUT: Output character in A.
-; Must return an error code in a/x.
-;
-
-PUT:
-
-; Try to send
-
- ldx SendFreeCnt
- inx ; X = $ff?
- beq @L2
- pha
- lda #$00
- jsr TryToSend
- pla
-
-; Put byte into send buffer & send
-
-@L2: ldx SendFreeCnt
- bne @L3
- lda #<SER_ERR_OVERFLOW ; X is already zero
- rts
-
-@L3: ldx SendTail
- sta SendBuf,x
- inc SendTail
- dec SendFreeCnt
- lda #$ff
- jsr TryToSend
- lda #<SER_ERR_OK
- tax
- rts
-
-;----------------------------------------------------------------------------
-; STATUS: Return the status in the variable pointed to by ptr1.
-; Must return an error code in a/x.
-;
-
-STATUS: lda #$0F
- sta IndReg
- ldy #ACIA::STATUS
- lda (acia),y
- ldx #0
- sta (ptr1,x)
- lda IndReg
- sta ExecReg
- txa ; SER_ERR_OK
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>SER_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
-; registers are already save, no parameters are passed, but the carry flag
-; is clear on entry. The routine must return with carry set if the interrupt
-; was handled, otherwise with carry clear.
-;
-
-IRQ: lda #$0F
- sta IndReg ; Switch to the system bank
- ldy #ACIA::STATUS
- lda (acia),y ; Check ACIA status for receive interrupt
- and #$08
- beq @L9 ; Jump if no ACIA interrupt (carry still clear)
- ldy #ACIA::DATA
- lda (acia),y ; Get byte from ACIA
- ldx RecvFreeCnt ; Check if we have free space left
- beq @L1 ; Jump if no space in receive buffer
- ldy RecvTail ; Load buffer pointer
- sta RecvBuf,y ; Store received byte in buffer
- inc RecvTail ; Increment buffer pointer
- dec RecvFreeCnt ; Decrement free space counter
- cpx #33 ; Check for buffer space low
- bcs @L9 ; Assert flow control if buffer space low
-
-; Assert flow control if buffer space too low
-
-@L1: lda RtsOff
- ldy #ACIA::CMD
- sta (acia),y
- sta Stopped
- sec ; Interrupt handled
-
-; Done, switch back to the execution segment
-
-@L9: lda ExecReg
- sta IndReg
- rts
-
-;----------------------------------------------------------------------------
-; Try to send a byte. Internal routine. A = TryHard
-
-.proc TryToSend
-
- sta tmp1 ; Remember tryHard flag
- lda #$0F
- sta IndReg ; Switch to the system bank
-@L0: lda SendFreeCnt
- cmp #$ff
- beq @L3 ; Bail out
-
-; Check for flow stopped
-
-@L1: lda Stopped
- bne @L3 ; Bail out
-
-; Check that swiftlink is ready to send
-
-@L2: ldy #ACIA::STATUS
- lda (acia),y
- and #$10
- bne @L4
- bit tmp1 ; Keep trying if must try hard
- bmi @L0
-
-; Switch back the bank and return
-
-@L3: lda ExecReg
- sta IndReg
- rts
-
-; Send byte and try again
-
-@L4: ldx SendHead
- lda SendBuf,x
- ldy #ACIA::DATA
- sta (acia),y
- inc SendHead
- inc SendFreeCnt
- jmp @L0
-
-.endproc
-
-
-;----------------------------------------------------------------------------
-; Write to the ACIA changing the indirect segment. Offset is in Y, value in A.
-
-write_cmd:
- ldy #ACIA::CMD
-write: pha
- lda #$0F
- sta IndReg
- pla
- sta (acia),y
- lda ExecReg
- sta IndReg
- rts
-
--- /dev/null
+;
+; Extended memory driver for the CBM610 additional RAM banks. Driver works
+; without problems when linked statically.
+;
+; Ullrich von Bassewitz, 2002-12-09, 2003-12-20
+;
+
+ .include "zeropage.inc"
+
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+ .include "cbm610.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+RAMBANK = 2
+OFFS = 2
+
+; ------------------------------------------------------------------------
+; Data.
+
+.bss
+curpage: .res 1 ; Current page number
+
+window: .res 256 ; Memory "window"
+pagecount: .res 1 ; Number of available pages
+
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ lda #$FF
+ sta curpage ; Invalidate the current page
+ sta pagecount ; Assume all memory available
+
+ sec
+ jsr $FF99 ; MEMTOP
+
+ cmp #RAMBANK ; Top of memory in bank 2?
+ bne @L1 ; No: We can use all the memory
+ txa
+ sub #OFFS
+ tya
+ sbc #$00
+ sta pagecount
+
+@L1: lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ rts
+
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx #0
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage ; Remember the new page
+
+ sta ptr1+1
+ lda #OFFS
+ sta ptr1
+
+; Transfer one page
+
+ ldx IndReg
+ lda #RAMBANK
+ sta IndReg
+
+ ldy #$00
+@L1: .repeat 2
+ lda (ptr1),y
+ sta window,y
+ iny
+ .endrepeat
+ bne @L1
+
+ stx IndReg
+
+; Return the memory window
+
+ lda #<window
+ ldx #>window ; Return the window address
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+ rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT: lda curpage ; Get the current page
+ cmp #$FF
+ beq done ; Jump if no page mapped
+
+ sta ptr1+1
+ lda #OFFS
+ sta ptr1
+
+; Transfer one page
+
+ ldx IndReg
+ lda #RAMBANK
+ sta IndReg
+
+ ldy #$00
+@L1: .repeat 2
+ lda window,y
+ sta (ptr1),y
+ iny
+ .endrepeat
+ bne @L1
+
+ stx IndReg
+
+; Done
+
+done: rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+
+; Setup the buffer address in this bank.
+
+ sta copyfrom_buf
+ stx copyfrom_buf+1
+
+; Check if we must copy full pages
+
+ ldx ptr2+1
+ beq @L2
+
+; Copy full pages
+
+ ldx #$00
+@L1: jsr copyfrom
+ inc ptr1+1
+ inc copyfrom_buf+1
+@L2: dec ptr2+1
+ bne @L1
+
+; Copy the remaining page
+
+ ldx ptr2
+ beq @L3
+
+ jsr copyfrom
+
+; Restore the indirect segment
+
+@L3: lda ExecReg
+ sta IndReg
+
+; Done
+
+ rts
+
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO: jsr setup
+
+; Setup the buffer address in this bank.
+
+ sta copyto_buf
+ stx copyto_buf+1
+
+; Check if we must copy full pages
+
+ ldx ptr2+1
+ beq @L2
+
+; Copy full pages
+
+ ldx #$00
+@L1: jsr copyto
+ inc ptr1+1
+ inc copyto_buf+1
+@L2: dec ptr2+1
+ bne @L1
+
+; Copy the remaining page
+
+ ldx ptr2
+ beq @L3
+
+ jsr copyto
+
+; Restore the indirect segment
+
+@L3: lda ExecReg
+ sta IndReg
+
+; Done
+
+ rts
+
+; ------------------------------------------------------------------------
+; setup: Helper function for COPYFROM and COPYTO, will setup parameters.
+;
+
+setup: sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ add #OFFS
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ adc #$00
+ sta ptr1+1
+
+ ldy #EM_COPY::COUNT
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; Get count into ptr2
+
+ ldy #EM_COPY::BUF+1
+ lda (ptr3),y
+ tax
+ dey
+ lda (ptr3),y ; Get the buffer pointer into a/x
+
+ ldy #RAMBANK
+ sty IndReg
+
+ ldy #$00
+
+ rts
+
+; ------------------------------------------------------------------------
+; copyfrom
+
+.data
+copyfrom:
+ lda (ptr1),y
+copyfrom_buf = * + 1
+ sta $0000,y
+ iny
+ dex
+ bne copyfrom
+ rts
+
+; ------------------------------------------------------------------------
+; copyto
+
+.data
+copyto:
+copyto_buf = * + 1
+ lda $0000,y
+ sta (ptr1),y
+ iny
+ dex
+ bne copyto
+ rts
+
--- /dev/null
+;
+; Serial driver for the builtin 6551 ACIA of the Commodore 610.
+;
+; Ullrich von Bassewitz, 2003-12-18
+;
+; The driver is based on the cc65 rs232 module, which in turn is based on
+; Craig Bruce device driver for the Switftlink/Turbo-232.
+;
+; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
+;
+; This software is Public Domain. It is in Buddy assembler format.
+;
+; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
+; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
+; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
+; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
+;
+; The code assumes that the kernal + I/O are in context. On the C128, call
+; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
+; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
+; interrupt handling assumes that the 65816 is in 6502-emulation mode.
+;
+
+ .include "zeropage.inc"
+ .include "../extzp.inc"
+ .include "ser-kernel.inc"
+ .include "ser-error.inc"
+ .include "cbm610.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $73, $65, $72 ; "ser"
+ .byte SER_API_VERSION ; Serial API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word OPEN
+ .word CLOSE
+ .word GET
+ .word PUT
+ .word STATUS
+ .word IOCTL
+ .word IRQ
+
+;----------------------------------------------------------------------------
+;
+; Global variables
+;
+
+.bss
+RecvHead: .res 1 ; Head of receive buffer
+RecvTail: .res 1 ; Tail of receive buffer
+RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
+SendHead: .res 1 ; Head of send buffer
+SendTail: .res 1 ; Tail of send buffer
+SendFreeCnt: .res 1 ; Number of bytes in send buffer
+
+Stopped: .res 1 ; Flow-stopped flag
+RtsOff: .res 1 ;
+
+; Send and receive buffers: 256 bytes each
+RecvBuf: .res 256
+SendBuf: .res 256
+
+.rodata
+
+; Tables used to translate RS232 params into register values
+
+BaudTable: ; bit7 = 1 means setting is invalid
+ .byte $FF ; SER_BAUD_45_5
+ .byte $01 ; SER_BAUD_50
+ .byte $02 ; SER_BAUD_75
+ .byte $03 ; SER_BAUD_110
+ .byte $04 ; SER_BAUD_134_5
+ .byte $05 ; SER_BAUD_150
+ .byte $06 ; SER_BAUD_300
+ .byte $07 ; SER_BAUD_600
+ .byte $08 ; SER_BAUD_1200
+ .byte $09 ; SER_BAUD_1800
+ .byte $0A ; SER_BAUD_2400
+ .byte $0B ; SER_BAUD_3600
+ .byte $0C ; SER_BAUD_4800
+ .byte $0D ; SER_BAUD_7200
+ .byte $0E ; SER_BAUD_9600
+ .byte $0F ; SER_BAUD_19200
+ .byte $FF ; SER_BAUD_38400
+ .byte $FF ; SER_BAUD_57600
+ .byte $FF ; SER_BAUD_115200
+ .byte $FF ; SER_BAUD_230400
+
+BitTable:
+ .byte $60 ; SER_BITS_5
+ .byte $40 ; SER_BITS_6
+ .byte $20 ; SER_BITS_7
+ .byte $00 ; SER_BITS_8
+
+StopTable:
+ .byte $00 ; SER_STOP_1
+ .byte $80 ; SER_STOP_2
+
+ParityTable:
+ .byte $00 ; SER_PAR_NONE
+ .byte $20 ; SER_PAR_ODD
+ .byte $60 ; SER_PAR_EVEN
+ .byte $A0 ; SER_PAR_MARK
+ .byte $E0 ; SER_PAR_SPACE
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an SER_ERR_xx code in a/x.
+;
+; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
+; the same as:
+;
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Must return an SER_ERR_xx code in a/x.
+;
+; and:
+;
+; CLOSE: Close the port, disable interrupts and flush the buffer. Called
+; without parameters. Must return an error code in a/x.
+;
+
+INSTALL:
+UNINSTALL:
+CLOSE:
+
+; Deactivate DTR and disable 6551 interrupts
+
+ lda #%00001010
+ jsr write_cmd
+
+; Done, return an error code
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+;----------------------------------------------------------------------------
+; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+OPEN:
+
+; Check if the handshake setting is valid
+
+ ldy #SER_PARAMS::HANDSHAKE ; Handshake
+ lda (ptr1),y
+ cmp #SER_HS_HW ; This is all we support
+ bne InvParam
+
+; Initialize buffers
+
+ ldx #0
+ stx Stopped
+ stx RecvHead
+ stx RecvTail
+ stx SendHead
+ stx SendTail
+ dex ; X = 255
+ stx RecvFreeCnt
+ stx SendFreeCnt
+
+; Set the value for the control register, which contains stop bits, word
+; length and the baud rate.
+
+ ldy #SER_PARAMS::BAUDRATE
+ lda (ptr1),y ; Baudrate index
+ tay
+ lda BaudTable,y ; Get 6551 value
+ bmi InvBaud ; Branch if rate not supported
+ sta tmp1
+
+ ldy #SER_PARAMS::DATABITS ; Databits
+ lda (ptr1),y
+ tay
+ lda BitTable,y
+ ora tmp1
+ sta tmp1
+
+ ldy #SER_PARAMS::STOPBITS ; Stopbits
+ lda (ptr1),y
+ tay
+ lda StopTable,y
+ ora tmp1
+ ora #%00010000 ; Receiver clock source = baudrate
+ ldy #ACIA::CTRL
+ jsr write
+
+; Set the value for the command register. We remember the base value in
+; RtsOff, since we will have to manipulate ACIA_CMD often.
+
+ ldy #SER_PARAMS::PARITY ; Parity
+ lda (ptr1),y
+ tay
+ lda ParityTable,y
+ ora #%00000001 ; DTR active
+ sta RtsOff
+ ora #%00001000 ; Enable receive interrupts
+ jsr write_cmd
+
+; Done
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+; Invalid parameter
+
+InvParam:
+ lda #<SER_ERR_INIT_FAILED
+ ldx #>SER_ERR_INIT_FAILED
+ rts
+
+; Baud rate not available
+
+InvBaud:
+ lda #<SER_ERR_BAUD_UNAVAIL
+ ldx #>SER_ERR_BAUD_UNAVAIL
+ rts
+
+;----------------------------------------------------------------------------
+; GET: Will fetch a character from the receive buffer and store it into the
+; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; return.
+;
+
+GET: ldx SendFreeCnt ; Send data if necessary
+ inx ; X == $FF?
+ beq @L1
+ lda #$00
+ jsr TryToSend
+
+; Check for buffer empty
+
+@L1: lda RecvFreeCnt
+ cmp #$ff
+ bne @L2
+ lda #<SER_ERR_NO_DATA
+ ldx #>SER_ERR_NO_DATA
+ rts
+
+; Check for flow stopped & enough free: release flow control
+
+@L2: ldx Stopped
+ beq @L3
+ cmp #63
+ bcc @L3
+ lda #$00
+ sta Stopped
+ lda RtsOff
+ ora #%00001000
+ jsr write_cmd
+
+; Get byte from buffer
+
+@L3: ldx RecvHead
+ lda RecvBuf,x
+ inc RecvHead
+ inc RecvFreeCnt
+ ldx #$00
+ sta (ptr1,x)
+ txa ; Return code = 0
+ rts
+
+;----------------------------------------------------------------------------
+; PUT: Output character in A.
+; Must return an error code in a/x.
+;
+
+PUT:
+
+; Try to send
+
+ ldx SendFreeCnt
+ inx ; X = $ff?
+ beq @L2
+ pha
+ lda #$00
+ jsr TryToSend
+ pla
+
+; Put byte into send buffer & send
+
+@L2: ldx SendFreeCnt
+ bne @L3
+ lda #<SER_ERR_OVERFLOW ; X is already zero
+ rts
+
+@L3: ldx SendTail
+ sta SendBuf,x
+ inc SendTail
+ dec SendFreeCnt
+ lda #$ff
+ jsr TryToSend
+ lda #<SER_ERR_OK
+ tax
+ rts
+
+;----------------------------------------------------------------------------
+; STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an error code in a/x.
+;
+
+STATUS: lda #$0F
+ sta IndReg
+ ldy #ACIA::STATUS
+ lda (acia),y
+ ldx #0
+ sta (ptr1,x)
+ lda IndReg
+ sta ExecReg
+ txa ; SER_ERR_OK
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>SER_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
+; registers are already save, no parameters are passed, but the carry flag
+; is clear on entry. The routine must return with carry set if the interrupt
+; was handled, otherwise with carry clear.
+;
+
+IRQ: lda #$0F
+ sta IndReg ; Switch to the system bank
+ ldy #ACIA::STATUS
+ lda (acia),y ; Check ACIA status for receive interrupt
+ and #$08
+ beq @L9 ; Jump if no ACIA interrupt (carry still clear)
+ ldy #ACIA::DATA
+ lda (acia),y ; Get byte from ACIA
+ ldx RecvFreeCnt ; Check if we have free space left
+ beq @L1 ; Jump if no space in receive buffer
+ ldy RecvTail ; Load buffer pointer
+ sta RecvBuf,y ; Store received byte in buffer
+ inc RecvTail ; Increment buffer pointer
+ dec RecvFreeCnt ; Decrement free space counter
+ cpx #33 ; Check for buffer space low
+ bcs @L9 ; Assert flow control if buffer space low
+
+; Assert flow control if buffer space too low
+
+@L1: lda RtsOff
+ ldy #ACIA::CMD
+ sta (acia),y
+ sta Stopped
+ sec ; Interrupt handled
+
+; Done, switch back to the execution segment
+
+@L9: lda ExecReg
+ sta IndReg
+ rts
+
+;----------------------------------------------------------------------------
+; Try to send a byte. Internal routine. A = TryHard
+
+.proc TryToSend
+
+ sta tmp1 ; Remember tryHard flag
+ lda #$0F
+ sta IndReg ; Switch to the system bank
+@L0: lda SendFreeCnt
+ cmp #$ff
+ beq @L3 ; Bail out
+
+; Check for flow stopped
+
+@L1: lda Stopped
+ bne @L3 ; Bail out
+
+; Check that swiftlink is ready to send
+
+@L2: ldy #ACIA::STATUS
+ lda (acia),y
+ and #$10
+ bne @L4
+ bit tmp1 ; Keep trying if must try hard
+ bmi @L0
+
+; Switch back the bank and return
+
+@L3: lda ExecReg
+ sta IndReg
+ rts
+
+; Send byte and try again
+
+@L4: ldx SendHead
+ lda SendBuf,x
+ ldy #ACIA::DATA
+ sta (acia),y
+ inc SendHead
+ inc SendFreeCnt
+ jmp @L0
+
+.endproc
+
+
+;----------------------------------------------------------------------------
+; Write to the ACIA changing the indirect segment. Offset is in Y, value in A.
+
+write_cmd:
+ ldy #ACIA::CMD
+write: pha
+ lda #$0F
+ sta IndReg
+ pla
+ sta (acia),y
+ lda ExecReg
+ sta IndReg
+ rts
+
+++ /dev/null
-# -*- makefile -*-
-#
-# makefile for CC65's common library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -g -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Rules to help us see what code the compiler and assembler make.
-
-%.s : %.c
- @$(CC) $(CFLAGS) -S $<
-
-%.lst : %.s
- @$(AS) $(AFLAGS) -l -o /dev/null $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-# From C source-files
-C_OBJS = _afailed.o \
- _hextab.o \
- _longminstr.o \
- _poserror.o \
- _scanf.o \
- abort.o \
- asctime.o \
- bsearch.o \
- errormsg.o \
- fdopen.o \
- fgetc.o \
- fgetpos.o \
- fgets.o \
- fputc.o \
- fputs.o \
- freopen.o \
- fseek.o \
- fsetpos.o \
- ftell.o \
- getchar.o \
- getopt.o \
- gets.o \
- gmtime.o \
- locale.o \
- localtime.o \
- mktime.o \
- perror.o \
- pmemalign.o \
- puts.o \
- qsort.o \
- realloc.o \
- rewind.o \
- sleep.o \
- strftime.o \
- strtok.o \
- strtol.o \
- strtoul.o \
- strxfrm.o \
- system.o \
- timezone.o
-
-# From assembly source-files
-S_OBJS = _cwd.o \
- _environ.o \
- _fdesc.o \
- _file.o \
- _fopen.o \
- _heap.o \
- _heapadd.o \
- _heapblocksize.o \
- _heapmaxavail.o \
- _heapmemavail.o \
- _oserror.o \
- _printf.o \
- _seterrno.o \
- _swap.o \
- _sys.o \
- abs.o \
- atexit.o \
- atoi.o \
- calloc.o \
- cc65_idiv32by16r16.o \
- cc65_imul16x16r32.o \
- cc65_sincos.o \
- cc65_udiv32by16r16.o \
- cc65_umul16x16r32.o \
- cc65_umul16x8r32.o \
- chdir.o \
- copydata.o \
- creat.o \
- ctime.o \
- divt.o \
- errno.o \
- fclose.o \
- fmisc.o \
- fopen.o \
- fprintf.o \
- fread.o \
- free.o \
- fscanf.o \
- fwrite.o \
- getcpu.o \
- getcwd.o \
- getenv.o \
- interrupt.o \
- isalnum.o \
- isalpha.o \
- isblank.o \
- iscntrl.o \
- isdigit.o \
- isgraph.o \
- islower.o \
- isprint.o \
- ispunct.o \
- isspace.o \
- isupper.o \
- isxdigit.o \
- itoa.o \
- labs.o \
- longjmp.o \
- ltoa.o \
- malloc.o \
- memchr.o \
- memcmp.o \
- memcpy.o \
- memmove.o \
- memset.o \
- mkdir.o \
- modfree.o \
- modload.o \
- printf.o \
- putchar.o \
- putenv.o \
- rand.o \
- raise.o \
- remove.o \
- rename.o \
- rmdir.o \
- scanf.o \
- searchenv.o \
- setjmp.o \
- signal.o \
- sigtable.o \
- snprintf.o \
- sprintf.o \
- sscanf.o \
- strcat.o \
- strchr.o \
- strcmp.o \
- strcoll.o \
- strcpy.o \
- strcspn.o \
- strdup.o \
- strerror.o \
- stricmp.o \
- strlen.o \
- strlower.o \
- strncat.o \
- strncmp.o \
- strncpy.o \
- strnicmp.o \
- stroserr.o \
- strpbrk.o \
- strrchr.o \
- strspn.o \
- strstr.o \
- strtoimax.o \
- strtoumax.o \
- strupper.o \
- time.o \
- tolower.o \
- toupper.o \
- uname.o \
- ungetc.o \
- unlink.o \
- utscopy.o \
- vfprintf.o \
- vfscanf.o \
- vprintf.o \
- vscanf.o \
- vsnprintf.o \
- vsprintf.o \
- vsscanf.o \
- zerobss.o
-
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @$(RM) *~ *.lst
- @$(RM) $(C_OBJS:.o=.s)
- @$(RM) $(C_OBJS)
- @$(RM) $(S_OBJS)
-
-zap: clean
-
+++ /dev/null
-# -*- makefile -*-
-#
-# makefile for CC65's console library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Rules to help us see what code the compiler and assembler make.
-
-#%.s : %.c
-# @$(CC) $(CFLAGS) -S $<
-
-%.lst : %.s
- @$(AS) $(AFLAGS) -l -o /dev/null $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _cursor.o \
- cprintf.o \
- cputhex.o \
- cputs.o \
- cscanf.o \
- cursor.o \
- scrsize.o \
- vcprintf.o \
- vcscanf.o
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS)
-
-clean:
- @$(RM) *~ *.lst $(OBJS)
-
-zap: clean
-
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -g -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS = dbg.o
-
-S_OBJS = asmtab.o dbgdasm.o dbgdump.o dbgisram.o dbgsupp.o
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @$(RM) *~ $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS)
-
-zap: clean
-
+++ /dev/null
-#
-# Makefile for the extended memory library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -g -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS =
-
-S_OBJS = em-kernel.o \
- em_commit.o \
- em_copyto.o \
- em_copyfrom.o \
- em_load.o \
- em_map.o \
- em_pagecount.o \
- em_unload.o \
- em_use.o
-
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @$(RM) *~ $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS)
-
-zap: clean
-
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = geos-apple2
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I. -I../geos-common -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) -o $(notdir $(*).s) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Directories
-
-DIRS = disk
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS =
-
-JOYS =
-
-MOUS =
-
-SERS =
-
-TGIS =
-
-#--------------------------------------------------------------------------
-# Directives
-
-include $(addsuffix /Makefile, $(DIRS))
-vpath %.c $(DIRS)
-vpath %.s $(DIRS)
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(MOUS:.mou=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
--- /dev/null
+CFLAGS += -Wa -Igeos-apple,-Igeos-common
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += enterturbo.o \
- exitturbo.o \
- purgeturbo.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = geos-cbm
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I. -I../geos-common -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) -o $(notdir $(*).s) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Directories
-
-DIRS = disk \
- drivers \
- file \
- memory \
- system
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS = geos-vdc.emd
-
-JOYS = geos-stdjoy.joy
-
-MOUS =
-
-SERS =
-
-TGIS = geos-tgi.tgi
-
-#--------------------------------------------------------------------------
-# Directives
-
-include $(addsuffix /Makefile, $(DIRS))
-vpath %.c $(DIRS)
-vpath %.s $(DIRS)
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(MOUS:.mou=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
--- /dev/null
+CFLAGS += -Wa -Igeos-cbm,-Igeos-common
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += changediskdevice.o \
- chkdkgeos.o \
- dio_cts.o \
- dio_openclose.o \
- dio_params.o \
- dio_qcount.o \
- dio_qsize.o \
- dio_read.o \
- dio_stc.o \
- dio_write.o \
- dio_writev.o \
- enterturbo.o \
- exitturbo.o \
- findbambit.o \
- newdisk.o \
- purgeturbo.o \
- readblock.o \
- readbuff.o \
- setgeosdisk.o \
- writeblock.o \
- writebuff.o \
- verwriteblock.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += joy_stddrv.o \
- tgi_colors.o \
- tgi_stddrv.o
+++ /dev/null
-;
-; Standard joystick driver for the C64. May be used multiple times when linked
-; to the statically application.
-;
-; Ullrich von Bassewitz, 2002-12-20
-;
-
- .include "zeropage.inc"
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "geossym.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word COUNT
- .word READ
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
-; ------------------------------------------------------------------------
-; Data.
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ:
- tax
- php
- sei ; disable IRQ
- lda $01
- pha
- lda #$35
- sta $01 ; enable I/O
-
- txa ; Joystick number into X
- bne joy2
-
-; Read joystick 1
-
-joy1:
- lda #$7F
- sta cia1base
- lda cia1base+1
-back: tay
- pla
- sta $01
- plp
- tya
- and #$1F
- eor #$1F
- rts
-
-; Read joystick 2
-
-joy2: ldx #0
- lda #$E0
- ldy #$FF
- sta cia1base+2
- lda cia1base+1
- sty cia1base+2
- jmp back
+++ /dev/null
-;
-; Graphics driver for the 320x200x2 and 640x200x2 modes on GEOS 64/128
-; 2010-08-17, Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
-; 2010-08-18, Greg King
-
- .include "zeropage.inc"
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
- .include "const.inc"
- .include "jumptab.inc"
- .include "geossym.inc"
- .include "geossym2.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Constants
-
-VDC_ADDR_REG := $D600 ; VDC address
-VDC_DATA_REG := $D601 ; VDC data
-
-VDC_DSP_HI = 12 ; registers used
-VDC_DSP_LO = 13
-VDC_DATA_HI = 18
-VDC_DATA_LO = 19
-VDC_VSCROLL = 24
-VDC_HSCROLL = 25
-VDC_COLORS = 26
-VDC_CSET = 28
-VDC_COUNT = 30
-VDC_DATA = 31
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table and constants.
-
-.segment "JUMPTABLE"
-
-; First part of the header is a structure that has a magic signature,
-; and defines the capabilities of the driver.
-
- .byte $74, $67, $69 ; "tgi"
- .byte TGI_API_VERSION ; TGI API version number
-xres: .word 320 ; X resolution
-yres: .word 200 ; Y resolution
- .byte 2 ; Number of drawing colors
-pages: .byte 1 ; Number of screens available
- .byte 8 ; System font X size
- .byte 8 ; System font Y size
-aspect: .word $00D4 ; Aspect ratio (based on 4/3 display)
- .byte 0 ; TGI driver flags
-
-; Next comes the jump table. With the exception of IRQ, 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 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
-
-; Absolute variables used in the code
-
-.bss
-
-SCRBASE:
- .res 1 ; High byte of screen base (64k VDC only)
-
-ERROR:
- .res 1 ; Error code
-PALETTE:
- .res 2 ; The current palette
-
-BITMASK:
- .res 1 ; $00 = clear, $01 = set pixels
-
-OLDCOLOR:
- .res 1 ; colors before entering gfx mode
-
-; Text output stuff
-TEXTMAGX:
- .res 1
-TEXTMAGY:
- .res 1
-TEXTDIR:
- .res 1
-
-; Constants and tables
-
-.rodata
-
-DEFPALETTE:
- .byte $00, $0f ; White on black
-PALETTESIZE = * - DEFPALETTE
-
-; color translation table (indexed by VIC color)
-COLTRANS:
- .byte $00, $0f, $08, $06, $0a, $04, $02, $0c
- .byte $0d, $0b, $09, $01, $0e, $05, $03, $07
- ; colors BROWN and GRAY3 are wrong
-
-.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:
- lda version ; if GEOS 1.0...
- and #$f0
- cmp #$10
- beq @L40
- lda c128Flag ; at least GEOS 2.0, but we're on C128?
- bpl @L40
- lda graphMode ; GEOS 2.0, C128, but is 80 column screen enabled?
- bmi @L80
-@L40: rts ; leave default values for 40 column screen
-
- ; check for VDC version and update register $19 value
-
-@L80:
- ; double the x resolution and halve the aspect ratio
-
- asl xres
- rol xres+1
-
- lsr aspect+1
- ror aspect
-
- ; update number of available screens
-
- ldx #VDC_CSET ; determine size of RAM...
- jsr VDCReadReg
- sta tmp1
- ora #%00010000
- jsr VDCWriteReg ; turn on 64k
-
- jsr settestadr1 ; save original value of test byte
- jsr VDCReadByte
- sta tmp2
-
- lda #$55 ; write $55 here
- ldy #ptr1
- jsr test64k ; read it here and there
- lda #$aa ; write $aa here
- ldy #ptr2
- jsr test64k ; read it here and there
-
- jsr settestadr1
- lda tmp2
- jsr VDCWriteByte ; restore original value of test byte
-
- lda ptr1 ; do bytes match?
- cmp ptr1+1
- bne @have64k
- lda ptr2
- cmp ptr2+1
- bne @have64k
-
- ldx #VDC_CSET
- lda tmp1
- jsr VDCWriteReg ; restore 16/64k flag
- jmp @endok ; and leave default values for 16k
-
-@have64k:
- lda #4
- sta pages
-@endok:
- lda #0
- sta SCRBASE ; draw page 0 as default
- rts
-
-test64k:
- sta tmp1
- sty ptr3
- lda #0
- sta ptr3+1
- jsr settestadr1
- lda tmp1
- jsr VDCWriteByte ; write $55
- jsr settestadr1
- jsr VDCReadByte ; read here
- pha
- jsr settestadr2
- jsr VDCReadByte ; and there
- ldy #1
- sta (ptr3),y
- pla
- dey
- sta (ptr3),y
- rts
-
-settestadr1:
- ldy #$02 ; test page 2 (here)
- .byte $2c
-settestadr2:
- ldy #$42 ; or page 64+2 (there)
- lda #0
- jmp VDCSetSourceAddr
-
-; ------------------------------------------------------------------------
-; 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:
- ldx #$01
- stx BITMASK ; solid black as pattern
- lda #1
- jsr SetPattern
- lda #ST_WR_FORE ; write only on foreground
- sta dispBufferOn
-
- lda graphMode
- bmi @L80
-
-; Remember current color value (40 columns)
- lda screencolors
- sta OLDCOLOR
- jmp @L99
-
-; Remember current color value (80 columns)
-@L80: lda scr80colors
- sta OLDCOLOR
-@L99: lda #0
- jsr SETVIEWPAGE ; switch into viewpage 0
-
-; 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:
- lda #0
- jsr SETVIEWPAGE ; switch into viewpage 0
-
- lda graphMode
- bmi @L80
-
- lda OLDCOLOR
- sta screencolors ; restore color for 40 columns
- ldx #0
-@L1: sta COLOR_MATRIX,x
- sta COLOR_MATRIX+$0100,x
- sta COLOR_MATRIX+$0200,x
- sta COLOR_MATRIX+1000-256,x
- inx
- bne @L1
- rts
-
-@L80: lda OLDCOLOR ; restore color for 80 columns
- ldx #VDC_COLORS
- jmp VDCWriteReg
-
-; ------------------------------------------------------------------------
-; 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:
- lda curPattern
- pha
- lda #0
- jsr SetPattern
- ldx #0
- stx r3L
- stx r3H
- stx r2L
- lda #199
- sta r2H
- lda graphMode
- bpl @L40
- lda #>639 ; 80 columns
- ldx #<639
- bne @L99
-@L40: lda #>319 ; 40 columns
- ldx #<319
-@L99: sta r4H
- stx r4L
- jsr Rectangle
- pla
- sta curPattern
- 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:
- ldx graphMode
- bmi @L80
- rts
-@L80: clc
- ror
- ror
- ror
- ldx #VDC_DSP_HI
- jmp VDCWriteReg
-
-; ------------------------------------------------------------------------
-; 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:
- ldx graphMode
- bmi @L80
- rts
-@L80: clc
- ror
- ror
- ror
- sta SCRBASE
- 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
- beq @L1
- lda #1
-@L1: sta BITMASK
- jmp SetPattern ; need to have either 0 or 1
-
-; ------------------------------------------------------------------------
-; 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:
- jsr GETERROR ; clear error (if any)
-
- ldy #PALETTESIZE - 1
-@L1: lda (ptr1),y ; Copy the palette
- and #$0F ; Make a valid color
- sta PALETTE,y
- dey
- bpl @L1
-
-; Put colors from palette into screen
-
- lda graphMode
- bmi @L80
-
- lda PALETTE+1 ; foreground
- asl a
- asl a
- asl a
- asl a
- ora PALETTE ; background
- ldx #0
-@L2: sta COLOR_MATRIX,x
- sta COLOR_MATRIX+$0100,x
- sta COLOR_MATRIX+$0200,x
- sta COLOR_MATRIX+1000-256,x
- inx
- bne @L2
- rts
-
-@L80: ldy PALETTE+1 ; Foreground color
- lda COLTRANS,y
- asl a
- asl a
- asl a
- asl a
- ldy PALETTE ; Background color
- ora COLTRANS,y
-
- ldx #VDC_COLORS
- jmp VDCWriteReg
-
-; ------------------------------------------------------------------------
-; 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:
- lda #<PALETTE
- ldx #>PALETTE
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- lda X1
- ldx X1+1
- ldy Y1
- sta r3L
- stx r3H
- sty r11L
- sec
- lda BITMASK ; set or clear C flag
- bne @L1
- clc
-@L1: lda #0
- jmp DrawPoint
-
-; ------------------------------------------------------------------------
-; 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
- ldx X1+1
- ldy Y1
- sta r3L
- stx r3H
- sty r11L
- jsr TestPoint
- ldx #0
- bcc @L1
- inx
-@L1: txa
- ldx #0
- 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:
- lda X1
- ldx X1+1
- ldy Y1
- sta r3L
- stx r3H
- sty r11L
- lda X2
- ldx X2+1
- ldy Y2
- sta r4L
- stx r4H
- sty r11H
- sec
- lda BITMASK ; set or clear C flag
- bne @L1
- clc
-@L1: lda #0
- jmp DrawLine
-
-; ------------------------------------------------------------------------
-; 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:
- lda X1
- ldx X1+1
- ldy Y1
- sta r3L
- stx r3H
- sty r2L
- lda X2
- ldx X2+1
- ldy Y2
- sta r4L
- stx r4H
- sty r2H
- jmp Rectangle
-
-; ------------------------------------------------------------------------
-; 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
- 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:
- lda TEXTDIR
-; cmp #TGI_TEXT_HORIZONTAL ; this is equal 0
- bne @vertical
-
- lda X1 ; horizontal text output
- ldx X1+1
- ldy Y1
- sta r11L
- stx r11H
- sty r1H
- lda ptr3
- ldx ptr3+1
- sta r0L
- stx r0H
- jmp PutString
-
-@vertical:
- lda X1 ; vertical text output
- ldx X1+1
- ldy Y1
- sta r11L
- stx r11H
- sty r1H
- ldy #0
- lda (ptr3),y
- beq @end
- jsr PutChar
- inc ptr3
- bne @L1
- inc ptr3+1
-@L1: lda Y1
- clc
- adc #8
- sta Y1
- bne @vertical
-@end: rts
-
-;-------------
-; VDC helpers
-
-VDCSetSourceAddr:
- pha
- tya
- ldx #VDC_DATA_HI
- jsr VDCWriteReg
- pla
- ldx #VDC_DATA_LO
- bne VDCWriteReg
-
-VDCReadByte:
- ldx #VDC_DATA
-VDCReadReg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda VDC_DATA_REG
- rts
-
-VDCWriteByte:
- ldx #VDC_DATA
-VDCWriteReg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- sta VDC_DATA_REG
- rts
+++ /dev/null
-;
-; Extended memory driver for the VDC RAM available on all C128 machines
-; version for GEOS enters safe I/O config on C64 (transparent on C128)
-;
-; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
-; 06,20,25.12.2002
-
- .include "zeropage.inc"
- .include "em-kernel.inc"
- .include "em-error.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $65, $6d, $64 ; "emd"
- .byte EMD_API_VERSION ; EM API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word PAGECOUNT
- .word MAP
- .word USE
- .word COMMIT
- .word COPYFROM
- .word COPYTO
-
-; ------------------------------------------------------------------------
-; Constants
-
-VDC_ADDR_REG = $D600 ; VDC address
-VDC_DATA_REG = $D601 ; VDC data
-
-VDC_DATA_HI = 18 ; used registers
-VDC_DATA_LO = 19
-VDC_CSET = 28
-VDC_DATA = 31
-
-; ------------------------------------------------------------------------
-; Data.
-
-.data
-
-pagecount:
- .word 64 ; $0000-$3fff as 16k default
-curpage:
- .word $ffff ; currently mapped-in page (invalid)
-
-.bss
-
-window:
- .res 256 ; memory window
-
-.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 EM_ERR_xx code in a/x.
-;
-
-INSTALL:
- ; do test for VDC presence here???
-
- php
- sei
- lda $01
- pha
- lda #$35
- sta $01
-
- ldx #VDC_CSET ; determine size of RAM...
- jsr vdcgetreg
- sta tmp1
- ora #%00010000
- jsr vdcputreg ; turn on 64k
-
- jsr settestadr1 ; save original value of test byte
- jsr vdcgetbyte
- sta tmp2
-
- lda #$55 ; write $55 here
- ldy #ptr1
- jsr test64k ; read it here and there
- lda #$aa ; write $aa here
- ldy #ptr2
- jsr test64k ; read it here and there
-
- jsr settestadr1
- lda tmp2
- jsr vdcputbyte ; restore original value of test byte
-
- lda ptr1 ; do bytes match?
- cmp ptr1+1
- bne @have64k
- lda ptr2
- cmp ptr2+1
- bne @have64k
-
- ldx #VDC_CSET
- lda tmp1
- jsr vdcputreg ; restore 16/64k flag
- jmp @endok ; and leave default values for 16k
-
-@have64k:
- lda #<256
- ldx #>256
- sta pagecount
- stx pagecount+1
-@endok:
- pla
- sta $01
- plp
- lda #<EM_ERR_OK
- ldx #>EM_ERR_OK
- rts
-
-test64k:
- sta tmp1
- sty ptr3
- lda #0
- sta ptr3+1
- jsr settestadr1
- lda tmp1
- jsr vdcputbyte ; write $55
- jsr settestadr1
- jsr vdcgetbyte ; read here
- pha
- jsr settestadr2
- jsr vdcgetbyte ; and there
- ldy #1
- sta (ptr3),y
- pla
- dey
- sta (ptr3),y
- rts
-
-settestadr1:
- ldy #$02 ; test page 2 (here)
- .byte $2c
-settestadr2:
- ldy #$42 ; or page 64+2 (there)
- lda #0
- jmp vdcsetsrcaddr
-
-; ------------------------------------------------------------------------
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Can do cleanup or whatever. Must not return anything.
-;
-
-UNINSTALL:
- ;on C128 restore font and clear the screen?
- rts
-
-; ------------------------------------------------------------------------
-; PAGECOUNT: Return the total number of available pages in a/x.
-;
-
-PAGECOUNT:
- lda pagecount
- ldx pagecount+1
- rts
-
-; ------------------------------------------------------------------------
-; MAP: Map the page in a/x into memory and return a pointer to the page in
-; a/x. The contents of the currently mapped page (if any) may be discarded
-; by the driver.
-;
-
-MAP: sta curpage
- stx curpage+1
- sta ptr1+1
- ldy #0
- sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
- jsr transferin
-
- lda #<window
- ldx #>window
- rts
-
-; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
-
-transferin:
- php
- sei
- lda $01
- pha
- lda #$35
- sta $01
- lda ptr1
- ldy ptr1+1
- jsr vdcsetsrcaddr ; set source address in VDC
- ldy #0
- ldx #VDC_DATA
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda VDC_DATA_REG ; get 2 bytes at a time to speed-up
- sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config)
- iny
- lda VDC_DATA_REG
- sta (ptr2),y
- iny
- bne @L0
- pla
- sta $01
- plp
- rts
-
-; ------------------------------------------------------------------------
-; USE: Tell the driver that the window is now associated with a given page.
-
-USE: sta curpage
- stx curpage+1 ; Remember the page
- lda #<window
- ldx #>window ; Return the window
-done: rts
-
-; ------------------------------------------------------------------------
-; COMMIT: Commit changes in the memory window to extended storage.
-
-COMMIT:
- lda curpage ; jump if no page mapped
- ldx curpage+1
- bmi done
- sta ptr1+1
- ldy #0
- sty ptr1
-
- lda #<window
- sta ptr2
- lda #>window
- sta ptr2+1
-
-; fall through to transferout
-
-; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
-
-transferout:
- php
- sei
- lda $01
- pha
- lda #$35
- sta $01
- lda ptr1
- ldy ptr1+1
- jsr vdcsetsrcaddr ; set source address in VDC
- ldy #0
- ldx #VDC_DATA
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda (ptr2),y ; speedup does not work for writing
- sta VDC_DATA_REG
- iny
- bne @L0
- pla
- sta $01
- plp
- rts
-
-; ------------------------------------------------------------------------
-; COPYFROM: Copy from extended into linear memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYFROM:
- jsr setup
- beq @L2 ; Skip if no full pages
-
-; Copy full pages
-
-@L1: jsr transferin
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- sta tmp1
-
-; Transfer the bytes in the last page
- php
- sei
- lda $01
- pha
- lda #$35
- sta $01
- ldy #0
-@L3: jsr vdcgetbyte
- sta (ptr2),y
- iny
- dec tmp1
- lda tmp1
- bne @L3
- pla
- sta $01
- plp
-@L4: rts
-
-; ------------------------------------------------------------------------
-; COPYTO: Copy from linear into extended memory. A pointer to a structure
-; describing the request is passed in a/x.
-; The function must not return anything.
-;
-
-COPYTO:
- jsr setup
- beq @L2 ; Skip if no full pages
-
-; Copy full pages
-
-@L1: jsr transferout
- inc ptr1+1
- inc ptr2+1
- dec tmp1
- bne @L1
-
-; Copy the remainder of the page
-
-@L2: ldy #EM_COPY::COUNT
- lda (ptr3),y ; Get bytes in last page
- beq @L4
- sta tmp1
-
-; Transfer the bytes in the last page
- php
- sei
- lda $01
- pha
- lda #$35
- sta $01
- ldy #0
-@L3: lda (ptr2),y
- jsr vdcputbyte
- iny
- dec tmp1
- lda tmp1
- bne @L3
- pla
- sta $01
- plp
-@L4: rts
-
-;-------------------------------------------------------------------------
-; Helper functions to handle VDC ram
-;
-
-vdcsetsrcaddr:
- ldx #VDC_DATA_LO
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- sta VDC_DATA_REG
- dex
- tya
- stx VDC_ADDR_REG
- sta VDC_DATA_REG
- rts
-
-vdcgetbyte:
- ldx #VDC_DATA
-vdcgetreg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- lda VDC_DATA_REG
- rts
-
-vdcputbyte:
- ldx #VDC_DATA
-vdcputreg:
- stx VDC_ADDR_REG
-@L0: bit VDC_ADDR_REG
- bpl @L0
- sta VDC_DATA_REG
- rts
-
-; ------------------------------------------------------------------------
-; Helper function for COPYFROM and COPYTO: Store the pointer to the request
-; structure and prepare data for the copy
-;
-
-setup:
- sta ptr3
- stx ptr3+1 ; Save the passed em_copy pointer
-
- ldy #EM_COPY::OFFS
- lda (ptr3),y
- sta ptr1
- ldy #EM_COPY::PAGE
- lda (ptr3),y
- sta ptr1+1 ; From
-
- ldy #EM_COPY::BUF
- lda (ptr3),y
- sta ptr2
- iny
- lda (ptr3),y
- sta ptr2+1 ; To
-
- ldy #EM_COPY::COUNT+1
- lda (ptr3),y ; Get number of pages
- sta tmp1
- rts
+++ /dev/null
-;
-; Name of the standard joystick driver
-;
-; Ullrich von Bassewitz, 2002-12-21
-;
-; const char joy_stddrv[];
-;
-
- .export _joy_stddrv
-
-.rodata
-
-_joy_stddrv:
- .asciiz "geos-stdjoy.joy"
-
+++ /dev/null
-;
-; Target-specific black & white values, for use by the target-shared TGI kernel
-;
-
- .include "tgi-kernel.inc"
-
-tgi_color_black = $00
-tgi_color_white = $01
+++ /dev/null
-;
-; Name of the standard tgi driver
-;
-; Oliver Schmidt, 2011-05-02
-;
-; const char tgi_stddrv[];
-;
-
- .export _tgi_stddrv
-
-.rodata
-
-_tgi_stddrv:
- .asciiz "geos-tgi.tgi"
--- /dev/null
+;
+; Extended memory driver for the VDC RAM available on all C128 machines
+; version for GEOS enters safe I/O config on C64 (transparent on C128)
+;
+; Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 06,20,25.12.2002
+
+ .include "zeropage.inc"
+ .include "em-kernel.inc"
+ .include "em-error.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $65, $6d, $64 ; "emd"
+ .byte EMD_API_VERSION ; EM API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word PAGECOUNT
+ .word MAP
+ .word USE
+ .word COMMIT
+ .word COPYFROM
+ .word COPYTO
+
+; ------------------------------------------------------------------------
+; Constants
+
+VDC_ADDR_REG = $D600 ; VDC address
+VDC_DATA_REG = $D601 ; VDC data
+
+VDC_DATA_HI = 18 ; used registers
+VDC_DATA_LO = 19
+VDC_CSET = 28
+VDC_DATA = 31
+
+; ------------------------------------------------------------------------
+; Data.
+
+.data
+
+pagecount:
+ .word 64 ; $0000-$3fff as 16k default
+curpage:
+ .word $ffff ; currently mapped-in page (invalid)
+
+.bss
+
+window:
+ .res 256 ; memory window
+
+.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 EM_ERR_xx code in a/x.
+;
+
+INSTALL:
+ ; do test for VDC presence here???
+
+ php
+ sei
+ lda $01
+ pha
+ lda #$35
+ sta $01
+
+ ldx #VDC_CSET ; determine size of RAM...
+ jsr vdcgetreg
+ sta tmp1
+ ora #%00010000
+ jsr vdcputreg ; turn on 64k
+
+ jsr settestadr1 ; save original value of test byte
+ jsr vdcgetbyte
+ sta tmp2
+
+ lda #$55 ; write $55 here
+ ldy #ptr1
+ jsr test64k ; read it here and there
+ lda #$aa ; write $aa here
+ ldy #ptr2
+ jsr test64k ; read it here and there
+
+ jsr settestadr1
+ lda tmp2
+ jsr vdcputbyte ; restore original value of test byte
+
+ lda ptr1 ; do bytes match?
+ cmp ptr1+1
+ bne @have64k
+ lda ptr2
+ cmp ptr2+1
+ bne @have64k
+
+ ldx #VDC_CSET
+ lda tmp1
+ jsr vdcputreg ; restore 16/64k flag
+ jmp @endok ; and leave default values for 16k
+
+@have64k:
+ lda #<256
+ ldx #>256
+ sta pagecount
+ stx pagecount+1
+@endok:
+ pla
+ sta $01
+ plp
+ lda #<EM_ERR_OK
+ ldx #>EM_ERR_OK
+ rts
+
+test64k:
+ sta tmp1
+ sty ptr3
+ lda #0
+ sta ptr3+1
+ jsr settestadr1
+ lda tmp1
+ jsr vdcputbyte ; write $55
+ jsr settestadr1
+ jsr vdcgetbyte ; read here
+ pha
+ jsr settestadr2
+ jsr vdcgetbyte ; and there
+ ldy #1
+ sta (ptr3),y
+ pla
+ dey
+ sta (ptr3),y
+ rts
+
+settestadr1:
+ ldy #$02 ; test page 2 (here)
+ .byte $2c
+settestadr2:
+ ldy #$42 ; or page 64+2 (there)
+ lda #0
+ jmp vdcsetsrcaddr
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+ ;on C128 restore font and clear the screen?
+ rts
+
+; ------------------------------------------------------------------------
+; PAGECOUNT: Return the total number of available pages in a/x.
+;
+
+PAGECOUNT:
+ lda pagecount
+ ldx pagecount+1
+ rts
+
+; ------------------------------------------------------------------------
+; MAP: Map the page in a/x into memory and return a pointer to the page in
+; a/x. The contents of the currently mapped page (if any) may be discarded
+; by the driver.
+;
+
+MAP: sta curpage
+ stx curpage+1
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+ jsr transferin
+
+ lda #<window
+ ldx #>window
+ rts
+
+; copy a single page from (ptr1):VDCRAM to (ptr2):RAM
+
+transferin:
+ php
+ sei
+ lda $01
+ pha
+ lda #$35
+ sta $01
+ lda ptr1
+ ldy ptr1+1
+ jsr vdcsetsrcaddr ; set source address in VDC
+ ldy #0
+ ldx #VDC_DATA
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda VDC_DATA_REG ; get 2 bytes at a time to speed-up
+ sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config)
+ iny
+ lda VDC_DATA_REG
+ sta (ptr2),y
+ iny
+ bne @L0
+ pla
+ sta $01
+ plp
+ rts
+
+; ------------------------------------------------------------------------
+; USE: Tell the driver that the window is now associated with a given page.
+
+USE: sta curpage
+ stx curpage+1 ; Remember the page
+ lda #<window
+ ldx #>window ; Return the window
+done: rts
+
+; ------------------------------------------------------------------------
+; COMMIT: Commit changes in the memory window to extended storage.
+
+COMMIT:
+ lda curpage ; jump if no page mapped
+ ldx curpage+1
+ bmi done
+ sta ptr1+1
+ ldy #0
+ sty ptr1
+
+ lda #<window
+ sta ptr2
+ lda #>window
+ sta ptr2+1
+
+; fall through to transferout
+
+; copy a single page from (ptr2):RAM to (ptr1):VDCRAM
+
+transferout:
+ php
+ sei
+ lda $01
+ pha
+ lda #$35
+ sta $01
+ lda ptr1
+ ldy ptr1+1
+ jsr vdcsetsrcaddr ; set source address in VDC
+ ldy #0
+ ldx #VDC_DATA
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda (ptr2),y ; speedup does not work for writing
+ sta VDC_DATA_REG
+ iny
+ bne @L0
+ pla
+ sta $01
+ plp
+ rts
+
+; ------------------------------------------------------------------------
+; COPYFROM: Copy from extended into linear memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYFROM:
+ jsr setup
+ beq @L2 ; Skip if no full pages
+
+; Copy full pages
+
+@L1: jsr transferin
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+; Transfer the bytes in the last page
+ php
+ sei
+ lda $01
+ pha
+ lda #$35
+ sta $01
+ ldy #0
+@L3: jsr vdcgetbyte
+ sta (ptr2),y
+ iny
+ dec tmp1
+ lda tmp1
+ bne @L3
+ pla
+ sta $01
+ plp
+@L4: rts
+
+; ------------------------------------------------------------------------
+; COPYTO: Copy from linear into extended memory. A pointer to a structure
+; describing the request is passed in a/x.
+; The function must not return anything.
+;
+
+COPYTO:
+ jsr setup
+ beq @L2 ; Skip if no full pages
+
+; Copy full pages
+
+@L1: jsr transferout
+ inc ptr1+1
+ inc ptr2+1
+ dec tmp1
+ bne @L1
+
+; Copy the remainder of the page
+
+@L2: ldy #EM_COPY::COUNT
+ lda (ptr3),y ; Get bytes in last page
+ beq @L4
+ sta tmp1
+
+; Transfer the bytes in the last page
+ php
+ sei
+ lda $01
+ pha
+ lda #$35
+ sta $01
+ ldy #0
+@L3: lda (ptr2),y
+ jsr vdcputbyte
+ iny
+ dec tmp1
+ lda tmp1
+ bne @L3
+ pla
+ sta $01
+ plp
+@L4: rts
+
+;-------------------------------------------------------------------------
+; Helper functions to handle VDC ram
+;
+
+vdcsetsrcaddr:
+ ldx #VDC_DATA_LO
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ sta VDC_DATA_REG
+ dex
+ tya
+ stx VDC_ADDR_REG
+ sta VDC_DATA_REG
+ rts
+
+vdcgetbyte:
+ ldx #VDC_DATA
+vdcgetreg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda VDC_DATA_REG
+ rts
+
+vdcputbyte:
+ ldx #VDC_DATA
+vdcputreg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ sta VDC_DATA_REG
+ rts
+
+; ------------------------------------------------------------------------
+; Helper function for COPYFROM and COPYTO: Store the pointer to the request
+; structure and prepare data for the copy
+;
+
+setup:
+ sta ptr3
+ stx ptr3+1 ; Save the passed em_copy pointer
+
+ ldy #EM_COPY::OFFS
+ lda (ptr3),y
+ sta ptr1
+ ldy #EM_COPY::PAGE
+ lda (ptr3),y
+ sta ptr1+1 ; From
+
+ ldy #EM_COPY::BUF
+ lda (ptr3),y
+ sta ptr2
+ iny
+ lda (ptr3),y
+ sta ptr2+1 ; To
+
+ ldy #EM_COPY::COUNT+1
+ lda (ptr3),y ; Get number of pages
+ sta tmp1
+ rts
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += followchain.o
--- /dev/null
+;
+; Standard joystick driver for the C64. May be used multiple times when linked
+; to the statically application.
+;
+; Ullrich von Bassewitz, 2002-12-20
+;
+
+ .include "zeropage.inc"
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "geossym.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word COUNT
+ .word READ
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+; ------------------------------------------------------------------------
+; Data.
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ:
+ tax
+ php
+ sei ; disable IRQ
+ lda $01
+ pha
+ lda #$35
+ sta $01 ; enable I/O
+
+ txa ; Joystick number into X
+ bne joy2
+
+; Read joystick 1
+
+joy1:
+ lda #$7F
+ sta cia1base
+ lda cia1base+1
+back: tay
+ pla
+ sta $01
+ plp
+ tya
+ and #$1F
+ eor #$1F
+ rts
+
+; Read joystick 2
+
+joy2: ldx #0
+ lda #$E0
+ ldy #$FF
+ sta cia1base+2
+ lda cia1base+1
+ sty cia1base+2
+ jmp back
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += fetchram.o \
- reuregs.o \
- stashram.o \
- swapram.o \
- verifyram.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += get_ostype.o \
- getserialnumber.o \
- initdoneio.o \
- setdevice.o \
- tobasic.o
--- /dev/null
+;
+; Graphics driver for the 320x200x2 and 640x200x2 modes on GEOS 64/128
+; 2010-08-17, Maciej 'YTM/Elysium' Witkowiak <ytm@elysium.pl>
+; 2010-08-18, Greg King
+
+ .include "zeropage.inc"
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+ .include "const.inc"
+ .include "jumptab.inc"
+ .include "geossym.inc"
+ .include "geossym2.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; Constants
+
+VDC_ADDR_REG := $D600 ; VDC address
+VDC_DATA_REG := $D601 ; VDC data
+
+VDC_DSP_HI = 12 ; registers used
+VDC_DSP_LO = 13
+VDC_DATA_HI = 18
+VDC_DATA_LO = 19
+VDC_VSCROLL = 24
+VDC_HSCROLL = 25
+VDC_COLORS = 26
+VDC_CSET = 28
+VDC_COUNT = 30
+VDC_DATA = 31
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table and constants.
+
+.segment "JUMPTABLE"
+
+; First part of the header is a structure that has a magic signature,
+; and defines the capabilities of the driver.
+
+ .byte $74, $67, $69 ; "tgi"
+ .byte TGI_API_VERSION ; TGI API version number
+xres: .word 320 ; X resolution
+yres: .word 200 ; Y resolution
+ .byte 2 ; Number of drawing colors
+pages: .byte 1 ; Number of screens available
+ .byte 8 ; System font X size
+ .byte 8 ; System font Y size
+aspect: .word $00D4 ; Aspect ratio (based on 4/3 display)
+ .byte 0 ; TGI driver flags
+
+; Next comes the jump table. With the exception of IRQ, 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 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
+
+; Absolute variables used in the code
+
+.bss
+
+SCRBASE:
+ .res 1 ; High byte of screen base (64k VDC only)
+
+ERROR:
+ .res 1 ; Error code
+PALETTE:
+ .res 2 ; The current palette
+
+BITMASK:
+ .res 1 ; $00 = clear, $01 = set pixels
+
+OLDCOLOR:
+ .res 1 ; colors before entering gfx mode
+
+; Text output stuff
+TEXTMAGX:
+ .res 1
+TEXTMAGY:
+ .res 1
+TEXTDIR:
+ .res 1
+
+; Constants and tables
+
+.rodata
+
+DEFPALETTE:
+ .byte $00, $0f ; White on black
+PALETTESIZE = * - DEFPALETTE
+
+; color translation table (indexed by VIC color)
+COLTRANS:
+ .byte $00, $0f, $08, $06, $0a, $04, $02, $0c
+ .byte $0d, $0b, $09, $01, $0e, $05, $03, $07
+ ; colors BROWN and GRAY3 are wrong
+
+.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:
+ lda version ; if GEOS 1.0...
+ and #$f0
+ cmp #$10
+ beq @L40
+ lda c128Flag ; at least GEOS 2.0, but we're on C128?
+ bpl @L40
+ lda graphMode ; GEOS 2.0, C128, but is 80 column screen enabled?
+ bmi @L80
+@L40: rts ; leave default values for 40 column screen
+
+ ; check for VDC version and update register $19 value
+
+@L80:
+ ; double the x resolution and halve the aspect ratio
+
+ asl xres
+ rol xres+1
+
+ lsr aspect+1
+ ror aspect
+
+ ; update number of available screens
+
+ ldx #VDC_CSET ; determine size of RAM...
+ jsr VDCReadReg
+ sta tmp1
+ ora #%00010000
+ jsr VDCWriteReg ; turn on 64k
+
+ jsr settestadr1 ; save original value of test byte
+ jsr VDCReadByte
+ sta tmp2
+
+ lda #$55 ; write $55 here
+ ldy #ptr1
+ jsr test64k ; read it here and there
+ lda #$aa ; write $aa here
+ ldy #ptr2
+ jsr test64k ; read it here and there
+
+ jsr settestadr1
+ lda tmp2
+ jsr VDCWriteByte ; restore original value of test byte
+
+ lda ptr1 ; do bytes match?
+ cmp ptr1+1
+ bne @have64k
+ lda ptr2
+ cmp ptr2+1
+ bne @have64k
+
+ ldx #VDC_CSET
+ lda tmp1
+ jsr VDCWriteReg ; restore 16/64k flag
+ jmp @endok ; and leave default values for 16k
+
+@have64k:
+ lda #4
+ sta pages
+@endok:
+ lda #0
+ sta SCRBASE ; draw page 0 as default
+ rts
+
+test64k:
+ sta tmp1
+ sty ptr3
+ lda #0
+ sta ptr3+1
+ jsr settestadr1
+ lda tmp1
+ jsr VDCWriteByte ; write $55
+ jsr settestadr1
+ jsr VDCReadByte ; read here
+ pha
+ jsr settestadr2
+ jsr VDCReadByte ; and there
+ ldy #1
+ sta (ptr3),y
+ pla
+ dey
+ sta (ptr3),y
+ rts
+
+settestadr1:
+ ldy #$02 ; test page 2 (here)
+ .byte $2c
+settestadr2:
+ ldy #$42 ; or page 64+2 (there)
+ lda #0
+ jmp VDCSetSourceAddr
+
+; ------------------------------------------------------------------------
+; 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:
+ ldx #$01
+ stx BITMASK ; solid black as pattern
+ lda #1
+ jsr SetPattern
+ lda #ST_WR_FORE ; write only on foreground
+ sta dispBufferOn
+
+ lda graphMode
+ bmi @L80
+
+; Remember current color value (40 columns)
+ lda screencolors
+ sta OLDCOLOR
+ jmp @L99
+
+; Remember current color value (80 columns)
+@L80: lda scr80colors
+ sta OLDCOLOR
+@L99: lda #0
+ jsr SETVIEWPAGE ; switch into viewpage 0
+
+; 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:
+ lda #0
+ jsr SETVIEWPAGE ; switch into viewpage 0
+
+ lda graphMode
+ bmi @L80
+
+ lda OLDCOLOR
+ sta screencolors ; restore color for 40 columns
+ ldx #0
+@L1: sta COLOR_MATRIX,x
+ sta COLOR_MATRIX+$0100,x
+ sta COLOR_MATRIX+$0200,x
+ sta COLOR_MATRIX+1000-256,x
+ inx
+ bne @L1
+ rts
+
+@L80: lda OLDCOLOR ; restore color for 80 columns
+ ldx #VDC_COLORS
+ jmp VDCWriteReg
+
+; ------------------------------------------------------------------------
+; 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:
+ lda curPattern
+ pha
+ lda #0
+ jsr SetPattern
+ ldx #0
+ stx r3L
+ stx r3H
+ stx r2L
+ lda #199
+ sta r2H
+ lda graphMode
+ bpl @L40
+ lda #>639 ; 80 columns
+ ldx #<639
+ bne @L99
+@L40: lda #>319 ; 40 columns
+ ldx #<319
+@L99: sta r4H
+ stx r4L
+ jsr Rectangle
+ pla
+ sta curPattern
+ 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:
+ ldx graphMode
+ bmi @L80
+ rts
+@L80: clc
+ ror
+ ror
+ ror
+ ldx #VDC_DSP_HI
+ jmp VDCWriteReg
+
+; ------------------------------------------------------------------------
+; 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:
+ ldx graphMode
+ bmi @L80
+ rts
+@L80: clc
+ ror
+ ror
+ ror
+ sta SCRBASE
+ 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
+ beq @L1
+ lda #1
+@L1: sta BITMASK
+ jmp SetPattern ; need to have either 0 or 1
+
+; ------------------------------------------------------------------------
+; 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:
+ jsr GETERROR ; clear error (if any)
+
+ ldy #PALETTESIZE - 1
+@L1: lda (ptr1),y ; Copy the palette
+ and #$0F ; Make a valid color
+ sta PALETTE,y
+ dey
+ bpl @L1
+
+; Put colors from palette into screen
+
+ lda graphMode
+ bmi @L80
+
+ lda PALETTE+1 ; foreground
+ asl a
+ asl a
+ asl a
+ asl a
+ ora PALETTE ; background
+ ldx #0
+@L2: sta COLOR_MATRIX,x
+ sta COLOR_MATRIX+$0100,x
+ sta COLOR_MATRIX+$0200,x
+ sta COLOR_MATRIX+1000-256,x
+ inx
+ bne @L2
+ rts
+
+@L80: ldy PALETTE+1 ; Foreground color
+ lda COLTRANS,y
+ asl a
+ asl a
+ asl a
+ asl a
+ ldy PALETTE ; Background color
+ ora COLTRANS,y
+
+ ldx #VDC_COLORS
+ jmp VDCWriteReg
+
+; ------------------------------------------------------------------------
+; 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:
+ lda #<PALETTE
+ ldx #>PALETTE
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ lda X1
+ ldx X1+1
+ ldy Y1
+ sta r3L
+ stx r3H
+ sty r11L
+ sec
+ lda BITMASK ; set or clear C flag
+ bne @L1
+ clc
+@L1: lda #0
+ jmp DrawPoint
+
+; ------------------------------------------------------------------------
+; 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
+ ldx X1+1
+ ldy Y1
+ sta r3L
+ stx r3H
+ sty r11L
+ jsr TestPoint
+ ldx #0
+ bcc @L1
+ inx
+@L1: txa
+ ldx #0
+ 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:
+ lda X1
+ ldx X1+1
+ ldy Y1
+ sta r3L
+ stx r3H
+ sty r11L
+ lda X2
+ ldx X2+1
+ ldy Y2
+ sta r4L
+ stx r4H
+ sty r11H
+ sec
+ lda BITMASK ; set or clear C flag
+ bne @L1
+ clc
+@L1: lda #0
+ jmp DrawLine
+
+; ------------------------------------------------------------------------
+; 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:
+ lda X1
+ ldx X1+1
+ ldy Y1
+ sta r3L
+ stx r3H
+ sty r2L
+ lda X2
+ ldx X2+1
+ ldy Y2
+ sta r4L
+ stx r4H
+ sty r2H
+ jmp Rectangle
+
+; ------------------------------------------------------------------------
+; 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
+ 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:
+ lda TEXTDIR
+; cmp #TGI_TEXT_HORIZONTAL ; this is equal 0
+ bne @vertical
+
+ lda X1 ; horizontal text output
+ ldx X1+1
+ ldy Y1
+ sta r11L
+ stx r11H
+ sty r1H
+ lda ptr3
+ ldx ptr3+1
+ sta r0L
+ stx r0H
+ jmp PutString
+
+@vertical:
+ lda X1 ; vertical text output
+ ldx X1+1
+ ldy Y1
+ sta r11L
+ stx r11H
+ sty r1H
+ ldy #0
+ lda (ptr3),y
+ beq @end
+ jsr PutChar
+ inc ptr3
+ bne @L1
+ inc ptr3+1
+@L1: lda Y1
+ clc
+ adc #8
+ sta Y1
+ bne @vertical
+@end: rts
+
+;-------------
+; VDC helpers
+
+VDCSetSourceAddr:
+ pha
+ tya
+ ldx #VDC_DATA_HI
+ jsr VDCWriteReg
+ pla
+ ldx #VDC_DATA_LO
+ bne VDCWriteReg
+
+VDCReadByte:
+ ldx #VDC_DATA
+VDCReadReg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ lda VDC_DATA_REG
+ rts
+
+VDCWriteByte:
+ ldx #VDC_DATA
+VDCWriteReg:
+ stx VDC_ADDR_REG
+@L0: bit VDC_ADDR_REG
+ bpl @L0
+ sta VDC_DATA_REG
+ rts
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = geos-cbm
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I. -I../$(SYS) -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) -o $(notdir $(*).s) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Directories
-
-DIRS = common \
- conio \
- dlgbox \
- disk \
- file \
- graph \
- memory \
- menuicon \
- mousesprite \
- process \
- runtime \
- system
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS =
-
-JOYS =
-
-MOUS = #geos-stdmou.mou
-
-SERS =
-
-TGIS =
-
-#--------------------------------------------------------------------------
-# Directives
-
-include $(addsuffix /Makefile, $(DIRS))
-vpath %.c $(DIRS)
-vpath %.s $(DIRS)
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS) $(EMDS:.emd=.o) $(JOYS:.joy=.o) $(MOUS:.mou=.o) $(SERS:.ser=.o) $(TGIS:.tgi=.o)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS += _afailed.o \
- _poserror.o \
- abort.o \
- perror.o \
- sleep.o
-
-S_OBJS += copydata.o \
- memcpy.o \
- memmove.o \
- memset.o \
- zerobss.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += _scrsize.o \
- cclear.o \
- cgetc.o \
- chline.o \
- clrscr.o \
- cputc.o \
- cvline.o \
- dummies.o \
- gotoxy.o \
- kbhit.o \
- where.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += blkalloc.o \
- calcblksfree.o \
- freeblock.o \
- getblock.o \
- getdirhead.o \
- getptrcurdknm.o \
- gettrse.o \
- nxtblkalloc.o \
- opendisk.o \
- putblock.o \
- putdirhead.o \
- setnextfree.o
\ No newline at end of file
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS += messagebox.o
-
-S_OBJS += dbget2lines.o \
- dlgboxgetstring.o \
- dlgboxfileselect.o \
- dlgboxok.o \
- dlgboxokcancel.o \
- dlgboxyesno.o \
- dodlgbox.o \
- rstrfrmdialogue.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += fio_module.o \
- mcbdefault.o \
- mouse_stddrv.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += appendrecord.o \
- closerecordfile.o \
- deletefile.o \
- deleterecord.o \
- findfile.o \
- findftypes.o \
- freefile.o \
- get1stdirentry.o \
- getfhdrinfo.o \
- getfile.o \
- getnxtdirentry.o \
- insertrecord.o \
- nextrecord.o \
- openrecordfile.o \
- pointrecord.o \
- previousrecord.o \
- readbyte.o \
- readfile.o \
- readrecord.o \
- renamefile.o \
- savefile.o \
- sysremove.o \
- sysrename.o \
- updaterecordfile.o \
- writerecord.o
\ No newline at end of file
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += bitmapclip.o \
- bitmapregs.o \
- bitmapup.o \
- bitotherclip.o \
- drawline.o \
- drawpoint.o \
- framerectangle.o \
- getcharwidth.o \
- getintcharint.o \
- graphicsstring.o \
- hlineregs.o \
- horizontalline.o \
- imprintrectangle.o \
- initdrawwindow.o \
- invertline.o \
- invertrectangle.o \
- loadcharset.o \
- pointregs.o \
- put_char.o \
- putdecimal.o \
- putstring.o \
- recoverline.o \
- recoverrectangle.o \
- rectangle.o \
- setpattern.o \
- testpoint.o \
- usesystemfont.o \
- verticalline.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += clearram.o \
- cmpfstring.o \
- cmpstring.o \
- copyfstring.o \
- copystring.o \
- crc.o \
- doublepop.o \
- doublespop.o \
- fillram.o \
- initram.o \
- movedata.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += doicons.o \
- domenu.o \
- dopreviousmenu.o \
- gotofirstmenu.o \
- recoverallmenus.o \
- recovermenu.o \
- redomenu.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += clearmousemode.o \
- disablsprite.o \
- drawsprite.o \
- enablsprite.o \
- getnextchar.o \
- inittextprompt.o \
- ismseinregion.o \
- mouseoff.o \
- mouseup.o \
- possprite.o \
- promptoff.o \
- prompton.o \
- startmousemode.o
\ No newline at end of file
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += processblock.o \
- processfreeze.o \
- processinitrestartenable.o \
- processsleep.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-S_OBJS += call.o
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS += systime.o
-
-S_OBJS += callroutine.o \
- crt0.o \
- ctype.o \
- enterdesktop.o \
- extzp.o \
- firstinit.o \
- getrandom.o \
- mainargs.o \
- mainloop.o \
- oserrlist.o \
- oserror.o \
- panic.o \
- randomize.o \
- setoserror.o \
- sysuname.o
--- /dev/null
+;
+; Name of the standard joystick driver
+;
+; Ullrich von Bassewitz, 2002-12-21
+;
+; const char joy_stddrv[];
+;
+
+ .export _joy_stddrv
+
+.rodata
+
+_joy_stddrv:
+ .asciiz "geos-stdjoy.joy"
+
--- /dev/null
+;
+; Target-specific black & white values, for use by the target-shared TGI kernel
+;
+
+ .include "tgi-kernel.inc"
+
+tgi_color_black = $00
+tgi_color_white = $01
--- /dev/null
+;
+; Name of the standard tgi driver
+;
+; Oliver Schmidt, 2011-05-02
+;
+; const char tgi_stddrv[];
+;
+
+ .export _tgi_stddrv
+
+.rodata
+
+_tgi_stddrv:
+ .asciiz "geos-tgi.tgi"
+++ /dev/null
-#
-# Makefile for the joystick library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -g -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS =
-
-S_OBJS = joy-kernel.o \
- joy_read.o \
- joy_count.o \
- joy_load.o \
- joy_unload.o
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @$(RM) *~ $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS)
-
-zap: clean
-
-
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = lynx
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-mou.o: %.mou
- @$(CO) -o $(*)-mou.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-mou.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o extzp.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = bllhdr.o \
- bootldr.o \
- cgetc.o \
- clock.o \
- crt0.o \
- ctype.o \
- defdir.o \
- eeprom.o \
- eeprom46.o \
- eeprom66.o \
- eeprom86.o \
- exec.o \
- exehdr.o \
- extzp.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- load.o \
- lseek.o \
- lynx-cart.o \
- lynx-snd.o \
- mainargs.o \
- open.o \
- oserror.o \
- read.o \
- sysuname.o \
- tgi_colors.o \
- tgi_stat_stddrv.o \
- tgi_stddrv.o \
- toascii.o \
- uploader.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(MOUS:.mou=-mou.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS =
-
-JOYS = lynx-stdjoy.joy
-
-MOUS =
-
-SERS = lynx-comlynx.ser
-
-TGIS = lynx-160-102-16.tgi
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(MOUS:.mou=.o) $(MOUS:.mou=-mou.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
--- /dev/null
+;
+; Standard joystick driver for the Atari Lynx.
+; The Lynx has two fire buttons. So it is not quite "standard".
+;
+; Modified by Karri Kaksonen, 2004-09-16
+; Ullrich von Bassewitz, 2002-12-20
+; Using code from Steve Schmidtke
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "lynx.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+joy_mask:
+ .byte $80 ; JOY_UP
+ .byte $40 ; JOY_DOWN
+ .byte $20 ; JOY_LEFT
+ .byte $10 ; JOY_RIGHT
+ .byte $01 ; JOY_FIRE
+ .byte $02 ; JOY_FIRE1
+ .byte $00 ;
+ .byte $00 ;
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 1 ; Number of joysticks we support
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+
+READ:
+ ldx #$00 ; Clear high byte
+ lda JOYSTICK ; Read joystick
+ and #$F3 ; Mask relevant keys
+ rts
+
+
+++ /dev/null
-;
-; Graphics driver for the 160x102x16 mode on the Lynx.
-;
-; All the drawing functions are simply done by sprites as the sprite
-; engine is the only way to do fast graphics on a Lynx.
-;
-; This code is written by Karri Kaksonen, 2004 for the cc65 compiler.
-;
-
- .include "zeropage.inc"
- .include "extzp.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
-
- .include "lynx.inc"
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; 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
- .word 160 ; X resolution
- .word 102 ; Y resolution
- .byte 16 ; Number of drawing colors
- .byte 2 ; Number of screens available
- .byte 8 ; System font X size
- .byte 8 ; System font Y size
- .word $0100 ; Aspect ratio (square pixel LCD)
- .byte TGI_BM_FONT_FINESCALE ; TGI driver flags
-
-; Next comes the jump table. Currently all entries must be valid and may point
-; to an RTS for test versions (function not implemented). A future version may
-; allow for emulation: In this case the vector will be zero. Emulation means
-; that the graphics kernel will emulate the function by using lower level
-; primitives - for example ploting a line by using calls to SETPIXEL.
-
- .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 TEXTSTYLE
- .addr OUTTEXT
- .addr IRQ
-
-
-; ------------------------------------------------------------------------
-; 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
-
-STRPTR := ptr3
-FONTOFF := ptr4
-STROFF := tmp3
-STRLEN := tmp4
-
-; Absolute variables used in the code
-
-.bss
-
-ERROR: .res 1 ; Error code
-
-DRAWINDEX: .res 1 ; Pen to use for drawing
-VIEWPAGEL: .res 1
-VIEWPAGEH: .res 1
-DRAWPAGEL: .res 1
-DRAWPAGEH: .res 1
-
-; Text output stuff
-TEXTMAGX: .res 1
-TEXTMAGY: .res 1
-TEXTDIR: .res 1
-BGINDEX: .res 1 ; Pen to use for text background
-
-; Double buffer IRQ stuff
-DRAWPAGE: .res 1
-SWAPREQUEST: .res 1
-
-text_bitmap: .res 8*(1+20+1)+1
-; 8 rows with (one offset-byte plus 20 character bytes plus one fill-byte) plus one 0-offset-byte
-
-; Constants and tables
-
-.rodata
-
-DEFPALETTE: .byte >$011
- .byte >$34d
- .byte >$9af
- .byte >$9b8
- .byte >$777
- .byte >$335
- .byte >$448
- .byte >$75e
- .byte >$d5f
- .byte >$c53
- .byte >$822
- .byte >$223
- .byte >$484
- .byte >$8e5
- .byte >$cf5
- .byte >$fff
- .byte <$011
- .byte <$34d
- .byte <$9af
- .byte <$9b8
- .byte <$777
- .byte <$335
- .byte <$448
- .byte <$75e
- .byte <$d5f
- .byte <$c53
- .byte <$822
- .byte <$223
- .byte <$484
- .byte <$8e5
- .byte <$cf5
- .byte <$fff
-
-PALETTESIZE = * - DEFPALETTE
-
-.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:
- lda #1
- sta TEXTMAGX
- sta TEXTMAGY
- stz BGINDEX
- stz DRAWPAGE
- stz SWAPREQUEST
- rts
-
-
-; ------------------------------------------------------------------------
-; 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:
-; Enable interrupts for VBL
- lda #$80
- tsb VTIMCTLA
-; Set up collision buffer to $A058
- lda #$58
- sta COLLBASL
- lda #$A0
- sta COLLBASH
-; Put collision index before sprite data
- lda #$FF
- sta COLLOFFL
- lda #$FF
- sta COLLOFFH
-; 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:
- rts
-
-; ------------------------------------------------------------------------
-; 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
-;
-; The TGI lacks a way to draw sprites. As that functionality is vital to
-; Lynx games we borrow this CONTROL function to implement the still
-; missing tgi_draw_sprite funtion. To use this in your C-program
-; do a #define tgi_draw_sprite(spr) tgi_ioctl(0, spr)
-;
-; To do a flip-screen call tgi_ioctl(1, 0)
-;
-; To set the background index for text outputs call tgi_ioctl(2, bgindex)
-;
-; To set the frame rate for the display hardware call tgi_ioctl(3, rate)
-;
-; To check if the drawing engine is busy with the previous swap you can
-; call tgi_ioctl(4, 0). It returns 0 if idle and 1 if busy
-;
-; To update displays you can call tgi_ioctl(4, 1) it will wait for the
-; next VBL interrupt and swap draw and view buffers.
-;
-; Activate or deactivate collision detection by calling tgi_ioctl(5, 0/1).
-
-CONTROL:
- pha ; Almost all control routines succeed
- lda #TGI_ERR_OK
- sta ERROR
- pla
-
- cmp #5
- bne ControlSwap
- lda ptr1 ; Activate/deactivate collision detection
- bne @L0
- lda #%00000001 ; tgi_clear does not erase collision buffer
- sta cls_sprite
- lda #%00100000
- sta cls_sprite+2
- lda __sprsys
- ora #$20
- bra @L1
-@L0: lda #%00000000 ; tgi_clear erases collision buffer
- sta cls_sprite
- sta cls_sprite+2
- lda __sprsys
- and #$df
-@L1: sta __sprsys
- sta SPRSYS
- rts
-
-ControlSwap:
- cmp #4
- bne ControlFramerate
-
- lda ptr1 ; Swap request
- bne @L0
- lda SWAPREQUEST
- rts
-@L0: sta SWAPREQUEST
- rts
-
-ControlFramerate:
- cmp #3
- bne ControlTextBG
-
- lda ptr1
- cmp #75 ; Set framerate
- beq rate75
- cmp #60
- beq rate60
- cmp #50
- beq rate50
- lda #TGI_ERR_INV_ARG
- sta ERROR
- rts
-rate50: lda #$bd ; 50 Hz
- ldx #$31
- bra setRate
-rate60: lda #$9e ; 60 Hz
- ldx #$29
- bra setRate
-rate75: lda #$7e ; 75 Hz
- ldx #$20
-setRate:
- sta HTIMBKUP
- stx PBKUP
- rts
-
-ControlTextBG:
- cmp #2
- bne ControlFlipScreen
-
- lda ptr1 ; Set text background color
- sta BGINDEX
- rts
-
-ControlFlipScreen:
- cmp #1
- bne ControlDrawSprite
-
- lda __sprsys ; Flip screen
- eor #8
- sta __sprsys
- sta SPRSYS
- lda __viddma
- eor #2
- sta __viddma
- sta DISPCTL
- ldy VIEWPAGEL
- ldx VIEWPAGEH
- and #2
- beq NotFlipped
- clc
- tya
- adc #<8159
- tay
- txa
- adc #>8159
- tax
-NotFlipped:
- sty DISPADRL
- stx DISPADRH
- rts
-
-ControlDrawSprite:
- lda ptr1 ; Get the sprite address
- ldx ptr1+1
-
-draw_sprite: ; Draw it in render buffer
- sta SCBNEXTL
- stx SCBNEXTH
- lda DRAWPAGEL
- ldx DRAWPAGEH
- sta VIDBASL
- stx VIDBASH
- lda #1
- sta SPRGO
- stz SDONEACK
-@L0: stz CPUSLEEP
- lda SPRSYS
- lsr
- bcs @L0
- stz SDONEACK
- lda #TGI_ERR_OK
- sta ERROR
- rts
-
-; ------------------------------------------------------------------------
-; CLEAR: Clears the screen.
-;
-; Must set an error code: NO
-;
-
-.rodata
-pixel_bitmap:
- .byte 3,%10000100,%00000000, $0 ; A pixel bitmap
-.data
-cls_coll:
- .byte 0
-cls_sprite:
- .byte %00000001 ; A pixel sprite
- .byte %00010000
- .byte %00100000
- .addr 0,pixel_bitmap
- .word 0
- .word 0
- .word $a000 ; 160
- .word $6600 ; 102
- .byte $00
-
-.code
-CLEAR: lda #<cls_sprite
- ldx #>cls_sprite
- bra draw_sprite
-
-; ------------------------------------------------------------------------
-; 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)
-;
-; It is a good idea to call this function during the vertical blanking
-; period. If you call it in the middle of the screen update then half of
-; the drawn frame will be from the old buffer and the other half is
-; from the new buffer. This is usually noticed by the user.
-
-SETVIEWPAGE:
- cmp #1
- beq @L1 ; page == maxpages-1
- ldy #<$e018 ; page 0
- ldx #>$e018
- bra @L2
-@L1:
- ldy #<$c038 ; page 1
- ldx #>$c038
-@L2:
- sty VIEWPAGEL ; Save viewpage for getpixel
- stx VIEWPAGEH
-
- lda __viddma ; Process flipped displays
- and #2
- beq @L3
- clc
- tya
- adc #<8159
- tay
- txa
- adc #>8159
- tax
-@L3:
- sty DISPADRL ; $FD94
- stx DISPADRH ; $FD95
- 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:
- cmp #1
- beq @L1 ; page == maxpages-1
- lda #<$e018 ; page 0
- ldx #>$e018
- bra @L2
-@L1:
- lda #<$c038 ; page 1
- ldx #>$c038
-@L2:
- sta DRAWPAGEL
- stx DRAWPAGEH
- rts
-
-; ------------------------------------------------------------------------
-; IRQ: VBL interrupt handler
-;
-
-IRQ:
- lda INTSET ; Poll all pending interrupts
- and #VBL_INTERRUPT
- beq IRQEND ; Exit if not a VBL interrupt
-
- lda SWAPREQUEST
- beq @L0
- lda DRAWPAGE
- jsr SETVIEWPAGE
- lda DRAWPAGE
- eor #1
- sta DRAWPAGE
- jsr SETDRAWPAGE
- stz SWAPREQUEST
-@L0:
-IRQEND:
- clc
- 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:
- sta DRAWINDEX
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- ldy #31
-@L1: lda (ptr1),y
- sta GCOLMAP,y ; $FDA0
- dey
- bpl @L1
-
-; Done, reset the error code
-
- lda #TGI_ERR_OK
- 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:
- lda #<GCOLMAP ; $FDA0
- ldx #>GCOLMAP
- rts
-
-; ------------------------------------------------------------------------
-; 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
-;
-
-.data
-pixel_coll:
- .byte 0
-pixel_sprite:
- .byte %00000001 ; A pixel sprite
- .byte %00010000
- .byte %00100000
- .addr 0,pixel_bitmap
-pix_x: .word 0
-pix_y: .word 0
- .word $100
- .word $100
-pix_c: .byte $00
-
-.code
-SETPIXEL:
- lda X1
- sta pix_x
- lda Y1
- sta pix_y
- lda DRAWINDEX
- sta pix_c
- lda #<pixel_sprite
- ldx #>pixel_sprite
- jmp draw_sprite
-
-; ------------------------------------------------------------------------
-; 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 Y1
- sta MATHD ; Hardware multiply
- stz MATHC
- lda #80
- sta MATHB
- stz MATHA
- lda X1
- lsr A
- php
- tay
-
- clc
- lda VIEWPAGEL
- adc MATHH
- sta ptr1
- lda VIEWPAGEH
- adc MATHG
- sta ptr1+1
-
- ldx #0
- lda #15
- sta MAPCTL
- lda (ptr1),y
- tay
- lda #$0c
- sta MAPCTL
- tya
- plp
- bcc @L1
- and #$f
- rts
-
-@L1: lsr A
- lsr A
- lsr A
- lsr A
- 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
-;
-
-.data
-line_coll:
- .byte 0
-line_sprite:
- .byte 0 ; Will be replaced by the code
- .byte %00110000
- .byte %00100000
- .word 0,pixel_bitmap
-line_x:
- .word 0
-line_y:
- .word 0
-line_sx:
- .word $100
-line_sy:
- .word $100
- .word 0
-line_tilt:
- .word 0
-line_c:
- .byte $e
-
-.code
-LINE:
- lda DRAWINDEX
- sta line_c
- stz line_sx
- stz line_sy
-
- sec
- lda X2
- sbc X1
- lda X2+1
- sbc X1+1
- bpl @L1
- lda X1
- ldx X2
- sta X2
- stx X1
- lda X1+1
- ldx X2+1
- sta X2+1
- stx X1+1
- lda Y1
- ldx Y2
- sta Y2
- stx Y1
- lda Y1+1
- ldx Y2+1
- sta Y2+1
- stx Y1+1
-@L1:
- lda #%00000000 ; Not flipped
- sta line_sprite
-
- sec
- lda Y2
- sbc Y1
- sta Y2
- lda Y2+1
- sbc Y1+1
- sta Y2+1
- bpl @L2
- sec
- lda #0
- sbc Y2
- sta Y2
- lda #0
- sbc Y2+1
- sta Y2+1
- lda #%00010000 ; Vertical flip
- sta line_sprite
-@L2:
- lda X1
- sta line_x
- lda X1+1
- sta line_x+1
- lda Y1
- sta line_y
- lda Y1+1
- sta line_y+1
-
- lda Y2
- ina
- sta line_sy+1
- sta MATHP ; hardware divide
- stz MATHN
-
- stz MATHH
- stz MATHG
- sec
- lda X2
- sbc X1
- ina
- sta MATHF
- stz MATHE
-@L3:
- lda SPRSYS
- bmi @L3 ; wait for math done (bit 7 of sprsys)
- lda MATHC
- sta line_tilt
- lda MATHB
- sta line_tilt+1
- bne @L4
- lda #1
- sta line_sx+1
- bra @L6
-@L4:
- bit line_tilt
- bpl @L5
- ina
-@L5:
- sta line_sx+1
-@L6:
- lda #<line_sprite
- ldx #>line_sprite
- jmp draw_sprite
-
-; ------------------------------------------------------------------------
-; 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
-;
-
-.data
-bar_coll:
- .byte 0
-bar_sprite:
- .byte %00000001 ; A pixel sprite
- .byte %00010000
- .byte %00100000
- .addr 0,pixel_bitmap
-bar_x: .word 0
-bar_y: .word 0
-bar_sx: .word $0100
-bar_sy: .word $0100
-bar_c: .byte $00
-
-.code
-BAR: lda X1
- sta bar_x
- lda Y1
- sta bar_y
- lda X2
- sec
- sbc X1
- ina
- sta bar_sx+1
- lda Y2
- sec
- sbc Y1
- ina
- sta bar_sy+1
- lda DRAWINDEX
- sta bar_c
- lda #<bar_sprite
- ldx #>bar_sprite
- jmp draw_sprite
-
-; ------------------------------------------------------------------------
-; 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
- 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:
- lda TEXTMAGX ; Scale sprite
- sta text_sx+1
- lda TEXTMAGY
- sta text_sy+1
-
- stz text_sprite ; Set normal sprite
- lda BGINDEX
- bne @L1
- lda #4
- sta text_sprite ; Set opaque sprite
-@L1:
- lda DRAWINDEX ; Set color
- asl
- asl
- asl
- asl
- ora BGINDEX
- sta text_c
-
- lda X1 ; Set start position
- sta text_x
- lda X1+1
- sta text_x+1
- lda Y1
- sta text_y
- lda Y1+1
- sta text_y+1
-
- ldy #<-1 ; Calculate string length
-@L2:
- iny
- lda (STRPTR),y
- bne @L2
- cpy #20
- bmi @L3
- ldy #20
-@L3:
- sty STRLEN
- bne @L4
- rts ; Zero length string
-@L4:
- iny ; Prepare text_bitmap
- iny
- sty STROFF
-
- ldy #8-1 ; 8 pixel lines per character
- ldx #0
- clc
-@L5:
- lda STROFF
- sta text_bitmap,x
- txa
- adc STROFF
- tax
- lda #$ff
- sta text_bitmap-1,x
- dey
- bpl @L5
- stz text_bitmap,x
-
- stz tmp2
- iny
-@L6:
- lda (STRPTR),y
- sty tmp1
-
- sec ; (ch-' ') * 8
- sbc #32
- stz FONTOFF
- stz FONTOFF+1
- asl
- asl
- rol FONTOFF+1
- asl
- rol FONTOFF+1
- clc ; Choose font
- adc #<font
- sta FONTOFF
- lda FONTOFF+1
- adc #>font
- sta FONTOFF+1
-
-; and now copy the 8 bytes of that char
-
- ldx tmp2
- inx
- stx tmp2
-
-; draw char from top to bottom, reading char-data from offset 8-1 to offset 0
- ldy #8-1
-@L7:
- lda (FONTOFF),y ; *chptr
- sta text_bitmap,x ;textbuf[y*(1+len+1)+1+x]
-
- txa
- adc STROFF
- tax
-
- dey
- bpl @L7
-
- ; goto next char
- ldy tmp1
- iny
- dec STRLEN
- bne @L6
-
- lda #<text_sprite
- ldx #>text_sprite
- jmp draw_sprite
-
-.data
-text_coll:
- .byte 0
-text_sprite:
- .byte $00,$90,$20
- .addr 0, text_bitmap
-text_x:
- .word 0
-text_y:
- .word 0
-text_sx:
- .word $100
-text_sy:
- .word $100
-text_c:
- .byte 0
-
-.rodata
-; The Font
-; 96 characters from ASCII 32 to 127
-; 8 pixels wide, 8 pixels high
-; bit value 0 = foreground, bit value 1 = background / transparent
-font:
-; VERSAIL
- .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF ;32
- .byte $FF, $E7, $FF, $FF, $E7, $E7, $E7, $E7 ;33
- .byte $FF, $FF, $FF, $FF, $FF, $99, $99, $99 ;34
- .byte $FF, $99, $99, $00, $99, $00, $99, $99 ;35
- .byte $FF, $E7, $83, $F9, $C3, $9F, $C1, $E7 ;36
- .byte $FF, $B9, $99, $CF, $E7, $F3, $99, $9D ;37
- .byte $FF, $C0, $99, $98, $C7, $C3, $99, $C3 ;38
- .byte $FF, $FF, $FF, $FF, $FF, $E7, $F3, $F9 ;39
- .byte $FF, $F3, $E7, $CF, $CF, $CF, $E7, $F3 ;40
- .byte $FF, $CF, $E7, $F3, $F3, $F3, $E7, $CF ;41
- .byte $FF, $FF, $99, $C3, $00, $C3, $99, $FF ;42
- .byte $FF, $FF, $E7, $E7, $81, $E7, $E7, $FF ;43
- .byte $CF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;44
- .byte $FF, $FF, $FF, $FF, $81, $FF, $FF, $FF ;45
- .byte $FF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;46
- .byte $FF, $9F, $CF, $E7, $F3, $F9, $FC, $FF ;47
- .byte $FF, $C3, $99, $99, $89, $91, $99, $C3 ;48
- .byte $FF, $81, $E7, $E7, $E7, $C7, $E7, $E7 ;49
- .byte $FF, $81, $9F, $CF, $F3, $F9, $99, $C3 ;50
- .byte $FF, $C3, $99, $F9, $E3, $F9, $99, $C3 ;51
- .byte $FF, $F9, $F9, $80, $99, $E1, $F1, $F9 ;52
- .byte $FF, $C3, $99, $F9, $F9, $83, $9F, $81 ;53
- .byte $FF, $C3, $99, $99, $83, $9F, $99, $C3 ;54
- .byte $FF, $E7, $E7, $E7, $E7, $F3, $99, $81 ;55
- .byte $FF, $C3, $99, $99, $C3, $99, $99, $C3 ;56
- .byte $FF, $C3, $99, $F9, $C1, $99, $99, $C3 ;57
- .byte $FF, $FF, $E7, $FF, $FF, $E7, $FF, $FF ;58
- .byte $CF, $E7, $E7, $FF, $FF, $E7, $FF, $FF ;59
- .byte $FF, $F1, $E7, $CF, $9F, $CF, $E7, $F1 ;60
- .byte $FF, $FF, $FF, $81, $FF, $81, $FF, $FF ;61
- .byte $FF, $8F, $E7, $F3, $F9, $F3, $E7, $8F ;62
- .byte $FF, $E7, $FF, $E7, $F3, $F9, $99, $C3 ;63
-
-
- .byte $FF, $C3, $9D, $9F, $91, $91, $99, $C3 ;0
- .byte $FF, $99, $99, $99, $81, $99, $C3, $E7 ;1
- .byte $FF, $83, $99, $99, $83, $99, $99, $83 ;2
- .byte $FF, $C3, $99, $9F, $9F, $9F, $99, $C3 ;3
- .byte $FF, $87, $93, $99, $99, $99, $93, $87 ;4
- .byte $FF, $81, $9F, $9F, $87, $9F, $9F, $81 ;5
- .byte $FF, $9F, $9F, $9F, $87, $9F, $9F, $81 ;6
- .byte $FF, $C3, $99, $99, $91, $9F, $99, $C3 ;7
- .byte $FF, $99, $99, $99, $81, $99, $99, $99 ;8
- .byte $FF, $C3, $E7, $E7, $E7, $E7, $E7, $C3 ;9
- .byte $FF, $C7, $93, $F3, $F3, $F3, $F3, $E1 ;10
- .byte $FF, $99, $93, $87, $8F, $87, $93, $99 ;11
- .byte $FF, $81, $9F, $9F, $9F, $9F, $9F, $9F ;12
- .byte $FF, $9C, $9C, $9C, $94, $80, $88, $9C ;13
- .byte $FF, $99, $99, $91, $81, $81, $89, $99 ;14
- .byte $FF, $C3, $99, $99, $99, $99, $99, $C3 ;15
- .byte $FF, $9F, $9F, $9F, $83, $99, $99, $83 ;16
- .byte $FF, $F1, $C3, $99, $99, $99, $99, $C3 ;17
- .byte $FF, $99, $93, $87, $83, $99, $99, $83 ;18
- .byte $FF, $C3, $99, $F9, $C3, $9F, $99, $C3 ;19
- .byte $FF, $E7, $E7, $E7, $E7, $E7, $E7, $81 ;20
- .byte $FF, $C3, $99, $99, $99, $99, $99, $99 ;21
- .byte $FF, $E7, $C3, $99, $99, $99, $99, $99 ;22
- .byte $FF, $9C, $88, $80, $94, $9C, $9C, $9C ;23
- .byte $FF, $99, $99, $C3, $E7, $C3, $99, $99 ;24
- .byte $FF, $E7, $E7, $E7, $C3, $99, $99, $99 ;25
- .byte $FF, $81, $9F, $CF, $E7, $F3, $F9, $81 ;26
- .byte $FF, $C3, $CF, $CF, $CF, $CF, $CF, $C3 ;27
- .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3 ;28
- .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3 ;29
- .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF ;30
- .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF ;31
-
-
-; gemena
- .byte $FF, $C3, $9D, $9F, $91, $91, $99, $C3 ;224
- .byte $FF, $C1, $99, $C1, $F9, $C3, $FF, $FF ;225
- .byte $FF, $83, $99, $99, $83, $9F, $9F, $FF ;226
- .byte $FF, $C3, $9F, $9F, $9F, $C3, $FF, $FF ;227
- .byte $FF, $C1, $99, $99, $C1, $F9, $F9, $FF ;228
- .byte $FF, $C3, $9F, $81, $99, $C3, $FF, $FF ;229
- .byte $FF, $E7, $E7, $E7, $C1, $E7, $F1, $FF ;230
- .byte $83, $F9, $C1, $99, $99, $C1, $FF, $FF ;231
- .byte $FF, $99, $99, $99, $83, $9F, $9F, $FF ;232
- .byte $FF, $C3, $E7, $E7, $C7, $FF, $E7, $FF ;233
- .byte $C3, $F9, $F9, $F9, $F9, $FF, $F9, $FF ;234
- .byte $FF, $99, $93, $87, $93, $9F, $9F, $FF ;235
- .byte $FF, $C3, $E7, $E7, $E7, $E7, $C7, $FF ;236
- .byte $FF, $9C, $94, $80, $80, $99, $FF, $FF ;237
- .byte $FF, $99, $99, $99, $99, $83, $FF, $FF ;238
- .byte $FF, $C3, $99, $99, $99, $C3, $FF, $FF ;239
- .byte $9F, $9F, $83, $99, $99, $83, $FF, $FF ;240
- .byte $F9, $F9, $C1, $99, $99, $C1, $FF, $FF ;241
- .byte $FF, $9F, $9F, $9F, $99, $83, $FF, $FF ;242
- .byte $FF, $83, $F9, $C3, $9F, $C1, $FF, $FF ;243
- .byte $FF, $F1, $E7, $E7, $E7, $81, $E7, $FF ;244
- .byte $FF, $C1, $99, $99, $99, $99, $FF, $FF ;245
- .byte $FF, $E7, $C3, $99, $99, $99, $FF, $FF ;246
- .byte $FF, $C9, $C1, $80, $94, $9C, $FF, $FF ;247
- .byte $FF, $99, $C3, $E7, $C3, $99, $FF, $FF ;248
- .byte $87, $F3, $C1, $99, $99, $99, $FF, $FF ;249
- .byte $FF, $81, $CF, $E7, $F3, $81, $FF, $FF ;250
- .byte $FF, $C3, $CF, $CF, $CF, $CF, $CF, $C3 ;251
- .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3 ;252
- .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3 ;253
- .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF ;254
- .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF ;255
+++ /dev/null
-;
-; Serial driver for the Atari Lynx ComLynx port.
-;
-; Karri Kaksonen, 17.09.2009
-;
-
- .include "lynx.inc"
- .include "zeropage.inc"
- .include "ser-kernel.inc"
- .include "ser-error.inc"
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
- .segment "JUMPTABLE"
-
- ; Driver signature
- .byte $73, $65, $72 ; "ser"
- .byte SER_API_VERSION ; Serial API version number
-
- ; Jump table.
- .addr INSTALL
- .addr UNINSTALL
- .addr OPEN
- .addr CLOSE
- .addr GET
- .addr PUT
- .addr STATUS
- .addr IOCTL
- .addr IRQ
-
-;----------------------------------------------------------------------------
-; Global variables
-;
-
- .bss
-
-TxBuffer: .res 256
-RxBuffer: .res 256
-RxPtrIn: .res 1
-RxPtrOut: .res 1
-TxPtrIn: .res 1
-TxPtrOut: .res 1
-contrl: .res 1
-SerialStat: .res 1
-TxDone: .res 1
-
- .code
-
-;----------------------------------------------------------------------------
-; INSTALL: Is called after the driver is loaded into memory.
-;
-; Must return an SER_ERR_xx code in a/x.
-
-INSTALL:
- ; Set up IRQ vector ?
-
-;----------------------------------------------------------------------------
-; UNINSTALL: Is called before the driver is removed from memory.
-; No return code required (the driver is removed from memory on return).
-;
-
-UNINSTALL:
-
-;----------------------------------------------------------------------------
-; CLOSE: Close the port and disable interrupts. Called without parameters.
-; Must return an SER_ERR_xx code in a/x.
-
-CLOSE:
- ; Disable interrupts
- ; Done, return an error code
- lda #<SER_ERR_OK
- ldx #>SER_ERR_OK
- rts
-
-;----------------------------------------------------------------------------
-; OPEN: A pointer to a ser_params structure is passed in ptr1.
-;
-; The Lynx has only two correct serial data formats:
-; 8 bits, parity mark, 1 stop bit
-; 8 bits, parity space, 1 stop bit
-;
-; It also has two wrong formats;
-; 8 bits, even parity, 1 stop bit
-; 8 bits, odd parity, 1 stop bit
-;
-; Unfortunately the parity bit includes itself in the calculation making
-; parity not compatible with the rest of the world.
-;
-; We can only specify a few baud rates.
-; Lynx has two non-standard speeds 31250 and 62500 which are
-; frequently used in games.
-;
-; The receiver will always read the parity and report parity errors.
-;
-; Must return an SER_ERR_xx code in a/x.
-
-OPEN:
- stz RxPtrIn
- stz RxPtrOut
- stz TxPtrIn
- stz TxPtrOut
-
- ; clock = 8 * 15625
- lda #%00011000
- sta TIM4CTLA
- ldy #SER_PARAMS::BAUDRATE
- lda (ptr1),y
-
- ldx #1
- cmp #SER_BAUD_62500
- beq setbaudrate
-
- ldx #2
- cmp #SER_BAUD_31250
- beq setbaudrate
-
- ldx #12
- cmp #SER_BAUD_9600
- beq setbaudrate
-
- ldx #25
- cmp #SER_BAUD_4800
- beq setbaudrate
-
- ldx #51
- cmp #SER_BAUD_2400
- beq setbaudrate
-
- ldx #103
- cmp #SER_BAUD_1200
- beq setbaudrate
-
- ldx #207
- cmp #SER_BAUD_600
- beq setbaudrate
-
- ; clock = 6 * 15625
- ldx #%00011010
- stx TIM4CTLA
-
- ldx #12
- cmp #SER_BAUD_7200
- beq setbaudrate
-
- ldx #25
- cmp #SER_BAUD_3600
- beq setbaudrate
-
- ldx #207
- stx TIM4BKUP
-
- ; clock = 4 * 15625
- ldx #%00011100
- cmp #SER_BAUD_300
- beq setprescaler
-
- ; clock = 6 * 15625
- ldx #%00011110
- cmp #SER_BAUD_150
- beq setprescaler
-
- ; clock = 1 * 15625
- ldx #%00011111
- stx TIM4CTLA
- cmp #SER_BAUD_75
- beq baudsuccess
-
- ldx #141
- cmp #SER_BAUD_110
- beq setbaudrate
-
- ; clock = 2 * 15625
- ldx #%00011010
- stx TIM4CTLA
- ldx #68
- cmp #SER_BAUD_1800
- beq setbaudrate
-
- ; clock = 6 * 15625
- ldx #%00011110
- stx TIM4CTLA
- ldx #231
- cmp #SER_BAUD_134_5
- beq setbaudrate
-
- lda #<SER_ERR_BAUD_UNAVAIL
- ldx #>SER_ERR_BAUD_UNAVAIL
- rts
-setprescaler:
- stx TIM4CTLA
- bra baudsuccess
-setbaudrate:
- stx TIM4BKUP
-baudsuccess:
- ldx #TxOpenColl|ParEven
- stx contrl
- ldy #SER_PARAMS::DATABITS ; Databits
- lda (ptr1),y
- cmp #SER_BITS_8
- bne invparameter
- ldy #SER_PARAMS::STOPBITS ; Stopbits
- lda (ptr1),y
- cmp #SER_STOP_1
- bne invparameter
- ldy #SER_PARAMS::PARITY ; Parity
- lda (ptr1),y
- cmp #SER_PAR_NONE
- beq invparameter
- cmp #SER_PAR_MARK
- beq checkhs
- cmp #SER_PAR_SPACE
- bne @L0
- ldx #TxOpenColl
- stx contrl
- bra checkhs
-@L0:
- ldx #TxParEnable|TxOpenColl|ParEven
- stx contrl
- cmp #SER_PAR_EVEN
- beq checkhs
- ldx #TxParEnable|TxOpenColl
- stx contrl
-checkhs:
- ldx contrl
- stx SERCTL
- ldy #SER_PARAMS::HANDSHAKE ; Handshake
- lda (ptr1),y
- cmp #SER_HS_NONE
- bne invparameter
- lda SERDAT
- lda contrl
- ora #RxIntEnable|ResetErr
- sta SERCTL
- lda #<SER_ERR_OK
- ldx #>SER_ERR_OK
- rts
-invparameter:
- lda #<SER_ERR_INIT_FAILED
- ldx #>SER_ERR_INIT_FAILED
- rts
-
-;----------------------------------------------------------------------------
-; GET: Will fetch a character from the receive buffer and store it into the
-; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
-; returned.
-
-GET:
- lda RxPtrIn
- cmp RxPtrOut
- bne GetByte
- lda #<SER_ERR_NO_DATA
- ldx #>SER_ERR_NO_DATA
- rts
-GetByte:
- ldy RxPtrOut
- lda RxBuffer,y
- inc RxPtrOut
- ldx #$00
- sta (ptr1,x)
- txa ; Return code = 0
- rts
-
-;----------------------------------------------------------------------------
-; PUT: Output character in A.
-; Must return an SER_ERR_xx code in a/x.
-
-PUT:
- tax
- lda TxPtrIn
- ina
- cmp TxPtrOut
- bne PutByte
- lda #<SER_ERR_OVERFLOW
- ldx #>SER_ERR_OVERFLOW
- rts
-PutByte:
- ldy TxPtrIn
- txa
- sta TxBuffer,y
- inc TxPtrIn
-
- bit TxDone
- bmi @L1
- php
- sei
- lda contrl
- ora #TxIntEnable|ResetErr
- sta SERCTL ; Allow TX-IRQ to hang RX-IRQ
- sta TxDone
- plp
-@L1:
- lda #<SER_ERR_OK
- tax
- rts
-
-;----------------------------------------------------------------------------
-; STATUS: Return the status in the variable pointed to by ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-STATUS:
- ldy SerialStat
- ldx #$00
- sta (ptr1,x)
- txa ; Return code = 0
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an SER_ERR_xx code in a/x.
-
-IOCTL:
- lda #<SER_ERR_INV_IOCTL
- ldx #>SER_ERR_INV_IOCTL
- rts
-
-;----------------------------------------------------------------------------
-; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
-; registers are already saved, no parameters are passed, but the carry flag
-; is clear on entry. The routine must return with carry set if the interrupt
-; was handled, otherwise with carry clear.
-;
-; Both the Tx and Rx interrupts are level sensitive instead of edge sensitive.
-; Due to this bug you have to disable the interrupt before clearing it.
-
-IRQ:
- lda INTSET ; Poll all pending interrupts
- and #SERIAL_INTERRUPT
- bne @L0
- clc
- rts
-@L0:
- bit TxDone
- bmi @tx_irq ; Transmit in progress
- ldx SERDAT
- lda SERCTL
- and #RxParityErr|RxOverrun|RxFrameErr|RxBreak
- beq @rx_irq
- tsb SerialStat ; Save error condition
- bit #RxBreak
- beq @noBreak
- stz TxPtrIn ; Break received - drop buffers
- stz TxPtrOut
- stz RxPtrIn
- stz RxPtrOut
-@noBreak:
- lda contrl
- ora #RxIntEnable|ResetErr
- sta SERCTL
- lda #$10
- sta INTRST
- bra @IRQexit
-@rx_irq:
- lda contrl
- ora #RxIntEnable|ResetErr
- sta SERCTL
- txa
- ldx RxPtrIn
- sta RxBuffer,x
- txa
- inx
-
-@cont0:
- cpx RxPtrOut
- beq @1
- stx RxPtrIn
- lda #SERIAL_INTERRUPT
- sta INTRST
- bra @IRQexit
-
-@1:
- sta RxPtrIn
- lda #$80
- tsb SerialStat
-@tx_irq:
- ldx TxPtrOut ; Has all bytes been sent?
- cpx TxPtrIn
- beq @allSent
-
- lda TxBuffer,x ; Send next byte
- sta SERDAT
- inc TxPtrOut
-
-@exit1:
- lda contrl
- ora #TxIntEnable|ResetErr
- sta SERCTL
- lda #SERIAL_INTERRUPT
- sta INTRST
- bra @IRQexit
-
-@allSent:
- lda SERCTL ; All bytes sent
- bit #TxEmpty
- beq @exit1
- bvs @exit1
- stz TxDone
- lda contrl
- ora #RxIntEnable|ResetErr
- sta SERCTL
-
- lda #SERIAL_INTERRUPT
- sta INTRST
-@IRQexit:
- clc
- rts
-
+++ /dev/null
-;
-; Standard joystick driver for the Atari Lynx.
-; The Lynx has two fire buttons. So it is not quite "standard".
-;
-; Modified by Karri Kaksonen, 2004-09-16
-; Ullrich von Bassewitz, 2002-12-20
-; Using code from Steve Schmidtke
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "lynx.inc"
- .include "extzp.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
-joy_mask:
- .byte $80 ; JOY_UP
- .byte $40 ; JOY_DOWN
- .byte $20 ; JOY_LEFT
- .byte $10 ; JOY_RIGHT
- .byte $01 ; JOY_FIRE
- .byte $02 ; JOY_FIRE1
- .byte $00 ;
- .byte $00 ;
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 1 ; Number of joysticks we support
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-
-READ:
- ldx #$00 ; Clear high byte
- lda JOYSTICK ; Read joystick
- and #$F3 ; Mask relevant keys
- rts
-
-
--- /dev/null
+;
+; Serial driver for the Atari Lynx ComLynx port.
+;
+; Karri Kaksonen, 17.09.2009
+;
+
+ .include "lynx.inc"
+ .include "zeropage.inc"
+ .include "ser-kernel.inc"
+ .include "ser-error.inc"
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ .segment "JUMPTABLE"
+
+ ; Driver signature
+ .byte $73, $65, $72 ; "ser"
+ .byte SER_API_VERSION ; Serial API version number
+
+ ; Jump table.
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr OPEN
+ .addr CLOSE
+ .addr GET
+ .addr PUT
+ .addr STATUS
+ .addr IOCTL
+ .addr IRQ
+
+;----------------------------------------------------------------------------
+; Global variables
+;
+
+ .bss
+
+TxBuffer: .res 256
+RxBuffer: .res 256
+RxPtrIn: .res 1
+RxPtrOut: .res 1
+TxPtrIn: .res 1
+TxPtrOut: .res 1
+contrl: .res 1
+SerialStat: .res 1
+TxDone: .res 1
+
+ .code
+
+;----------------------------------------------------------------------------
+; INSTALL: Is called after the driver is loaded into memory.
+;
+; Must return an SER_ERR_xx code in a/x.
+
+INSTALL:
+ ; Set up IRQ vector ?
+
+;----------------------------------------------------------------------------
+; UNINSTALL: Is called before the driver is removed from memory.
+; No return code required (the driver is removed from memory on return).
+;
+
+UNINSTALL:
+
+;----------------------------------------------------------------------------
+; CLOSE: Close the port and disable interrupts. Called without parameters.
+; Must return an SER_ERR_xx code in a/x.
+
+CLOSE:
+ ; Disable interrupts
+ ; Done, return an error code
+ lda #<SER_ERR_OK
+ ldx #>SER_ERR_OK
+ rts
+
+;----------------------------------------------------------------------------
+; OPEN: A pointer to a ser_params structure is passed in ptr1.
+;
+; The Lynx has only two correct serial data formats:
+; 8 bits, parity mark, 1 stop bit
+; 8 bits, parity space, 1 stop bit
+;
+; It also has two wrong formats;
+; 8 bits, even parity, 1 stop bit
+; 8 bits, odd parity, 1 stop bit
+;
+; Unfortunately the parity bit includes itself in the calculation making
+; parity not compatible with the rest of the world.
+;
+; We can only specify a few baud rates.
+; Lynx has two non-standard speeds 31250 and 62500 which are
+; frequently used in games.
+;
+; The receiver will always read the parity and report parity errors.
+;
+; Must return an SER_ERR_xx code in a/x.
+
+OPEN:
+ stz RxPtrIn
+ stz RxPtrOut
+ stz TxPtrIn
+ stz TxPtrOut
+
+ ; clock = 8 * 15625
+ lda #%00011000
+ sta TIM4CTLA
+ ldy #SER_PARAMS::BAUDRATE
+ lda (ptr1),y
+
+ ldx #1
+ cmp #SER_BAUD_62500
+ beq setbaudrate
+
+ ldx #2
+ cmp #SER_BAUD_31250
+ beq setbaudrate
+
+ ldx #12
+ cmp #SER_BAUD_9600
+ beq setbaudrate
+
+ ldx #25
+ cmp #SER_BAUD_4800
+ beq setbaudrate
+
+ ldx #51
+ cmp #SER_BAUD_2400
+ beq setbaudrate
+
+ ldx #103
+ cmp #SER_BAUD_1200
+ beq setbaudrate
+
+ ldx #207
+ cmp #SER_BAUD_600
+ beq setbaudrate
+
+ ; clock = 6 * 15625
+ ldx #%00011010
+ stx TIM4CTLA
+
+ ldx #12
+ cmp #SER_BAUD_7200
+ beq setbaudrate
+
+ ldx #25
+ cmp #SER_BAUD_3600
+ beq setbaudrate
+
+ ldx #207
+ stx TIM4BKUP
+
+ ; clock = 4 * 15625
+ ldx #%00011100
+ cmp #SER_BAUD_300
+ beq setprescaler
+
+ ; clock = 6 * 15625
+ ldx #%00011110
+ cmp #SER_BAUD_150
+ beq setprescaler
+
+ ; clock = 1 * 15625
+ ldx #%00011111
+ stx TIM4CTLA
+ cmp #SER_BAUD_75
+ beq baudsuccess
+
+ ldx #141
+ cmp #SER_BAUD_110
+ beq setbaudrate
+
+ ; clock = 2 * 15625
+ ldx #%00011010
+ stx TIM4CTLA
+ ldx #68
+ cmp #SER_BAUD_1800
+ beq setbaudrate
+
+ ; clock = 6 * 15625
+ ldx #%00011110
+ stx TIM4CTLA
+ ldx #231
+ cmp #SER_BAUD_134_5
+ beq setbaudrate
+
+ lda #<SER_ERR_BAUD_UNAVAIL
+ ldx #>SER_ERR_BAUD_UNAVAIL
+ rts
+setprescaler:
+ stx TIM4CTLA
+ bra baudsuccess
+setbaudrate:
+ stx TIM4BKUP
+baudsuccess:
+ ldx #TxOpenColl|ParEven
+ stx contrl
+ ldy #SER_PARAMS::DATABITS ; Databits
+ lda (ptr1),y
+ cmp #SER_BITS_8
+ bne invparameter
+ ldy #SER_PARAMS::STOPBITS ; Stopbits
+ lda (ptr1),y
+ cmp #SER_STOP_1
+ bne invparameter
+ ldy #SER_PARAMS::PARITY ; Parity
+ lda (ptr1),y
+ cmp #SER_PAR_NONE
+ beq invparameter
+ cmp #SER_PAR_MARK
+ beq checkhs
+ cmp #SER_PAR_SPACE
+ bne @L0
+ ldx #TxOpenColl
+ stx contrl
+ bra checkhs
+@L0:
+ ldx #TxParEnable|TxOpenColl|ParEven
+ stx contrl
+ cmp #SER_PAR_EVEN
+ beq checkhs
+ ldx #TxParEnable|TxOpenColl
+ stx contrl
+checkhs:
+ ldx contrl
+ stx SERCTL
+ ldy #SER_PARAMS::HANDSHAKE ; Handshake
+ lda (ptr1),y
+ cmp #SER_HS_NONE
+ bne invparameter
+ lda SERDAT
+ lda contrl
+ ora #RxIntEnable|ResetErr
+ sta SERCTL
+ lda #<SER_ERR_OK
+ ldx #>SER_ERR_OK
+ rts
+invparameter:
+ lda #<SER_ERR_INIT_FAILED
+ ldx #>SER_ERR_INIT_FAILED
+ rts
+
+;----------------------------------------------------------------------------
+; GET: Will fetch a character from the receive buffer and store it into the
+; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; returned.
+
+GET:
+ lda RxPtrIn
+ cmp RxPtrOut
+ bne GetByte
+ lda #<SER_ERR_NO_DATA
+ ldx #>SER_ERR_NO_DATA
+ rts
+GetByte:
+ ldy RxPtrOut
+ lda RxBuffer,y
+ inc RxPtrOut
+ ldx #$00
+ sta (ptr1,x)
+ txa ; Return code = 0
+ rts
+
+;----------------------------------------------------------------------------
+; PUT: Output character in A.
+; Must return an SER_ERR_xx code in a/x.
+
+PUT:
+ tax
+ lda TxPtrIn
+ ina
+ cmp TxPtrOut
+ bne PutByte
+ lda #<SER_ERR_OVERFLOW
+ ldx #>SER_ERR_OVERFLOW
+ rts
+PutByte:
+ ldy TxPtrIn
+ txa
+ sta TxBuffer,y
+ inc TxPtrIn
+
+ bit TxDone
+ bmi @L1
+ php
+ sei
+ lda contrl
+ ora #TxIntEnable|ResetErr
+ sta SERCTL ; Allow TX-IRQ to hang RX-IRQ
+ sta TxDone
+ plp
+@L1:
+ lda #<SER_ERR_OK
+ tax
+ rts
+
+;----------------------------------------------------------------------------
+; STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+STATUS:
+ ldy SerialStat
+ ldx #$00
+ sta (ptr1,x)
+ txa ; Return code = 0
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an SER_ERR_xx code in a/x.
+
+IOCTL:
+ lda #<SER_ERR_INV_IOCTL
+ ldx #>SER_ERR_INV_IOCTL
+ rts
+
+;----------------------------------------------------------------------------
+; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
+; registers are already saved, no parameters are passed, but the carry flag
+; is clear on entry. The routine must return with carry set if the interrupt
+; was handled, otherwise with carry clear.
+;
+; Both the Tx and Rx interrupts are level sensitive instead of edge sensitive.
+; Due to this bug you have to disable the interrupt before clearing it.
+
+IRQ:
+ lda INTSET ; Poll all pending interrupts
+ and #SERIAL_INTERRUPT
+ bne @L0
+ clc
+ rts
+@L0:
+ bit TxDone
+ bmi @tx_irq ; Transmit in progress
+ ldx SERDAT
+ lda SERCTL
+ and #RxParityErr|RxOverrun|RxFrameErr|RxBreak
+ beq @rx_irq
+ tsb SerialStat ; Save error condition
+ bit #RxBreak
+ beq @noBreak
+ stz TxPtrIn ; Break received - drop buffers
+ stz TxPtrOut
+ stz RxPtrIn
+ stz RxPtrOut
+@noBreak:
+ lda contrl
+ ora #RxIntEnable|ResetErr
+ sta SERCTL
+ lda #$10
+ sta INTRST
+ bra @IRQexit
+@rx_irq:
+ lda contrl
+ ora #RxIntEnable|ResetErr
+ sta SERCTL
+ txa
+ ldx RxPtrIn
+ sta RxBuffer,x
+ txa
+ inx
+
+@cont0:
+ cpx RxPtrOut
+ beq @1
+ stx RxPtrIn
+ lda #SERIAL_INTERRUPT
+ sta INTRST
+ bra @IRQexit
+
+@1:
+ sta RxPtrIn
+ lda #$80
+ tsb SerialStat
+@tx_irq:
+ ldx TxPtrOut ; Has all bytes been sent?
+ cpx TxPtrIn
+ beq @allSent
+
+ lda TxBuffer,x ; Send next byte
+ sta SERDAT
+ inc TxPtrOut
+
+@exit1:
+ lda contrl
+ ora #TxIntEnable|ResetErr
+ sta SERCTL
+ lda #SERIAL_INTERRUPT
+ sta INTRST
+ bra @IRQexit
+
+@allSent:
+ lda SERCTL ; All bytes sent
+ bit #TxEmpty
+ beq @exit1
+ bvs @exit1
+ stz TxDone
+ lda contrl
+ ora #RxIntEnable|ResetErr
+ sta SERCTL
+
+ lda #SERIAL_INTERRUPT
+ sta INTRST
+@IRQexit:
+ clc
+ rts
+
--- /dev/null
+;
+; Graphics driver for the 160x102x16 mode on the Lynx.
+;
+; All the drawing functions are simply done by sprites as the sprite
+; engine is the only way to do fast graphics on a Lynx.
+;
+; This code is written by Karri Kaksonen, 2004 for the cc65 compiler.
+;
+
+ .include "zeropage.inc"
+ .include "../extzp.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+
+ .include "lynx.inc"
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; 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
+ .word 160 ; X resolution
+ .word 102 ; Y resolution
+ .byte 16 ; Number of drawing colors
+ .byte 2 ; Number of screens available
+ .byte 8 ; System font X size
+ .byte 8 ; System font Y size
+ .word $0100 ; Aspect ratio (square pixel LCD)
+ .byte TGI_BM_FONT_FINESCALE ; TGI driver flags
+
+; Next comes the jump table. Currently all entries must be valid and may point
+; to an RTS for test versions (function not implemented). A future version may
+; allow for emulation: In this case the vector will be zero. Emulation means
+; that the graphics kernel will emulate the function by using lower level
+; primitives - for example ploting a line by using calls to SETPIXEL.
+
+ .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 TEXTSTYLE
+ .addr OUTTEXT
+ .addr IRQ
+
+
+; ------------------------------------------------------------------------
+; 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
+
+STRPTR := ptr3
+FONTOFF := ptr4
+STROFF := tmp3
+STRLEN := tmp4
+
+; Absolute variables used in the code
+
+.bss
+
+ERROR: .res 1 ; Error code
+
+DRAWINDEX: .res 1 ; Pen to use for drawing
+VIEWPAGEL: .res 1
+VIEWPAGEH: .res 1
+DRAWPAGEL: .res 1
+DRAWPAGEH: .res 1
+
+; Text output stuff
+TEXTMAGX: .res 1
+TEXTMAGY: .res 1
+TEXTDIR: .res 1
+BGINDEX: .res 1 ; Pen to use for text background
+
+; Double buffer IRQ stuff
+DRAWPAGE: .res 1
+SWAPREQUEST: .res 1
+
+text_bitmap: .res 8*(1+20+1)+1
+; 8 rows with (one offset-byte plus 20 character bytes plus one fill-byte) plus one 0-offset-byte
+
+; Constants and tables
+
+.rodata
+
+DEFPALETTE: .byte >$011
+ .byte >$34d
+ .byte >$9af
+ .byte >$9b8
+ .byte >$777
+ .byte >$335
+ .byte >$448
+ .byte >$75e
+ .byte >$d5f
+ .byte >$c53
+ .byte >$822
+ .byte >$223
+ .byte >$484
+ .byte >$8e5
+ .byte >$cf5
+ .byte >$fff
+ .byte <$011
+ .byte <$34d
+ .byte <$9af
+ .byte <$9b8
+ .byte <$777
+ .byte <$335
+ .byte <$448
+ .byte <$75e
+ .byte <$d5f
+ .byte <$c53
+ .byte <$822
+ .byte <$223
+ .byte <$484
+ .byte <$8e5
+ .byte <$cf5
+ .byte <$fff
+
+PALETTESIZE = * - DEFPALETTE
+
+.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:
+ lda #1
+ sta TEXTMAGX
+ sta TEXTMAGY
+ stz BGINDEX
+ stz DRAWPAGE
+ stz SWAPREQUEST
+ rts
+
+
+; ------------------------------------------------------------------------
+; 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:
+; Enable interrupts for VBL
+ lda #$80
+ tsb VTIMCTLA
+; Set up collision buffer to $A058
+ lda #$58
+ sta COLLBASL
+ lda #$A0
+ sta COLLBASH
+; Put collision index before sprite data
+ lda #$FF
+ sta COLLOFFL
+ lda #$FF
+ sta COLLOFFH
+; 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:
+ rts
+
+; ------------------------------------------------------------------------
+; 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
+;
+; The TGI lacks a way to draw sprites. As that functionality is vital to
+; Lynx games we borrow this CONTROL function to implement the still
+; missing tgi_draw_sprite funtion. To use this in your C-program
+; do a #define tgi_draw_sprite(spr) tgi_ioctl(0, spr)
+;
+; To do a flip-screen call tgi_ioctl(1, 0)
+;
+; To set the background index for text outputs call tgi_ioctl(2, bgindex)
+;
+; To set the frame rate for the display hardware call tgi_ioctl(3, rate)
+;
+; To check if the drawing engine is busy with the previous swap you can
+; call tgi_ioctl(4, 0). It returns 0 if idle and 1 if busy
+;
+; To update displays you can call tgi_ioctl(4, 1) it will wait for the
+; next VBL interrupt and swap draw and view buffers.
+;
+; Activate or deactivate collision detection by calling tgi_ioctl(5, 0/1).
+
+CONTROL:
+ pha ; Almost all control routines succeed
+ lda #TGI_ERR_OK
+ sta ERROR
+ pla
+
+ cmp #5
+ bne ControlSwap
+ lda ptr1 ; Activate/deactivate collision detection
+ bne @L0
+ lda #%00000001 ; tgi_clear does not erase collision buffer
+ sta cls_sprite
+ lda #%00100000
+ sta cls_sprite+2
+ lda __sprsys
+ ora #$20
+ bra @L1
+@L0: lda #%00000000 ; tgi_clear erases collision buffer
+ sta cls_sprite
+ sta cls_sprite+2
+ lda __sprsys
+ and #$df
+@L1: sta __sprsys
+ sta SPRSYS
+ rts
+
+ControlSwap:
+ cmp #4
+ bne ControlFramerate
+
+ lda ptr1 ; Swap request
+ bne @L0
+ lda SWAPREQUEST
+ rts
+@L0: sta SWAPREQUEST
+ rts
+
+ControlFramerate:
+ cmp #3
+ bne ControlTextBG
+
+ lda ptr1
+ cmp #75 ; Set framerate
+ beq rate75
+ cmp #60
+ beq rate60
+ cmp #50
+ beq rate50
+ lda #TGI_ERR_INV_ARG
+ sta ERROR
+ rts
+rate50: lda #$bd ; 50 Hz
+ ldx #$31
+ bra setRate
+rate60: lda #$9e ; 60 Hz
+ ldx #$29
+ bra setRate
+rate75: lda #$7e ; 75 Hz
+ ldx #$20
+setRate:
+ sta HTIMBKUP
+ stx PBKUP
+ rts
+
+ControlTextBG:
+ cmp #2
+ bne ControlFlipScreen
+
+ lda ptr1 ; Set text background color
+ sta BGINDEX
+ rts
+
+ControlFlipScreen:
+ cmp #1
+ bne ControlDrawSprite
+
+ lda __sprsys ; Flip screen
+ eor #8
+ sta __sprsys
+ sta SPRSYS
+ lda __viddma
+ eor #2
+ sta __viddma
+ sta DISPCTL
+ ldy VIEWPAGEL
+ ldx VIEWPAGEH
+ and #2
+ beq NotFlipped
+ clc
+ tya
+ adc #<8159
+ tay
+ txa
+ adc #>8159
+ tax
+NotFlipped:
+ sty DISPADRL
+ stx DISPADRH
+ rts
+
+ControlDrawSprite:
+ lda ptr1 ; Get the sprite address
+ ldx ptr1+1
+
+draw_sprite: ; Draw it in render buffer
+ sta SCBNEXTL
+ stx SCBNEXTH
+ lda DRAWPAGEL
+ ldx DRAWPAGEH
+ sta VIDBASL
+ stx VIDBASH
+ lda #1
+ sta SPRGO
+ stz SDONEACK
+@L0: stz CPUSLEEP
+ lda SPRSYS
+ lsr
+ bcs @L0
+ stz SDONEACK
+ lda #TGI_ERR_OK
+ sta ERROR
+ rts
+
+; ------------------------------------------------------------------------
+; CLEAR: Clears the screen.
+;
+; Must set an error code: NO
+;
+
+.rodata
+pixel_bitmap:
+ .byte 3,%10000100,%00000000, $0 ; A pixel bitmap
+.data
+cls_coll:
+ .byte 0
+cls_sprite:
+ .byte %00000001 ; A pixel sprite
+ .byte %00010000
+ .byte %00100000
+ .addr 0,pixel_bitmap
+ .word 0
+ .word 0
+ .word $a000 ; 160
+ .word $6600 ; 102
+ .byte $00
+
+.code
+CLEAR: lda #<cls_sprite
+ ldx #>cls_sprite
+ bra draw_sprite
+
+; ------------------------------------------------------------------------
+; 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)
+;
+; It is a good idea to call this function during the vertical blanking
+; period. If you call it in the middle of the screen update then half of
+; the drawn frame will be from the old buffer and the other half is
+; from the new buffer. This is usually noticed by the user.
+
+SETVIEWPAGE:
+ cmp #1
+ beq @L1 ; page == maxpages-1
+ ldy #<$e018 ; page 0
+ ldx #>$e018
+ bra @L2
+@L1:
+ ldy #<$c038 ; page 1
+ ldx #>$c038
+@L2:
+ sty VIEWPAGEL ; Save viewpage for getpixel
+ stx VIEWPAGEH
+
+ lda __viddma ; Process flipped displays
+ and #2
+ beq @L3
+ clc
+ tya
+ adc #<8159
+ tay
+ txa
+ adc #>8159
+ tax
+@L3:
+ sty DISPADRL ; $FD94
+ stx DISPADRH ; $FD95
+ 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:
+ cmp #1
+ beq @L1 ; page == maxpages-1
+ lda #<$e018 ; page 0
+ ldx #>$e018
+ bra @L2
+@L1:
+ lda #<$c038 ; page 1
+ ldx #>$c038
+@L2:
+ sta DRAWPAGEL
+ stx DRAWPAGEH
+ rts
+
+; ------------------------------------------------------------------------
+; IRQ: VBL interrupt handler
+;
+
+IRQ:
+ lda INTSET ; Poll all pending interrupts
+ and #VBL_INTERRUPT
+ beq IRQEND ; Exit if not a VBL interrupt
+
+ lda SWAPREQUEST
+ beq @L0
+ lda DRAWPAGE
+ jsr SETVIEWPAGE
+ lda DRAWPAGE
+ eor #1
+ sta DRAWPAGE
+ jsr SETDRAWPAGE
+ stz SWAPREQUEST
+@L0:
+IRQEND:
+ clc
+ 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:
+ sta DRAWINDEX
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ ldy #31
+@L1: lda (ptr1),y
+ sta GCOLMAP,y ; $FDA0
+ dey
+ bpl @L1
+
+; Done, reset the error code
+
+ lda #TGI_ERR_OK
+ 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:
+ lda #<GCOLMAP ; $FDA0
+ ldx #>GCOLMAP
+ rts
+
+; ------------------------------------------------------------------------
+; 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
+;
+
+.data
+pixel_coll:
+ .byte 0
+pixel_sprite:
+ .byte %00000001 ; A pixel sprite
+ .byte %00010000
+ .byte %00100000
+ .addr 0,pixel_bitmap
+pix_x: .word 0
+pix_y: .word 0
+ .word $100
+ .word $100
+pix_c: .byte $00
+
+.code
+SETPIXEL:
+ lda X1
+ sta pix_x
+ lda Y1
+ sta pix_y
+ lda DRAWINDEX
+ sta pix_c
+ lda #<pixel_sprite
+ ldx #>pixel_sprite
+ jmp draw_sprite
+
+; ------------------------------------------------------------------------
+; 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 Y1
+ sta MATHD ; Hardware multiply
+ stz MATHC
+ lda #80
+ sta MATHB
+ stz MATHA
+ lda X1
+ lsr A
+ php
+ tay
+
+ clc
+ lda VIEWPAGEL
+ adc MATHH
+ sta ptr1
+ lda VIEWPAGEH
+ adc MATHG
+ sta ptr1+1
+
+ ldx #0
+ lda #15
+ sta MAPCTL
+ lda (ptr1),y
+ tay
+ lda #$0c
+ sta MAPCTL
+ tya
+ plp
+ bcc @L1
+ and #$f
+ rts
+
+@L1: lsr A
+ lsr A
+ lsr A
+ lsr A
+ 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
+;
+
+.data
+line_coll:
+ .byte 0
+line_sprite:
+ .byte 0 ; Will be replaced by the code
+ .byte %00110000
+ .byte %00100000
+ .word 0,pixel_bitmap
+line_x:
+ .word 0
+line_y:
+ .word 0
+line_sx:
+ .word $100
+line_sy:
+ .word $100
+ .word 0
+line_tilt:
+ .word 0
+line_c:
+ .byte $e
+
+.code
+LINE:
+ lda DRAWINDEX
+ sta line_c
+ stz line_sx
+ stz line_sy
+
+ sec
+ lda X2
+ sbc X1
+ lda X2+1
+ sbc X1+1
+ bpl @L1
+ lda X1
+ ldx X2
+ sta X2
+ stx X1
+ lda X1+1
+ ldx X2+1
+ sta X2+1
+ stx X1+1
+ lda Y1
+ ldx Y2
+ sta Y2
+ stx Y1
+ lda Y1+1
+ ldx Y2+1
+ sta Y2+1
+ stx Y1+1
+@L1:
+ lda #%00000000 ; Not flipped
+ sta line_sprite
+
+ sec
+ lda Y2
+ sbc Y1
+ sta Y2
+ lda Y2+1
+ sbc Y1+1
+ sta Y2+1
+ bpl @L2
+ sec
+ lda #0
+ sbc Y2
+ sta Y2
+ lda #0
+ sbc Y2+1
+ sta Y2+1
+ lda #%00010000 ; Vertical flip
+ sta line_sprite
+@L2:
+ lda X1
+ sta line_x
+ lda X1+1
+ sta line_x+1
+ lda Y1
+ sta line_y
+ lda Y1+1
+ sta line_y+1
+
+ lda Y2
+ ina
+ sta line_sy+1
+ sta MATHP ; hardware divide
+ stz MATHN
+
+ stz MATHH
+ stz MATHG
+ sec
+ lda X2
+ sbc X1
+ ina
+ sta MATHF
+ stz MATHE
+@L3:
+ lda SPRSYS
+ bmi @L3 ; wait for math done (bit 7 of sprsys)
+ lda MATHC
+ sta line_tilt
+ lda MATHB
+ sta line_tilt+1
+ bne @L4
+ lda #1
+ sta line_sx+1
+ bra @L6
+@L4:
+ bit line_tilt
+ bpl @L5
+ ina
+@L5:
+ sta line_sx+1
+@L6:
+ lda #<line_sprite
+ ldx #>line_sprite
+ jmp draw_sprite
+
+; ------------------------------------------------------------------------
+; 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
+;
+
+.data
+bar_coll:
+ .byte 0
+bar_sprite:
+ .byte %00000001 ; A pixel sprite
+ .byte %00010000
+ .byte %00100000
+ .addr 0,pixel_bitmap
+bar_x: .word 0
+bar_y: .word 0
+bar_sx: .word $0100
+bar_sy: .word $0100
+bar_c: .byte $00
+
+.code
+BAR: lda X1
+ sta bar_x
+ lda Y1
+ sta bar_y
+ lda X2
+ sec
+ sbc X1
+ ina
+ sta bar_sx+1
+ lda Y2
+ sec
+ sbc Y1
+ ina
+ sta bar_sy+1
+ lda DRAWINDEX
+ sta bar_c
+ lda #<bar_sprite
+ ldx #>bar_sprite
+ jmp draw_sprite
+
+; ------------------------------------------------------------------------
+; 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
+ 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:
+ lda TEXTMAGX ; Scale sprite
+ sta text_sx+1
+ lda TEXTMAGY
+ sta text_sy+1
+
+ stz text_sprite ; Set normal sprite
+ lda BGINDEX
+ bne @L1
+ lda #4
+ sta text_sprite ; Set opaque sprite
+@L1:
+ lda DRAWINDEX ; Set color
+ asl
+ asl
+ asl
+ asl
+ ora BGINDEX
+ sta text_c
+
+ lda X1 ; Set start position
+ sta text_x
+ lda X1+1
+ sta text_x+1
+ lda Y1
+ sta text_y
+ lda Y1+1
+ sta text_y+1
+
+ ldy #<-1 ; Calculate string length
+@L2:
+ iny
+ lda (STRPTR),y
+ bne @L2
+ cpy #20
+ bmi @L3
+ ldy #20
+@L3:
+ sty STRLEN
+ bne @L4
+ rts ; Zero length string
+@L4:
+ iny ; Prepare text_bitmap
+ iny
+ sty STROFF
+
+ ldy #8-1 ; 8 pixel lines per character
+ ldx #0
+ clc
+@L5:
+ lda STROFF
+ sta text_bitmap,x
+ txa
+ adc STROFF
+ tax
+ lda #$ff
+ sta text_bitmap-1,x
+ dey
+ bpl @L5
+ stz text_bitmap,x
+
+ stz tmp2
+ iny
+@L6:
+ lda (STRPTR),y
+ sty tmp1
+
+ sec ; (ch-' ') * 8
+ sbc #32
+ stz FONTOFF
+ stz FONTOFF+1
+ asl
+ asl
+ rol FONTOFF+1
+ asl
+ rol FONTOFF+1
+ clc ; Choose font
+ adc #<font
+ sta FONTOFF
+ lda FONTOFF+1
+ adc #>font
+ sta FONTOFF+1
+
+; and now copy the 8 bytes of that char
+
+ ldx tmp2
+ inx
+ stx tmp2
+
+; draw char from top to bottom, reading char-data from offset 8-1 to offset 0
+ ldy #8-1
+@L7:
+ lda (FONTOFF),y ; *chptr
+ sta text_bitmap,x ;textbuf[y*(1+len+1)+1+x]
+
+ txa
+ adc STROFF
+ tax
+
+ dey
+ bpl @L7
+
+ ; goto next char
+ ldy tmp1
+ iny
+ dec STRLEN
+ bne @L6
+
+ lda #<text_sprite
+ ldx #>text_sprite
+ jmp draw_sprite
+
+.data
+text_coll:
+ .byte 0
+text_sprite:
+ .byte $00,$90,$20
+ .addr 0, text_bitmap
+text_x:
+ .word 0
+text_y:
+ .word 0
+text_sx:
+ .word $100
+text_sy:
+ .word $100
+text_c:
+ .byte 0
+
+.rodata
+; The Font
+; 96 characters from ASCII 32 to 127
+; 8 pixels wide, 8 pixels high
+; bit value 0 = foreground, bit value 1 = background / transparent
+font:
+; VERSAIL
+ .byte $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF ;32
+ .byte $FF, $E7, $FF, $FF, $E7, $E7, $E7, $E7 ;33
+ .byte $FF, $FF, $FF, $FF, $FF, $99, $99, $99 ;34
+ .byte $FF, $99, $99, $00, $99, $00, $99, $99 ;35
+ .byte $FF, $E7, $83, $F9, $C3, $9F, $C1, $E7 ;36
+ .byte $FF, $B9, $99, $CF, $E7, $F3, $99, $9D ;37
+ .byte $FF, $C0, $99, $98, $C7, $C3, $99, $C3 ;38
+ .byte $FF, $FF, $FF, $FF, $FF, $E7, $F3, $F9 ;39
+ .byte $FF, $F3, $E7, $CF, $CF, $CF, $E7, $F3 ;40
+ .byte $FF, $CF, $E7, $F3, $F3, $F3, $E7, $CF ;41
+ .byte $FF, $FF, $99, $C3, $00, $C3, $99, $FF ;42
+ .byte $FF, $FF, $E7, $E7, $81, $E7, $E7, $FF ;43
+ .byte $CF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;44
+ .byte $FF, $FF, $FF, $FF, $81, $FF, $FF, $FF ;45
+ .byte $FF, $E7, $E7, $FF, $FF, $FF, $FF, $FF ;46
+ .byte $FF, $9F, $CF, $E7, $F3, $F9, $FC, $FF ;47
+ .byte $FF, $C3, $99, $99, $89, $91, $99, $C3 ;48
+ .byte $FF, $81, $E7, $E7, $E7, $C7, $E7, $E7 ;49
+ .byte $FF, $81, $9F, $CF, $F3, $F9, $99, $C3 ;50
+ .byte $FF, $C3, $99, $F9, $E3, $F9, $99, $C3 ;51
+ .byte $FF, $F9, $F9, $80, $99, $E1, $F1, $F9 ;52
+ .byte $FF, $C3, $99, $F9, $F9, $83, $9F, $81 ;53
+ .byte $FF, $C3, $99, $99, $83, $9F, $99, $C3 ;54
+ .byte $FF, $E7, $E7, $E7, $E7, $F3, $99, $81 ;55
+ .byte $FF, $C3, $99, $99, $C3, $99, $99, $C3 ;56
+ .byte $FF, $C3, $99, $F9, $C1, $99, $99, $C3 ;57
+ .byte $FF, $FF, $E7, $FF, $FF, $E7, $FF, $FF ;58
+ .byte $CF, $E7, $E7, $FF, $FF, $E7, $FF, $FF ;59
+ .byte $FF, $F1, $E7, $CF, $9F, $CF, $E7, $F1 ;60
+ .byte $FF, $FF, $FF, $81, $FF, $81, $FF, $FF ;61
+ .byte $FF, $8F, $E7, $F3, $F9, $F3, $E7, $8F ;62
+ .byte $FF, $E7, $FF, $E7, $F3, $F9, $99, $C3 ;63
+
+
+ .byte $FF, $C3, $9D, $9F, $91, $91, $99, $C3 ;0
+ .byte $FF, $99, $99, $99, $81, $99, $C3, $E7 ;1
+ .byte $FF, $83, $99, $99, $83, $99, $99, $83 ;2
+ .byte $FF, $C3, $99, $9F, $9F, $9F, $99, $C3 ;3
+ .byte $FF, $87, $93, $99, $99, $99, $93, $87 ;4
+ .byte $FF, $81, $9F, $9F, $87, $9F, $9F, $81 ;5
+ .byte $FF, $9F, $9F, $9F, $87, $9F, $9F, $81 ;6
+ .byte $FF, $C3, $99, $99, $91, $9F, $99, $C3 ;7
+ .byte $FF, $99, $99, $99, $81, $99, $99, $99 ;8
+ .byte $FF, $C3, $E7, $E7, $E7, $E7, $E7, $C3 ;9
+ .byte $FF, $C7, $93, $F3, $F3, $F3, $F3, $E1 ;10
+ .byte $FF, $99, $93, $87, $8F, $87, $93, $99 ;11
+ .byte $FF, $81, $9F, $9F, $9F, $9F, $9F, $9F ;12
+ .byte $FF, $9C, $9C, $9C, $94, $80, $88, $9C ;13
+ .byte $FF, $99, $99, $91, $81, $81, $89, $99 ;14
+ .byte $FF, $C3, $99, $99, $99, $99, $99, $C3 ;15
+ .byte $FF, $9F, $9F, $9F, $83, $99, $99, $83 ;16
+ .byte $FF, $F1, $C3, $99, $99, $99, $99, $C3 ;17
+ .byte $FF, $99, $93, $87, $83, $99, $99, $83 ;18
+ .byte $FF, $C3, $99, $F9, $C3, $9F, $99, $C3 ;19
+ .byte $FF, $E7, $E7, $E7, $E7, $E7, $E7, $81 ;20
+ .byte $FF, $C3, $99, $99, $99, $99, $99, $99 ;21
+ .byte $FF, $E7, $C3, $99, $99, $99, $99, $99 ;22
+ .byte $FF, $9C, $88, $80, $94, $9C, $9C, $9C ;23
+ .byte $FF, $99, $99, $C3, $E7, $C3, $99, $99 ;24
+ .byte $FF, $E7, $E7, $E7, $C3, $99, $99, $99 ;25
+ .byte $FF, $81, $9F, $CF, $E7, $F3, $F9, $81 ;26
+ .byte $FF, $C3, $CF, $CF, $CF, $CF, $CF, $C3 ;27
+ .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3 ;28
+ .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3 ;29
+ .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF ;30
+ .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF ;31
+
+
+; gemena
+ .byte $FF, $C3, $9D, $9F, $91, $91, $99, $C3 ;224
+ .byte $FF, $C1, $99, $C1, $F9, $C3, $FF, $FF ;225
+ .byte $FF, $83, $99, $99, $83, $9F, $9F, $FF ;226
+ .byte $FF, $C3, $9F, $9F, $9F, $C3, $FF, $FF ;227
+ .byte $FF, $C1, $99, $99, $C1, $F9, $F9, $FF ;228
+ .byte $FF, $C3, $9F, $81, $99, $C3, $FF, $FF ;229
+ .byte $FF, $E7, $E7, $E7, $C1, $E7, $F1, $FF ;230
+ .byte $83, $F9, $C1, $99, $99, $C1, $FF, $FF ;231
+ .byte $FF, $99, $99, $99, $83, $9F, $9F, $FF ;232
+ .byte $FF, $C3, $E7, $E7, $C7, $FF, $E7, $FF ;233
+ .byte $C3, $F9, $F9, $F9, $F9, $FF, $F9, $FF ;234
+ .byte $FF, $99, $93, $87, $93, $9F, $9F, $FF ;235
+ .byte $FF, $C3, $E7, $E7, $E7, $E7, $C7, $FF ;236
+ .byte $FF, $9C, $94, $80, $80, $99, $FF, $FF ;237
+ .byte $FF, $99, $99, $99, $99, $83, $FF, $FF ;238
+ .byte $FF, $C3, $99, $99, $99, $C3, $FF, $FF ;239
+ .byte $9F, $9F, $83, $99, $99, $83, $FF, $FF ;240
+ .byte $F9, $F9, $C1, $99, $99, $C1, $FF, $FF ;241
+ .byte $FF, $9F, $9F, $9F, $99, $83, $FF, $FF ;242
+ .byte $FF, $83, $F9, $C3, $9F, $C1, $FF, $FF ;243
+ .byte $FF, $F1, $E7, $E7, $E7, $81, $E7, $FF ;244
+ .byte $FF, $C1, $99, $99, $99, $99, $FF, $FF ;245
+ .byte $FF, $E7, $C3, $99, $99, $99, $FF, $FF ;246
+ .byte $FF, $C9, $C1, $80, $94, $9C, $FF, $FF ;247
+ .byte $FF, $99, $C3, $E7, $C3, $99, $FF, $FF ;248
+ .byte $87, $F3, $C1, $99, $99, $99, $FF, $FF ;249
+ .byte $FF, $81, $CF, $E7, $F3, $81, $FF, $FF ;250
+ .byte $FF, $C3, $CF, $CF, $CF, $CF, $CF, $C3 ;251
+ .byte $FF, $03, $9D, $CF, $83, $CF, $ED, $F3 ;252
+ .byte $FF, $C3, $F3, $F3, $F3, $F3, $F3, $C3 ;253
+ .byte $E7, $E7, $E7, $E7, $81, $C3, $E7, $FF ;254
+ .byte $FF, $EF, $CF, $80, $80, $CF, $EF, $FF ;255
+++ /dev/null
-#
-# Makefile for the mouse driver library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -g -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS =
-
-S_OBJS = mouse-kernel.o \
- mouse_buttons.o \
- mouse_getbox.o \
- mouse_geterrormsg.o \
- mouse_hide.o \
- mouse_info.o \
- mouse_ioctl.o \
- mouse_load.o \
- mouse_move.o \
- mouse_pos.o \
- mouse_setbox.o \
- mouse_show.o \
- mouse_unload.o
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @$(RM) *~ $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS)
-
-zap: clean
-
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = nes
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-mou.o: %.mou
- @$(CO) -o $(*)-mou.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-mou.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.mou: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- cclear.o \
- chline.o \
- clock.o \
- clrscr.o \
- color.o \
- cputc.o \
- crt0.o \
- ctype.o \
- cvline.o \
- get_tv.o \
- gotox.o \
- gotoxy.o \
- gotoy.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- mainargs.o \
- ppu.o \
- ppubuf.o \
- randomize.o \
- revers.o \
- setcursor.o \
- sysuname.o \
- tgi_colors.o \
- tgi_stat_stddrv.o \
- tgi_stddrv.o \
- waitvblank.o \
- wherex.o \
- wherey.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(MOUS:.mou=-mou.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS =
-
-JOYS = nes-stdjoy.joy
-
-MOUS =
-
-SERS =
-
-TGIS = nes-64-56-2.tgi
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
-
-../runtime/popa.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-nes-64-56-2.tgi: nes-64-56-2.o \
- ../runtime/popa.o \
- ../runtime/zeropage.o \
- clrscr.o \
- cputc.o \
- get_tv.o \
- gotoxy.o \
- ppu.o \
- ppubuf.o \
- setcursor.o
- @$(LD) -o $@ -t module $^
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(MOUS:.mou=.o) $(MOUS:.mou=-mou.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(MOUS) $(SERS) $(TGIS)
--- /dev/null
+../tgi/nes-64-56-2.tgi: ../wrk/nes/clrscr.o \
+ ../wrk/nes/cputc.o \
+ ../wrk/nes/get_tv.o \
+ ../wrk/nes/gotoxy.o \
+ ../wrk/nes/popa.o \
+ ../wrk/nes/ppu.o \
+ ../wrk/nes/ppubuf.o \
+ ../wrk/nes/setcursor.o
--- /dev/null
+;
+; Standard joypad driver for the NES. May be used multiple times when
+; linked to the statically application.
+;
+; Ullrich von Bassewitz, 2003-05-02
+; Stefan Haubenthal, 2004-10-05
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "nes.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $10 ; JOY_UP
+ .byte $20 ; JOY_DOWN
+ .byte $40 ; JOY_LEFT
+ .byte $80 ; JOY_RIGHT
+ .byte $01 ; JOY_FIRE (A)
+ .byte $02 ; JOY_FIRE2 (B)
+ .byte $04 ; (Select)
+ .byte $08 ; (Start)
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READJOY
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+
+.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 #0
+; rts ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; 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 #0
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READJOY:
+ and #$01 ; Fix joystick number
+ tay ; Joystick number (0,1) into Y
+
+ lda #1
+ sta APU_PAD1,y
+ lda #0
+ sta APU_PAD1,y
+
+; Read joystick
+
+ ldx #8
+@Loop: lda APU_PAD1,y
+ ror a
+ ror tmp1
+ dex
+ bne @Loop
+
+ lda tmp1
+; ldx #$00 ; X implicitly fixed
+ rts
+++ /dev/null
-;
-; Graphics driver for the lores 64x56x2 mode on the NES
-;
-; Stefan Haubenthal, 2009-03-10
-; Based on Maciej Witkowiak's line routine.
-;
-
- .include "zeropage.inc"
-
- .include "tgi-kernel.inc"
- .include "tgi-error.inc"
- .include "nes.inc"
- .include "get_tv.inc"
- .import _clrscr, setcursor, putchar
- .import paldata
-
- .macpack generic
-
-; ------------------------------------------------------------------------
-; 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 charsperline*2 ; Max X resolution
-yres: .word 56 ; Max Y resolution
- .byte 2 ; Number of drawing colors
- .byte 1 ; Number of screens available
- .byte 2 ; System font X size
- .byte 2 ; System font Y size
- .word $100 ; Aspect ratio
- .byte 0 ; TGI driver flags
-
-; 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 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
-
-; Absolute variables used in the code
-
-.bss
-
-MEM: .res charsperline*2*56/4
-MEMEND:
-ERROR: .res 1 ; Error code
-COLOR: .res 1 ; Current color
-PALETTE: .res 2 ; The current palette
-
-; Line routine stuff
-
-OGora:
-COUNT: .res 2
-OUkos:
-NY: .res 2
-Y3:
-DX: .res 1
-DY: .res 1
-AY: .res 1
-
-; Constants and tables
-
-.rodata
-
-DEFPALETTE: .byte $0, $1
-OFFSET: .byte 8, 4, 2, 1
-; 00 00 00 00 01 01 01 01
-; 00 01 10 11 00 01 10 11
-CODE: .byte 32, 29, 26, 25, 28, 24+128, 31+128, 30+128
-; 10 10 10 10 11 11 11 11
-; 00 01 10 11 00 01 10 11
- .byte 30, 31, 24, 28+128, 25+128, 26+128, 29+128, 32+128
-
-.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:
- jsr _get_tv
- cmp #TV::NTSC
- beq ntsc
-; TODO ROM!
- inc yres
- inc yres
-ntsc:; rts
-
-; ------------------------------------------------------------------------
-; 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:
-
-; 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:
- rts
-
-; ------------------------------------------------------------------------
-; GETERROR: Return the error code in A and clear it.
-
-GETERROR:
- lda ERROR
- ldx #TGI_ERR_OK
- 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:
- ldx #<MEM
- stx TEMP
- ldx #>MEM
- stx TEMP+1
- lda #0
- tay
-@L1: sta (TEMP),y
- iny
- bne @L1
- inc TEMP+1
- inx
- cpx #>MEMEND
- bne @L1
- jmp _clrscr
-
-; ------------------------------------------------------------------------
-; 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:
- sta COLOR
-; 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:
-
-; ------------------------------------------------------------------------
-; 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
-
-; ------------------------------------------------------------------------
-; 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:
-; Wait for v-blank
-@wait: lda PPU_STATUS
- bpl @wait
-
- lda #$3F
- sta PPU_VRAM_ADDR2
- lda #$00
- sta PPU_VRAM_ADDR2
-
- ldy #0
- lda (ptr1),y
- sta PALETTE
- tax
- lda paldata,x
-; sta PPU_VRAM_IO
-
- iny
- lda (ptr1),y
- sta PALETTE+1
- tax
- lda paldata,x
- sta PPU_VRAM_IO
-
- lda #TGI_ERR_OK
- 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:
- lda #<PALETTE
- ldx #>PALETTE
- rts
-
-; ------------------------------------------------------------------------
-; 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:
- ldx Y1 ; y+2<yres
- inx
- inx
- cpx yres
- bcc @L2
- ldx X1 ; x+2<xres
- inx
- inx
- cpx xres
- bcc @L2
- rts
-@L2: lda X1
- lsr
- tay
- lda Y1
- lsr
- tax
- clc
- jsr setcursor
- jsr CALC
- ldx COLOR
- bne @set2
- eor #%00001111
-@set2: sta TEMP3
-
- lda (TEMP),y
- ldx COLOR
- bne @set
- and TEMP3
- .byte $2c
-@set: ora TEMP3
- sta (TEMP),y
- tax
- lda CODE,x
-@normal:jmp putchar
-
-; ------------------------------------------------------------------------
-; 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:
- jsr CALC
- sta TEMP3
- lda (TEMP),y
- and TEMP3
- beq @L1
- lda #1
-@L1: ldx #0
- 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
-@L1: lda X1
- pha
-@L2: jsr SETPIXEL
- inc X1
- lda X2
- cmp X1
- bne @L2
- pla
- sta X1
- inc Y1
- lda Y2
- cmp Y1
- bne @L1
- rts
-
-; ------------------------------------------------------------------------
-; 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
- lsr
- tay
- lda ptr2
- lsr
- tax
- clc
- jsr setcursor
- ldy #0
-@L1: lda (ptr3),y
- jsr putchar
- iny
- cmp #$0
- bne @L1
- rts
-
-; ------------------------------------------------------------------------
-; Calculate all variables to plot the pixel at X1/Y1. If the point is out
-; of range, a carry is returned and INRANGE is set to a value !0 zero. If
-; the coordinates are valid, INRANGE is zero and the carry clear.
-
-CALC: lda xres
- sta TEMP
- lda #0
- sta TEMP+1
- ldy Y1
-@L1: lda TEMP
- add xres
- lsr
- sta TEMP
- lda TEMP+1
- adc #0
- lsr
- sta TEMP+1
- dey
- bne @L1
- lda TEMP
- add X1
- lsr
- sta TEMP
- lda TEMP+1
- adc #0
- lsr
- sta TEMP+1
- lda TEMP
- add #<MEM
- sta TEMP
- lda TEMP+1
- adc #>MEM
- sta TEMP+1
-
- lda X1
- and #%00000001
- sta TEMP3
- lda Y1
- asl
- and #%00000010
- ora TEMP3
- tax
- lda OFFSET,x
- rts
-
-; ------------------------------------------------------------------------
-
-.include "../tgi/tgidrv_line.inc"
+++ /dev/null
-;
-; Standard joypad driver for the NES. May be used multiple times when
-; linked to the statically application.
-;
-; Ullrich von Bassewitz, 2003-05-02
-; Stefan Haubenthal, 2004-10-05
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "nes.inc"
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $10 ; JOY_UP
- .byte $20 ; JOY_DOWN
- .byte $40 ; JOY_LEFT
- .byte $80 ; JOY_RIGHT
- .byte $01 ; JOY_FIRE (A)
- .byte $02 ; JOY_FIRE2 (B)
- .byte $04 ; (Select)
- .byte $08 ; (Start)
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READJOY
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
-
-.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 #0
-; rts ; Run into UNINSTALL instead
-
-; ------------------------------------------------------------------------
-; 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 #0
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READJOY:
- and #$01 ; Fix joystick number
- tay ; Joystick number (0,1) into Y
-
- lda #1
- sta APU_PAD1,y
- lda #0
- sta APU_PAD1,y
-
-; Read joystick
-
- ldx #8
-@Loop: lda APU_PAD1,y
- ror a
- ror tmp1
- dex
- bne @Loop
-
- lda tmp1
-; ldx #$00 ; X implicitly fixed
- rts
--- /dev/null
+;
+; Graphics driver for the lores 64x56x2 mode on the NES
+;
+; Stefan Haubenthal, 2009-03-10
+; Based on Maciej Witkowiak's line routine.
+;
+
+ .include "zeropage.inc"
+
+ .include "tgi-kernel.inc"
+ .include "tgi-error.inc"
+ .include "nes.inc"
+ .include "get_tv.inc"
+ .import _clrscr, setcursor, putchar
+ .import paldata
+
+ .macpack generic
+
+; ------------------------------------------------------------------------
+; 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 charsperline*2 ; Max X resolution
+yres: .word 56 ; Max Y resolution
+ .byte 2 ; Number of drawing colors
+ .byte 1 ; Number of screens available
+ .byte 2 ; System font X size
+ .byte 2 ; System font Y size
+ .word $100 ; Aspect ratio
+ .byte 0 ; TGI driver flags
+
+; 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 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
+
+; Absolute variables used in the code
+
+.bss
+
+MEM: .res charsperline*2*56/4
+MEMEND:
+ERROR: .res 1 ; Error code
+COLOR: .res 1 ; Current color
+PALETTE: .res 2 ; The current palette
+
+; Line routine stuff
+
+OGora:
+COUNT: .res 2
+OUkos:
+NY: .res 2
+Y3:
+DX: .res 1
+DY: .res 1
+AY: .res 1
+
+; Constants and tables
+
+.rodata
+
+DEFPALETTE: .byte $0, $1
+OFFSET: .byte 8, 4, 2, 1
+; 00 00 00 00 01 01 01 01
+; 00 01 10 11 00 01 10 11
+CODE: .byte 32, 29, 26, 25, 28, 24+128, 31+128, 30+128
+; 10 10 10 10 11 11 11 11
+; 00 01 10 11 00 01 10 11
+ .byte 30, 31, 24, 28+128, 25+128, 26+128, 29+128, 32+128
+
+.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:
+ jsr _get_tv
+ cmp #TV::NTSC
+ beq ntsc
+; TODO ROM!
+ inc yres
+ inc yres
+ntsc:; rts
+
+; ------------------------------------------------------------------------
+; 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:
+
+; 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:
+ rts
+
+; ------------------------------------------------------------------------
+; GETERROR: Return the error code in A and clear it.
+
+GETERROR:
+ lda ERROR
+ ldx #TGI_ERR_OK
+ 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:
+ ldx #<MEM
+ stx TEMP
+ ldx #>MEM
+ stx TEMP+1
+ lda #0
+ tay
+@L1: sta (TEMP),y
+ iny
+ bne @L1
+ inc TEMP+1
+ inx
+ cpx #>MEMEND
+ bne @L1
+ jmp _clrscr
+
+; ------------------------------------------------------------------------
+; 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:
+ sta COLOR
+; 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:
+
+; ------------------------------------------------------------------------
+; 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
+
+; ------------------------------------------------------------------------
+; 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:
+; Wait for v-blank
+@wait: lda PPU_STATUS
+ bpl @wait
+
+ lda #$3F
+ sta PPU_VRAM_ADDR2
+ lda #$00
+ sta PPU_VRAM_ADDR2
+
+ ldy #0
+ lda (ptr1),y
+ sta PALETTE
+ tax
+ lda paldata,x
+; sta PPU_VRAM_IO
+
+ iny
+ lda (ptr1),y
+ sta PALETTE+1
+ tax
+ lda paldata,x
+ sta PPU_VRAM_IO
+
+ lda #TGI_ERR_OK
+ 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:
+ lda #<PALETTE
+ ldx #>PALETTE
+ rts
+
+; ------------------------------------------------------------------------
+; 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:
+ ldx Y1 ; y+2<yres
+ inx
+ inx
+ cpx yres
+ bcc @L2
+ ldx X1 ; x+2<xres
+ inx
+ inx
+ cpx xres
+ bcc @L2
+ rts
+@L2: lda X1
+ lsr
+ tay
+ lda Y1
+ lsr
+ tax
+ clc
+ jsr setcursor
+ jsr CALC
+ ldx COLOR
+ bne @set2
+ eor #%00001111
+@set2: sta TEMP3
+
+ lda (TEMP),y
+ ldx COLOR
+ bne @set
+ and TEMP3
+ .byte $2c
+@set: ora TEMP3
+ sta (TEMP),y
+ tax
+ lda CODE,x
+@normal:jmp putchar
+
+; ------------------------------------------------------------------------
+; 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:
+ jsr CALC
+ sta TEMP3
+ lda (TEMP),y
+ and TEMP3
+ beq @L1
+ lda #1
+@L1: ldx #0
+ 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
+@L1: lda X1
+ pha
+@L2: jsr SETPIXEL
+ inc X1
+ lda X2
+ cmp X1
+ bne @L2
+ pla
+ sta X1
+ inc Y1
+ lda Y2
+ cmp Y1
+ bne @L1
+ rts
+
+; ------------------------------------------------------------------------
+; 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
+ lsr
+ tay
+ lda ptr2
+ lsr
+ tax
+ clc
+ jsr setcursor
+ ldy #0
+@L1: lda (ptr3),y
+ jsr putchar
+ iny
+ cmp #$0
+ bne @L1
+ rts
+
+; ------------------------------------------------------------------------
+; Calculate all variables to plot the pixel at X1/Y1. If the point is out
+; of range, a carry is returned and INRANGE is set to a value !0 zero. If
+; the coordinates are valid, INRANGE is zero and the carry clear.
+
+CALC: lda xres
+ sta TEMP
+ lda #0
+ sta TEMP+1
+ ldy Y1
+@L1: lda TEMP
+ add xres
+ lsr
+ sta TEMP
+ lda TEMP+1
+ adc #0
+ lsr
+ sta TEMP+1
+ dey
+ bne @L1
+ lda TEMP
+ add X1
+ lsr
+ sta TEMP
+ lda TEMP+1
+ adc #0
+ lsr
+ sta TEMP+1
+ lda TEMP
+ add #<MEM
+ sta TEMP
+ lda TEMP+1
+ adc #>MEM
+ sta TEMP+1
+
+ lda X1
+ and #%00000001
+ sta TEMP3
+ lda Y1
+ asl
+ and #%00000010
+ ora TEMP3
+ tax
+ lda OFFSET,x
+ rts
+
+; ------------------------------------------------------------------------
+
+.include "../../tgi/tgidrv_line.inc"
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = pet
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- break.o \
- cgetc.o \
- checkst.o \
- clrscr.o \
- color.o \
- conio.o \
- cputc.o \
- crt0.o \
- devnum.o \
- get_tv.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- kbsout.o \
- kchkin.o \
- kckout.o \
- kclose.o \
- kernal.o \
- kopen.o \
- kplot.o \
- krdtim.o \
- kreadst.o \
- ksetlfs.o \
- ksetnam.o \
- mainargs.o \
- randomize.o \
- revers.o \
- status.o \
- sysuname.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(TGIS:.tgi=-tgi.o)
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS =
-
-JOYS = pet-ptvjoy.joy pet-stdjoy.joy
-
-TGIS =
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(TGIS)
--- /dev/null
+;
+; PTV-2 Player joystick driver for the PET
+;
+; Stefan Haubenthal, 2005-05-25
+; Groepaz/Hitmen, 2002-12-23
+; obviously based on Ullrichs driver :)
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+; .include "pet.inc"
+VIA_PRA := $E841 ; Port register A
+VIA_DDRA := $E843 ; Data direction register A
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ .segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: lda #%10000000 ; via port A Data-Direction
+ sta VIA_DDRA ; bit 7: out bit 6-0: in
+
+ tax ; Joystick number into X
+ bne joy2
+
+; Read joystick 1
+
+joy1: lda #$80 ; via port A read/write
+ sta VIA_PRA ; (output one at PA7)
+
+ lda VIA_PRA ; via port A read/write
+ and #$1f ; get bit 4-0 (PA4-PA0)
+ eor #$1f
+ rts
+
+; Read joystick 2
+
+joy2: lda #$00 ; via port A read/write
+ sta VIA_PRA ; (output zero at PA7)
+
+ lda VIA_PRA ; via port A read/write
+ and #$0f ; get bit 3-0 (PA3-PA0)
+ sta tmp1 ; joy 4 directions
+
+ lda VIA_PRA ; via port A read/write
+ and #%00100000 ; get bit 5 (PA5)
+ lsr
+ ora tmp1
+ eor #$1f
+
+ ldx #0
+ rts
--- /dev/null
+;
+; Standard PET userport joystick driver for the PET
+;
+; Marco van den Heuvel, 2010-01-23
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "pet.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ .segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ:
+ tax ; Joystick number into X
+ bne joy2
+
+; Read joystick 1
+
+joy1:
+ lda #0
+ sta VIA_DDRA
+ lda VIA_PRA
+ and #$0f
+ cmp #$0c
+ bne @notc1
+ lda #$0f
+ bne @end1
+@notc1:
+ ora #$10
+@end1:
+ eor #$1f
+ rts
+
+; Read joystick 2
+
+joy2:
+ lda #0
+ sta VIA_DDRA
+ lda VIA_PRA
+ lsr
+ lsr
+ lsr
+ lsr
+ cmp #$0c
+ bne @notc2
+ lda #$0f
+ bne @end2
+@notc2:
+ ora #$10
+@end2:
+ eor #$1f
+ ldx #0
+ rts
+++ /dev/null
-;
-; PTV-2 Player joystick driver for the PET
-;
-; Stefan Haubenthal, 2005-05-25
-; Groepaz/Hitmen, 2002-12-23
-; obviously based on Ullrichs driver :)
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
-; .include "pet.inc"
-VIA_PRA := $E841 ; Port register A
-VIA_DDRA := $E843 ; Data direction register A
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
- .segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: lda #%10000000 ; via port A Data-Direction
- sta VIA_DDRA ; bit 7: out bit 6-0: in
-
- tax ; Joystick number into X
- bne joy2
-
-; Read joystick 1
-
-joy1: lda #$80 ; via port A read/write
- sta VIA_PRA ; (output one at PA7)
-
- lda VIA_PRA ; via port A read/write
- and #$1f ; get bit 4-0 (PA4-PA0)
- eor #$1f
- rts
-
-; Read joystick 2
-
-joy2: lda #$00 ; via port A read/write
- sta VIA_PRA ; (output zero at PA7)
-
- lda VIA_PRA ; via port A read/write
- and #$0f ; get bit 3-0 (PA3-PA0)
- sta tmp1 ; joy 4 directions
-
- lda VIA_PRA ; via port A read/write
- and #%00100000 ; get bit 5 (PA5)
- lsr
- ora tmp1
- eor #$1f
-
- ldx #0
- rts
+++ /dev/null
-;
-; Standard PET userport joystick driver for the PET
-;
-; Marco van den Heuvel, 2010-01-23
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "pet.inc"
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
- .segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ:
- tax ; Joystick number into X
- bne joy2
-
-; Read joystick 1
-
-joy1:
- lda #0
- sta VIA_DDRA
- lda VIA_PRA
- and #$0f
- cmp #$0c
- bne @notc1
- lda #$0f
- bne @end1
-@notc1:
- ora #$10
-@end1:
- eor #$1f
- rts
-
-; Read joystick 2
-
-joy2:
- lda #0
- sta VIA_DDRA
- lda VIA_PRA
- lsr
- lsr
- lsr
- lsr
- cmp #$0c
- bne @notc2
- lda #$0f
- bne @end2
-@notc2:
- ora #$10
-@end2:
- eor #$1f
- ldx #0
- rts
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = c16
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-ser.o: %.ser
- @$(CO) -o $(*)-ser.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-ser.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.ser: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- break.o \
- cgetc.o \
- clrscr.o \
- color.o \
- conio.o \
- cputc.o \
- crt0.o \
- devnum.o \
- get_tv.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kacptr.o \
- kbasin.o \
- kbhit.o \
- kbsout.o \
- kchkin.o \
- kciout.o \
- kckout.o \
- kclall.o \
- kclose.o \
- kclrch.o \
- kiobase.o \
- klisten.o \
- kload.o \
- kopen.o \
- kplot.o \
- krdtim.o \
- kreadst.o \
- ksave.o \
- ksetlfs.o \
- ksetnam.o \
- ksettim.o \
- ktalk.o \
- kunlsn.o \
- kuntlk.o \
- mainargs.o \
- randomize.o \
- revers.o \
- status.o \
- systime.o \
- sysuname.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(SERS:.ser=-ser.o) \
- $(TGIS:.tgi=-tgi.o)
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS =
-
-JOYS = plus4-stdjoy.joy
-
-SERS = plus4-stdser.ser
-
-TGIS =
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(SERS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(SERS:.ser=.o) $(SERS:.ser=-ser.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(SERS) $(TGIS)
--- /dev/null
+;
+; Standard joystick driver for the Plus/4. May be used multiple times when linked
+; to the statically application.
+;
+; Ullrich von Bassewitz, 2002-12-21
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "plus4.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 2 ; Number of joysticks we support
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: ldy #$FA ; Load index for joystick #1
+ tax ; Test joystick number
+ beq @L1
+ ldy #$FB ; Load index for joystick #2
+@L1: sei
+ sty TED_KBD
+ lda TED_KBD
+ cli
+ ldx #$00 ; Clear high byte
+ and #$1F
+ eor #$1F
+ rts
+
+++ /dev/null
-;
-; Standard joystick driver for the Plus/4. May be used multiple times when linked
-; to the statically application.
-;
-; Ullrich von Bassewitz, 2002-12-21
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "plus4.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 2 ; Number of joysticks we support
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: ldy #$FA ; Load index for joystick #1
- tax ; Test joystick number
- beq @L1
- ldy #$FB ; Load index for joystick #2
-@L1: sei
- sty TED_KBD
- lda TED_KBD
- cli
- ldx #$00 ; Clear high byte
- and #$1F
- eor #$1F
- rts
-
+++ /dev/null
-;
-; Serial driver for the builtin 6551 ACIA of the Plus/4.
-;
-; Ullrich von Bassewitz, 2003-12-13
-;
-; The driver is based on the cc65 rs232 module, which in turn is based on
-; Craig Bruce device driver for the Switftlink/Turbo-232.
-;
-; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
-;
-; This software is Public Domain. It is in Buddy assembler format.
-;
-; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
-; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
-; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
-; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
-;
-; The code assumes that the kernal + I/O are in context. On the C128, call
-; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
-; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
-; interrupt handling assumes that the 65816 is in 6502-emulation mode.
-;
-
- .include "zeropage.inc"
- .include "ser-kernel.inc"
- .include "ser-error.inc"
- .include "plus4.inc"
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $73, $65, $72 ; "ser"
- .byte SER_API_VERSION ; Serial API version number
-
-; Jump table.
-
- .word INSTALL
- .word UNINSTALL
- .word OPEN
- .word CLOSE
- .word GET
- .word PUT
- .word STATUS
- .word IOCTL
- .word IRQ
-
-;----------------------------------------------------------------------------
-; I/O definitions
-
-ACIA = $DE00
-ACIA_DATA = ACIA+0 ; Data register
-ACIA_STATUS = ACIA+1 ; Status register
-ACIA_CMD = ACIA+2 ; Command register
-ACIA_CTRL = ACIA+3 ; Control register
-
-;----------------------------------------------------------------------------
-;
-; Global variables
-;
-
-.bss
-RecvHead: .res 1 ; Head of receive buffer
-RecvTail: .res 1 ; Tail of receive buffer
-RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
-SendHead: .res 1 ; Head of send buffer
-SendTail: .res 1 ; Tail of send buffer
-SendFreeCnt: .res 1 ; Number of bytes in send buffer
-
-Stopped: .res 1 ; Flow-stopped flag
-RtsOff: .res 1 ;
-
-; Send and receive buffers: 256 bytes each
-RecvBuf: .res 256
-SendBuf: .res 256
-
-.rodata
-
-; Tables used to translate RS232 params into register values
-
-BaudTable: ; bit7 = 1 means setting is invalid
- .byte $FF ; SER_BAUD_45_5
- .byte $01 ; SER_BAUD_50
- .byte $02 ; SER_BAUD_75
- .byte $03 ; SER_BAUD_110
- .byte $04 ; SER_BAUD_134_5
- .byte $05 ; SER_BAUD_150
- .byte $06 ; SER_BAUD_300
- .byte $07 ; SER_BAUD_600
- .byte $08 ; SER_BAUD_1200
- .byte $09 ; SER_BAUD_1800
- .byte $0A ; SER_BAUD_2400
- .byte $0B ; SER_BAUD_3600
- .byte $0C ; SER_BAUD_4800
- .byte $0D ; SER_BAUD_7200
- .byte $0E ; SER_BAUD_9600
- .byte $0F ; SER_BAUD_19200
- .byte $FF ; SER_BAUD_38400
- .byte $FF ; SER_BAUD_57600
- .byte $FF ; SER_BAUD_115200
- .byte $FF ; SER_BAUD_230400
-
-BitTable:
- .byte $60 ; SER_BITS_5
- .byte $40 ; SER_BITS_6
- .byte $20 ; SER_BITS_7
- .byte $00 ; SER_BITS_8
-
-StopTable:
- .byte $00 ; SER_STOP_1
- .byte $80 ; SER_STOP_2
-
-ParityTable:
- .byte $00 ; SER_PAR_NONE
- .byte $20 ; SER_PAR_ODD
- .byte $60 ; SER_PAR_EVEN
- .byte $A0 ; SER_PAR_MARK
- .byte $E0 ; SER_PAR_SPACE
-
-.code
-
-;----------------------------------------------------------------------------
-; INSTALL routine. Is called after the driver is loaded into memory. If
-; possible, check if the hardware is present.
-; Must return an SER_ERR_xx code in a/x.
-;
-; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
-; the same as:
-;
-; UNINSTALL routine. Is called before the driver is removed from memory.
-; Must return an SER_ERR_xx code in a/x.
-;
-; and:
-;
-; CLOSE: Close the port, disable interrupts and flush the buffer. Called
-; without parameters. Must return an error code in a/x.
-;
-
-INSTALL:
-UNINSTALL:
-CLOSE:
-
-; Deactivate DTR and disable 6551 interrupts
-
- lda #%00001010
- sta ACIA_CMD
-
-; Done, return an error code
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-;----------------------------------------------------------------------------
-; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
-; Must return an SER_ERR_xx code in a/x.
-
-OPEN:
-
-; Check if the handshake setting is valid
-
- ldy #SER_PARAMS::HANDSHAKE ; Handshake
- lda (ptr1),y
- cmp #SER_HS_HW ; This is all we support
- bne InvParam
-
-; Initialize buffers
-
- ldx #0
- stx Stopped
- stx RecvHead
- stx RecvTail
- stx SendHead
- stx SendTail
- dex ; X = 255
- stx RecvFreeCnt
- stx SendFreeCnt
-
-; Set the value for the control register, which contains stop bits, word
-; length and the baud rate.
-
- ldy #SER_PARAMS::BAUDRATE
- lda (ptr1),y ; Baudrate index
- tay
- lda BaudTable,y ; Get 6551 value
- bmi InvBaud ; Branch if rate not supported
- sta tmp1
-
- ldy #SER_PARAMS::DATABITS ; Databits
- lda (ptr1),y
- tay
- lda BitTable,y
- ora tmp1
- sta tmp1
-
- ldy #SER_PARAMS::STOPBITS ; Stopbits
- lda (ptr1),y
- tay
- lda StopTable,y
- ora tmp1
- ora #%00010000 ; Receiver clock source = baudrate
- sta ACIA_CTRL
-
-; Set the value for the command register. We remember the base value in
-; RtsOff, since we will have to manipulate ACIA_CMD often.
-
- ldy #SER_PARAMS::PARITY ; Parity
- lda (ptr1),y
- tay
- lda ParityTable,y
- ora #%00000001 ; DTR active
- sta RtsOff
- ora #%00001000 ; Enable receive interrupts
- sta ACIA_CMD
-
-; Done
-
- lda #<SER_ERR_OK
- tax ; A is zero
- rts
-
-; Invalid parameter
-
-InvParam:
- lda #<SER_ERR_INIT_FAILED
- ldx #>SER_ERR_INIT_FAILED
- rts
-
-; Baud rate not available
-
-InvBaud:
- lda #<SER_ERR_BAUD_UNAVAIL
- ldx #>SER_ERR_BAUD_UNAVAIL
- rts
-
-;----------------------------------------------------------------------------
-; GET: Will fetch a character from the receive buffer and store it into the
-; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
-; return.
-;
-
-GET: ldx SendFreeCnt ; Send data if necessary
- inx ; X == $FF?
- beq @L1
- lda #$00
- jsr TryToSend
-
-; Check for buffer empty
-
-@L1: lda RecvFreeCnt ; (25)
- cmp #$ff
- bne @L2
- lda #<SER_ERR_NO_DATA
- ldx #>SER_ERR_NO_DATA
- rts
-
-; Check for flow stopped & enough free: release flow control
-
-@L2: ldx Stopped ; (34)
- beq @L3
- cmp #63
- bcc @L3
- lda #$00
- sta Stopped
- lda RtsOff
- ora #%00001000
- sta ACIA_CMD
-
-; Get byte from buffer
-
-@L3: ldx RecvHead ; (41)
- lda RecvBuf,x
- inc RecvHead
- inc RecvFreeCnt
- ldx #$00 ; (59)
- sta (ptr1,x)
- txa ; Return code = 0
- rts
-
-;----------------------------------------------------------------------------
-; PUT: Output character in A.
-; Must return an error code in a/x.
-;
-
-PUT:
-
-; Try to send
-
- ldx SendFreeCnt
- inx ; X = $ff?
- beq @L2
- pha
- lda #$00
- jsr TryToSend
- pla
-
-; Put byte into send buffer & send
-
-@L2: ldx SendFreeCnt
- bne @L3
- lda #<SER_ERR_OVERFLOW ; X is already zero
- rts
-
-@L3: ldx SendTail
- sta SendBuf,x
- inc SendTail
- dec SendFreeCnt
- lda #$ff
- jsr TryToSend
- lda #<SER_ERR_OK
- tax
- rts
-
-;----------------------------------------------------------------------------
-; STATUS: Return the status in the variable pointed to by ptr1.
-; Must return an error code in a/x.
-;
-
-STATUS: lda ACIA_STATUS
- ldx #0
- sta (ptr1,x)
- txa ; SER_ERR_OK
- rts
-
-;----------------------------------------------------------------------------
-; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
-; specific data in ptr1, and the ioctl code in A.
-; Must return an error code in a/x.
-;
-
-IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
- ldx #>SER_ERR_INV_IOCTL
- rts ; Run into IRQ instead
-
-;----------------------------------------------------------------------------
-; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
-; registers are already save, no parameters are passed, but the carry flag
-; is clear on entry. The routine must return with carry set if the interrupt
-; was handled, otherwise with carry clear.
-;
-
-IRQ: lda ACIA_STATUS ; Check ACIA status for receive interrupt
- and #$08
- beq @L9 ; Jump if no ACIA interrupt (carry still clear)
- lda ACIA_DATA ; Get byte from ACIA
- ldx RecvFreeCnt ; Check if we have free space left
- beq @L1 ; Jump if no space in receive buffer
- ldy RecvTail ; Load buffer pointer
- sta RecvBuf,y ; Store received byte in buffer
- inc RecvTail ; Increment buffer pointer
- dec RecvFreeCnt ; Decrement free space counter
- cpx #33 ; Check for buffer space low
- bcc @L1 ; Assert flow control if buffer space low
- rts ; Return with carry set (interrupt handled)
-
-; Assert flow control if buffer space too low
-
-@L1: lda RtsOff
- sta ACIA_CMD
- sta Stopped
- sec ; Interrupt handled
-@L9: rts
-
-;----------------------------------------------------------------------------
-; Try to send a byte. Internal routine. A = TryHard
-
-.proc TryToSend
-
- sta tmp1 ; Remember tryHard flag
-@L0: lda SendFreeCnt
- cmp #$ff
- beq @L3 ; Bail out
-
-; Check for flow stopped
-
-@L1: lda Stopped
- bne @L3 ; Bail out
-
-; Check that swiftlink is ready to send
-
-@L2: lda ACIA_STATUS
- and #$10
- bne @L4
- bit tmp1 ;keep trying if must try hard
- bmi @L0
-@L3: rts
-
-; Send byte and try again
-
-@L4: ldx SendHead
- lda SendBuf,x
- sta ACIA_DATA
- inc SendHead
- inc SendFreeCnt
- jmp @L0
-
-.endproc
-
-
--- /dev/null
+;
+; Serial driver for the builtin 6551 ACIA of the Plus/4.
+;
+; Ullrich von Bassewitz, 2003-12-13
+;
+; The driver is based on the cc65 rs232 module, which in turn is based on
+; Craig Bruce device driver for the Switftlink/Turbo-232.
+;
+; SwiftLink/Turbo-232 v0.90 device driver, by Craig Bruce, 14-Apr-1998.
+;
+; This software is Public Domain. It is in Buddy assembler format.
+;
+; This device driver uses the SwiftLink RS-232 Serial Cartridge, available from
+; Creative Micro Designs, Inc, and also supports the extensions of the Turbo232
+; Serial Cartridge. Both devices are based on the 6551 ACIA chip. It also
+; supports the "hacked" SwiftLink with a 1.8432 MHz crystal.
+;
+; The code assumes that the kernal + I/O are in context. On the C128, call
+; it from Bank 15. On the C64, don't flip out the Kernal unless a suitable
+; NMI catcher is put into the RAM under then Kernal. For the SuperCPU, the
+; interrupt handling assumes that the 65816 is in 6502-emulation mode.
+;
+
+ .include "zeropage.inc"
+ .include "ser-kernel.inc"
+ .include "ser-error.inc"
+ .include "plus4.inc"
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $73, $65, $72 ; "ser"
+ .byte SER_API_VERSION ; Serial API version number
+
+; Jump table.
+
+ .word INSTALL
+ .word UNINSTALL
+ .word OPEN
+ .word CLOSE
+ .word GET
+ .word PUT
+ .word STATUS
+ .word IOCTL
+ .word IRQ
+
+;----------------------------------------------------------------------------
+; I/O definitions
+
+ACIA = $DE00
+ACIA_DATA = ACIA+0 ; Data register
+ACIA_STATUS = ACIA+1 ; Status register
+ACIA_CMD = ACIA+2 ; Command register
+ACIA_CTRL = ACIA+3 ; Control register
+
+;----------------------------------------------------------------------------
+;
+; Global variables
+;
+
+.bss
+RecvHead: .res 1 ; Head of receive buffer
+RecvTail: .res 1 ; Tail of receive buffer
+RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
+SendHead: .res 1 ; Head of send buffer
+SendTail: .res 1 ; Tail of send buffer
+SendFreeCnt: .res 1 ; Number of bytes in send buffer
+
+Stopped: .res 1 ; Flow-stopped flag
+RtsOff: .res 1 ;
+
+; Send and receive buffers: 256 bytes each
+RecvBuf: .res 256
+SendBuf: .res 256
+
+.rodata
+
+; Tables used to translate RS232 params into register values
+
+BaudTable: ; bit7 = 1 means setting is invalid
+ .byte $FF ; SER_BAUD_45_5
+ .byte $01 ; SER_BAUD_50
+ .byte $02 ; SER_BAUD_75
+ .byte $03 ; SER_BAUD_110
+ .byte $04 ; SER_BAUD_134_5
+ .byte $05 ; SER_BAUD_150
+ .byte $06 ; SER_BAUD_300
+ .byte $07 ; SER_BAUD_600
+ .byte $08 ; SER_BAUD_1200
+ .byte $09 ; SER_BAUD_1800
+ .byte $0A ; SER_BAUD_2400
+ .byte $0B ; SER_BAUD_3600
+ .byte $0C ; SER_BAUD_4800
+ .byte $0D ; SER_BAUD_7200
+ .byte $0E ; SER_BAUD_9600
+ .byte $0F ; SER_BAUD_19200
+ .byte $FF ; SER_BAUD_38400
+ .byte $FF ; SER_BAUD_57600
+ .byte $FF ; SER_BAUD_115200
+ .byte $FF ; SER_BAUD_230400
+
+BitTable:
+ .byte $60 ; SER_BITS_5
+ .byte $40 ; SER_BITS_6
+ .byte $20 ; SER_BITS_7
+ .byte $00 ; SER_BITS_8
+
+StopTable:
+ .byte $00 ; SER_STOP_1
+ .byte $80 ; SER_STOP_2
+
+ParityTable:
+ .byte $00 ; SER_PAR_NONE
+ .byte $20 ; SER_PAR_ODD
+ .byte $60 ; SER_PAR_EVEN
+ .byte $A0 ; SER_PAR_MARK
+ .byte $E0 ; SER_PAR_SPACE
+
+.code
+
+;----------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present.
+; Must return an SER_ERR_xx code in a/x.
+;
+; Since we don't have to manage the IRQ vector on the Plus/4, this is actually
+; the same as:
+;
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Must return an SER_ERR_xx code in a/x.
+;
+; and:
+;
+; CLOSE: Close the port, disable interrupts and flush the buffer. Called
+; without parameters. Must return an error code in a/x.
+;
+
+INSTALL:
+UNINSTALL:
+CLOSE:
+
+; Deactivate DTR and disable 6551 interrupts
+
+ lda #%00001010
+ sta ACIA_CMD
+
+; Done, return an error code
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+;----------------------------------------------------------------------------
+; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
+; Must return an SER_ERR_xx code in a/x.
+
+OPEN:
+
+; Check if the handshake setting is valid
+
+ ldy #SER_PARAMS::HANDSHAKE ; Handshake
+ lda (ptr1),y
+ cmp #SER_HS_HW ; This is all we support
+ bne InvParam
+
+; Initialize buffers
+
+ ldx #0
+ stx Stopped
+ stx RecvHead
+ stx RecvTail
+ stx SendHead
+ stx SendTail
+ dex ; X = 255
+ stx RecvFreeCnt
+ stx SendFreeCnt
+
+; Set the value for the control register, which contains stop bits, word
+; length and the baud rate.
+
+ ldy #SER_PARAMS::BAUDRATE
+ lda (ptr1),y ; Baudrate index
+ tay
+ lda BaudTable,y ; Get 6551 value
+ bmi InvBaud ; Branch if rate not supported
+ sta tmp1
+
+ ldy #SER_PARAMS::DATABITS ; Databits
+ lda (ptr1),y
+ tay
+ lda BitTable,y
+ ora tmp1
+ sta tmp1
+
+ ldy #SER_PARAMS::STOPBITS ; Stopbits
+ lda (ptr1),y
+ tay
+ lda StopTable,y
+ ora tmp1
+ ora #%00010000 ; Receiver clock source = baudrate
+ sta ACIA_CTRL
+
+; Set the value for the command register. We remember the base value in
+; RtsOff, since we will have to manipulate ACIA_CMD often.
+
+ ldy #SER_PARAMS::PARITY ; Parity
+ lda (ptr1),y
+ tay
+ lda ParityTable,y
+ ora #%00000001 ; DTR active
+ sta RtsOff
+ ora #%00001000 ; Enable receive interrupts
+ sta ACIA_CMD
+
+; Done
+
+ lda #<SER_ERR_OK
+ tax ; A is zero
+ rts
+
+; Invalid parameter
+
+InvParam:
+ lda #<SER_ERR_INIT_FAILED
+ ldx #>SER_ERR_INIT_FAILED
+ rts
+
+; Baud rate not available
+
+InvBaud:
+ lda #<SER_ERR_BAUD_UNAVAIL
+ ldx #>SER_ERR_BAUD_UNAVAIL
+ rts
+
+;----------------------------------------------------------------------------
+; GET: Will fetch a character from the receive buffer and store it into the
+; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
+; return.
+;
+
+GET: ldx SendFreeCnt ; Send data if necessary
+ inx ; X == $FF?
+ beq @L1
+ lda #$00
+ jsr TryToSend
+
+; Check for buffer empty
+
+@L1: lda RecvFreeCnt ; (25)
+ cmp #$ff
+ bne @L2
+ lda #<SER_ERR_NO_DATA
+ ldx #>SER_ERR_NO_DATA
+ rts
+
+; Check for flow stopped & enough free: release flow control
+
+@L2: ldx Stopped ; (34)
+ beq @L3
+ cmp #63
+ bcc @L3
+ lda #$00
+ sta Stopped
+ lda RtsOff
+ ora #%00001000
+ sta ACIA_CMD
+
+; Get byte from buffer
+
+@L3: ldx RecvHead ; (41)
+ lda RecvBuf,x
+ inc RecvHead
+ inc RecvFreeCnt
+ ldx #$00 ; (59)
+ sta (ptr1,x)
+ txa ; Return code = 0
+ rts
+
+;----------------------------------------------------------------------------
+; PUT: Output character in A.
+; Must return an error code in a/x.
+;
+
+PUT:
+
+; Try to send
+
+ ldx SendFreeCnt
+ inx ; X = $ff?
+ beq @L2
+ pha
+ lda #$00
+ jsr TryToSend
+ pla
+
+; Put byte into send buffer & send
+
+@L2: ldx SendFreeCnt
+ bne @L3
+ lda #<SER_ERR_OVERFLOW ; X is already zero
+ rts
+
+@L3: ldx SendTail
+ sta SendBuf,x
+ inc SendTail
+ dec SendFreeCnt
+ lda #$ff
+ jsr TryToSend
+ lda #<SER_ERR_OK
+ tax
+ rts
+
+;----------------------------------------------------------------------------
+; STATUS: Return the status in the variable pointed to by ptr1.
+; Must return an error code in a/x.
+;
+
+STATUS: lda ACIA_STATUS
+ ldx #0
+ sta (ptr1,x)
+ txa ; SER_ERR_OK
+ rts
+
+;----------------------------------------------------------------------------
+; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
+; specific data in ptr1, and the ioctl code in A.
+; Must return an error code in a/x.
+;
+
+IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
+ ldx #>SER_ERR_INV_IOCTL
+ rts ; Run into IRQ instead
+
+;----------------------------------------------------------------------------
+; IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
+; registers are already save, no parameters are passed, but the carry flag
+; is clear on entry. The routine must return with carry set if the interrupt
+; was handled, otherwise with carry clear.
+;
+
+IRQ: lda ACIA_STATUS ; Check ACIA status for receive interrupt
+ and #$08
+ beq @L9 ; Jump if no ACIA interrupt (carry still clear)
+ lda ACIA_DATA ; Get byte from ACIA
+ ldx RecvFreeCnt ; Check if we have free space left
+ beq @L1 ; Jump if no space in receive buffer
+ ldy RecvTail ; Load buffer pointer
+ sta RecvBuf,y ; Store received byte in buffer
+ inc RecvTail ; Increment buffer pointer
+ dec RecvFreeCnt ; Decrement free space counter
+ cpx #33 ; Check for buffer space low
+ bcc @L1 ; Assert flow control if buffer space low
+ rts ; Return with carry set (interrupt handled)
+
+; Assert flow control if buffer space too low
+
+@L1: lda RtsOff
+ sta ACIA_CMD
+ sta Stopped
+ sec ; Interrupt handled
+@L9: rts
+
+;----------------------------------------------------------------------------
+; Try to send a byte. Internal routine. A = TryHard
+
+.proc TryToSend
+
+ sta tmp1 ; Remember tryHard flag
+@L0: lda SendFreeCnt
+ cmp #$ff
+ beq @L3 ; Bail out
+
+; Check for flow stopped
+
+@L1: lda Stopped
+ bne @L3 ; Bail out
+
+; Check that swiftlink is ready to send
+
+@L2: lda ACIA_STATUS
+ and #$10
+ bne @L4
+ bit tmp1 ;keep trying if must try hard
+ bmi @L0
+@L3: rts
+
+; Send byte and try again
+
+@L4: ldx SendHead
+ lda SendBuf,x
+ sta ACIA_DATA
+ inc SendHead
+ inc SendFreeCnt
+ jmp @L0
+
+.endproc
+
+
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-.c.s:
- @$(CC) $(CFLAGS) $<
-
-.s.o:
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = add.o \
- addeqsp.o \
- addysp.o \
- along.o \
- and.o \
- aslax1.o \
- aslax2.o \
- aslax3.o \
- aslax4.o \
- asleax1.o \
- asleax2.o \
- asleax3.o \
- asleax4.o \
- asr.o \
- asrax1.o \
- asrax2.o \
- asrax3.o \
- asrax4.o \
- asreax1.o \
- asreax2.o \
- asreax3.o \
- asreax4.o \
- axlong.o \
- bneg.o \
- bpushbsp.o \
- call.o \
- callirq.o \
- callmain.o \
- compl.o \
- condes.o \
- decax1.o \
- decax2.o \
- decax3.o \
- decax4.o \
- decax5.o \
- decax6.o \
- decax7.o \
- decax8.o \
- decaxy.o \
- decsp1.o \
- decsp2.o \
- decsp3.o \
- decsp4.o \
- decsp5.o \
- decsp6.o \
- decsp7.o \
- decsp8.o \
- div.o \
- enter.o \
- eq.o \
- ge.o \
- gt.o \
- icmp.o \
- idiv32by16r16.o \
- imul16x16r32.o \
- incax1.o \
- incax2.o \
- incax3.o \
- incax5.o \
- incax6.o \
- incax7.o \
- incax8.o \
- incaxy.o \
- incsp1.o \
- incsp2.o \
- incsp3.o \
- incsp4.o \
- incsp5.o \
- incsp6.o \
- incsp7.o \
- incsp8.o \
- jmpvec.o \
- ladd.o \
- laddeq.o \
- laddeqsp.o \
- land.o \
- lasr.o \
- lbneg.o \
- lcmp.o \
- lcompl.o \
- ldai.o \
- ldau0sp.o \
- ldaui.o \
- ldauisp.o \
- ldaxi.o \
- ldaxsp.o \
- ldeaxi.o \
- ldeaxysp.o \
- ldec.o \
- ldiv.o \
- le.o \
- leaaxsp.o \
- leave.o \
- leq.o \
- lge.o \
- lgt.o \
- linc.o \
- lle.o \
- llt.o \
- lmod.o \
- lmul.o \
- lne.o \
- lneg.o \
- lor.o \
- lpop.o \
- lpush.o \
- lrsub.o \
- lsave.o \
- lshelp.o \
- lshl.o \
- lshr.o \
- lsub.o \
- lsubeq.o \
- lsubeqsp.o \
- lt.o \
- ltest.o \
- ludiv.o \
- luge.o \
- lugt.o \
- lule.o \
- lult.o \
- lumod.o \
- lxor.o \
- makebool.o \
- mod.o \
- mul.o \
- mul8.o \
- mulax3.o \
- mulax5.o \
- mulax6.o \
- mulax7.o \
- mulax9.o \
- mulax10.o \
- ne.o \
- neg.o \
- or.o \
- popa.o \
- popsreg.o \
- push1.o \
- push2.o \
- push3.o \
- push4.o \
- push5.o \
- push6.o \
- push7.o \
- pusha.o \
- pushaff.o \
- pushax.o \
- pushb.o \
- pushbsp.o \
- pushc0.o \
- pushc1.o \
- pushc2.o \
- pushlysp.o \
- pushw.o \
- pushwsp.o \
- regswap.o \
- regswap1.o \
- regswap2.o \
- return0.o \
- return1.o \
- rsub.o \
- shelp.o \
- shl.o \
- shr.o \
- shrax1.o \
- shrax2.o \
- shrax3.o \
- shrax4.o \
- shreax1.o \
- shreax2.o \
- shreax3.o \
- shreax4.o \
- staspidx.o \
- staxsp.o \
- staxspi.o \
- steaxsp.o \
- steaxspi.o \
- stkchk.o \
- sub.o \
- subeqsp.o \
- subysp.o \
- swap.o \
- tosint.o \
- toslong.o \
- udiv.o \
- uge.o \
- ugt.o \
- ule.o \
- ult.o \
- udiv32by16r16.o \
- umod.o \
- umul16x16r32.o \
- umul8x16r24.o \
- umul8x8r16.o \
- xor.o \
- zeropage.o
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS)
-
-clean:
- @$(RM) *~ $(COBJS:.o=.s) $(OBJS)
-
-zap: clean
-
+++ /dev/null
-#
-# Makefile for the serial driver API
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -g -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS =
-
-S_OBJS = ser-kernel.o \
- ser_close.o \
- ser_get.o \
- ser_ioctl.o \
- ser_load.o \
- ser_open.o \
- ser_put.o \
- ser_status.o \
- ser_unload.o
-
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @$(RM) *~ $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS)
-
-zap: clean
-
+++ /dev/null
-#
-# cc65 makefile for the supervision specific modules
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = supervision
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS=
-
-S_OBJS= crt0.o \
- ctype.o
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @$(RM) $(C_OBJS:.c=.s) $(C_OBJS) $(S_OBJS)
-
-zap: clean
+++ /dev/null
-#
-# Makefile for the TGI graphics kernel
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -g -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS = tgi_arc.o \
- tgi_load_vectorfont.o \
- tgi_pieslice.o
-
-S_OBJS = tgi-kernel.o \
- tgi_bar.o \
- tgi_circle.o \
- tgi_clear.o \
- tgi_clippedline.o \
- tgi_curtoxy.o \
- tgi_done.o \
- tgi_ellipse.o \
- tgi_free_vectorfont.o \
- tgi_getaspectratio.o \
- tgi_getcolor.o \
- tgi_getcolorcount.o \
- tgi_getdefpalette.o \
- tgi_geterror.o \
- tgi_geterrormsg.o \
- tgi_getmaxcolor.o \
- tgi_getmaxx.o \
- tgi_getmaxy.o \
- tgi_getpagecount.o \
- tgi_getpalette.o \
- tgi_getpixel.o \
- tgi_getset.o \
- tgi_gettextheight.o \
- tgi_gettextwidth.o \
- tgi_getxres.o \
- tgi_getyres.o \
- tgi_gotoxy.o \
- tgi_imulround.o \
- tgi_init.o \
- tgi_install_vectorfont.o\
- tgi_ioctl.o \
- tgi_line.o \
- tgi_linepop.o \
- tgi_lineto.o \
- tgi_load.o \
- tgi_outcode.o \
- tgi_outtext.o \
- tgi_outtextxy.o \
- tgi_popxy.o \
- tgi_popxy2.o \
- tgi_setaspectratio.o \
- tgi_setcolor.o \
- tgi_setdrawpage.o \
- tgi_setpalette.o \
- tgi_setpixel.o \
- tgi_settextdir.o \
- tgi_settextstyle.o \
- tgi_setviewpage.o \
- tgi_unload.o \
- tgi_vectorchar.o
-
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @$(RM) *~ $(C_OBJS:.o=.s) $(C_OBJS) $(S_OBJS)
-
-zap: clean
-
+++ /dev/null
-#
-# makefile for CC65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = vic20
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-CO = ../../src/co65/co65
-LD = ../../src/ld65/ld65
-
-AFLAGS=-t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS=-Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-%-emd.o: %.emd
- @$(CO) -o $(*)-emd.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-emd.s
-
-%-joy.o: %.joy
- @$(CO) -o $(*)-joy.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-joy.s
-
-%-tgi.o: %.tgi
- @$(CO) -o $(*)-tgi.s --code-label _$(subst -,_,$(*)) $<
- @$(AS) -o $@ $(AFLAGS) $(*)-tgi.s
-
-%.emd: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.joy: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-%.tgi: %.o ../runtime/zeropage.o
- @$(LD) -o $@ -t module $^
-
-#--------------------------------------------------------------------------
-# Object files
-
-OBJS = _scrsize.o \
- break.o \
- crt0.o \
- cgetc.o \
- clrscr.o \
- color.o \
- conio.o \
- cputc.o \
- devnum.o \
- get_tv.o \
- irq.o \
- joy_stat_stddrv.o \
- joy_stddrv.o \
- kbhit.o \
- kernal.o \
- kplot.o \
- mainargs.o \
- randomize.o \
- revers.o \
- status.o \
- sysuname.o \
- $(EMDS:.emd=-emd.o) \
- $(JOYS:.joy=-joy.o) \
- $(TGIS:.tgi=-tgi.o)
-
-#--------------------------------------------------------------------------
-# Drivers
-
-EMDS =
-
-JOYS = vic20-stdjoy.joy vic20-ptvjoy.joy
-
-TGIS =
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(OBJS) $(EMDS) $(JOYS) $(TGIS)
-
-../runtime/zeropage.o:
- $(MAKE) -C $(dir $@) $(notdir $@)
-
-clean:
- @$(RM) $(OBJS) \
- $(EMDS:.emd=.o) $(EMDS:.emd=-emd.s) \
- $(JOYS:.joy=.o) $(JOYS:.joy=-joy.s) \
- $(TGIS:.tgi=.o) $(TGIS:.tgi=-tgi.s)
-
-zap: clean
- @$(RM) $(EMDS) $(JOYS) $(TGIS)
--- /dev/null
+;
+; PTV-3 Player joystick driver for the VIC20
+;
+; Stefan Haubenthal, 2005-05-25
+; Groepaz/Hitmen, 2002-12-23
+; obviously based on Ullrichs driver :)
+; Using code from Steve Schmidtke
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "vic20.inc"
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+ .segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $01 ; JOY_UP
+ .byte $02 ; JOY_DOWN
+ .byte $04 ; JOY_LEFT
+ .byte $08 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+VIA1_PRB := VIA1 ; User port register
+JOY_COUNT = 3 ; Number of joysticks we support
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+;
+
+READ: tax ; Joystick number into X
+ bne joy2
+
+; Read joystick 1
+
+joy1: lda #$7F ; mask for VIA2 JOYBIT: sw3
+ ldx #$C3 ; mask for VIA1 JOYBITS: sw0,sw1,sw2,sw4
+ sei ; necessary?
+
+ ldy VIA2_DDRB ; remember the date of DDRB
+ sta VIA2_DDRB ; set JOYBITS on this VIA for input
+ lda VIA2_JOY ; read JOYBIT: sw3
+ sty VIA2_DDRB ; restore the state of DDRB
+ asl ; Shift sw3 into carry
+
+ ldy VIA1_DDRA ; remember the state of DDRA
+ stx VIA1_DDRA ; set JOYBITS on this VIA for input
+ lda VIA1_JOY ; read JOYBITS: sw0,sw1,sw2,sw4
+ sty VIA1_DDRA ; restore the state of DDRA
+
+ cli ; necessary?
+ ror ; Shift sw3 into bit 7
+ and #$9E ; Mask relevant bits
+ eor #$9E ; Active states are inverted
+
+ rts
+
+; Read joystick 2
+
+joy2: lda #%10000000 ; via port B Data-Direction
+ sta VIA1_DDRB ; bit 7: out bit 6-0: in
+
+ dex
+ bne joy3
+
+ lda #$80 ; via port B read/write
+ sta VIA1_PRB ; (output one at PB7)
+
+ lda VIA1_PRB ; via port B read/write
+ and #$1f ; get bit 4-0 (PB4-PB0)
+ eor #$1f
+ rts
+
+; Read joystick 3
+
+joy3: lda #$00 ; via port B read/write
+ sta VIA1_PRB ; (output zero at PB7)
+
+ lda VIA1_PRB ; via port B read/write
+ and #$0f ; get bit 3-0 (PB3-PB0)
+ sta tmp1 ; joy 4 directions
+
+ lda VIA1_PRB ; via port B read/write
+ and #%00100000 ; get bit 5 (PB5)
+ lsr
+ ora tmp1
+ eor #$1f
+
+ ldx #0
+ rts
+
--- /dev/null
+;
+; Standard joystick driver for the VIC20. May be used multiple times when linked
+; to the statically application.
+;
+; Ullrich von Bassewitz, 2002-12-20
+; Using code from Steve Schmidtke
+;
+
+ .include "zeropage.inc"
+
+ .include "joy-kernel.inc"
+ .include "joy-error.inc"
+ .include "vic20.inc"
+
+ .macpack generic
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+.segment "JUMPTABLE"
+
+; Driver signature
+
+ .byte $6A, $6F, $79 ; "joy"
+ .byte JOY_API_VERSION ; Driver API version number
+
+; Button state masks (8 values)
+
+ .byte $02 ; JOY_UP
+ .byte $04 ; JOY_DOWN
+ .byte $08 ; JOY_LEFT
+ .byte $80 ; JOY_RIGHT
+ .byte $10 ; JOY_FIRE
+ .byte $00 ; JOY_FIRE2 unavailable
+ .byte $00 ; Future expansion
+ .byte $00 ; Future expansion
+
+; Jump table.
+
+ .addr INSTALL
+ .addr UNINSTALL
+ .addr COUNT
+ .addr READ
+ .addr 0 ; IRQ entry unused
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT = 1 ; Number of joysticks we support
+
+
+; ------------------------------------------------------------------------
+; Data.
+
+
+.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
+
+; ------------------------------------------------------------------------
+; 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
+ rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A.
+; The current implemenation will ignore the joystick number because we do only
+; have one joystick
+
+READ: lda #$7F ; mask for VIA2 JOYBIT: sw3
+ ldx #$C3 ; mask for VIA1 JOYBITS: sw0,sw1,sw2,sw4
+ sei ; necessary?
+
+ ldy VIA2_DDRB ; remember the date of DDRB
+ sta VIA2_DDRB ; set JOYBITS on this VIA for input
+ lda VIA2_JOY ; read JOYBIT: sw3
+ sty VIA2_DDRB ; restore the state of DDRB
+ asl ; Shift sw3 into carry
+
+ ldy VIA1_DDRA ; remember the state of DDRA
+ stx VIA1_DDRA ; set JOYBITS on this VIA for input
+ lda VIA1_JOY ; read JOYBITS: sw0,sw1,sw2,sw4
+ sty VIA1_DDRA ; restore the state of DDRA
+
+ cli ; necessary?
+ ror ; Shift sw3 into bit 7
+ and #$9E ; Mask relevant bits
+ eor #$9E ; Active states are inverted
+
+ rts
+
+
+++ /dev/null
-;
-; PTV-3 Player joystick driver for the VIC20
-;
-; Stefan Haubenthal, 2005-05-25
-; Groepaz/Hitmen, 2002-12-23
-; obviously based on Ullrichs driver :)
-; Using code from Steve Schmidtke
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "vic20.inc"
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
- .segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $01 ; JOY_UP
- .byte $02 ; JOY_DOWN
- .byte $04 ; JOY_LEFT
- .byte $08 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-VIA1_PRB := VIA1 ; User port register
-JOY_COUNT = 3 ; Number of joysticks we support
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-;
-
-READ: tax ; Joystick number into X
- bne joy2
-
-; Read joystick 1
-
-joy1: lda #$7F ; mask for VIA2 JOYBIT: sw3
- ldx #$C3 ; mask for VIA1 JOYBITS: sw0,sw1,sw2,sw4
- sei ; necessary?
-
- ldy VIA2_DDRB ; remember the date of DDRB
- sta VIA2_DDRB ; set JOYBITS on this VIA for input
- lda VIA2_JOY ; read JOYBIT: sw3
- sty VIA2_DDRB ; restore the state of DDRB
- asl ; Shift sw3 into carry
-
- ldy VIA1_DDRA ; remember the state of DDRA
- stx VIA1_DDRA ; set JOYBITS on this VIA for input
- lda VIA1_JOY ; read JOYBITS: sw0,sw1,sw2,sw4
- sty VIA1_DDRA ; restore the state of DDRA
-
- cli ; necessary?
- ror ; Shift sw3 into bit 7
- and #$9E ; Mask relevant bits
- eor #$9E ; Active states are inverted
-
- rts
-
-; Read joystick 2
-
-joy2: lda #%10000000 ; via port B Data-Direction
- sta VIA1_DDRB ; bit 7: out bit 6-0: in
-
- dex
- bne joy3
-
- lda #$80 ; via port B read/write
- sta VIA1_PRB ; (output one at PB7)
-
- lda VIA1_PRB ; via port B read/write
- and #$1f ; get bit 4-0 (PB4-PB0)
- eor #$1f
- rts
-
-; Read joystick 3
-
-joy3: lda #$00 ; via port B read/write
- sta VIA1_PRB ; (output zero at PB7)
-
- lda VIA1_PRB ; via port B read/write
- and #$0f ; get bit 3-0 (PB3-PB0)
- sta tmp1 ; joy 4 directions
-
- lda VIA1_PRB ; via port B read/write
- and #%00100000 ; get bit 5 (PB5)
- lsr
- ora tmp1
- eor #$1f
-
- ldx #0
- rts
-
+++ /dev/null
-;
-; Standard joystick driver for the VIC20. May be used multiple times when linked
-; to the statically application.
-;
-; Ullrich von Bassewitz, 2002-12-20
-; Using code from Steve Schmidtke
-;
-
- .include "zeropage.inc"
-
- .include "joy-kernel.inc"
- .include "joy-error.inc"
- .include "vic20.inc"
-
- .macpack generic
-
-
-; ------------------------------------------------------------------------
-; Header. Includes jump table
-
-.segment "JUMPTABLE"
-
-; Driver signature
-
- .byte $6A, $6F, $79 ; "joy"
- .byte JOY_API_VERSION ; Driver API version number
-
-; Button state masks (8 values)
-
- .byte $02 ; JOY_UP
- .byte $04 ; JOY_DOWN
- .byte $08 ; JOY_LEFT
- .byte $80 ; JOY_RIGHT
- .byte $10 ; JOY_FIRE
- .byte $00 ; JOY_FIRE2 unavailable
- .byte $00 ; Future expansion
- .byte $00 ; Future expansion
-
-; Jump table.
-
- .addr INSTALL
- .addr UNINSTALL
- .addr COUNT
- .addr READ
- .addr 0 ; IRQ entry unused
-
-; ------------------------------------------------------------------------
-; Constants
-
-JOY_COUNT = 1 ; Number of joysticks we support
-
-
-; ------------------------------------------------------------------------
-; Data.
-
-
-.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
-
-; ------------------------------------------------------------------------
-; 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
- rts
-
-; ------------------------------------------------------------------------
-; READ: Read a particular joystick passed in A.
-; The current implemenation will ignore the joystick number because we do only
-; have one joystick
-
-READ: lda #$7F ; mask for VIA2 JOYBIT: sw3
- ldx #$C3 ; mask for VIA1 JOYBITS: sw0,sw1,sw2,sw4
- sei ; necessary?
-
- ldy VIA2_DDRB ; remember the date of DDRB
- sta VIA2_DDRB ; set JOYBITS on this VIA for input
- lda VIA2_JOY ; read JOYBIT: sw3
- sty VIA2_DDRB ; restore the state of DDRB
- asl ; Shift sw3 into carry
-
- ldy VIA1_DDRA ; remember the state of DDRA
- stx VIA1_DDRA ; set JOYBITS on this VIA for input
- lda VIA1_JOY ; read JOYBITS: sw0,sw1,sw2,sw4
- sty VIA1_DDRA ; restore the state of DDRA
-
- cli ; necessary?
- ror ; Shift sw3 into bit 7
- and #$9E ; Mask relevant bits
- eor #$9E ; Active states are inverted
-
- rts
-
-
+++ /dev/null
-#
-# Makefile for the zlib subdirectory of the cc65 runtime library
-#
-
-.SUFFIXES: .o .s .c
-
-#--------------------------------------------------------------------------
-# Programs and flags
-
-SYS = none
-
-AS = ../../src/ca65/ca65
-CC = ../../src/cc65/cc65
-LD = ../../src/ld65/ld65
-
-AFLAGS = -t $(SYS) --forget-inc-paths -I../../asminc
-CFLAGS = -Osir -g -T -t $(SYS) --forget-inc-paths -I . -I ../../include
-
-#--------------------------------------------------------------------------
-# Rules
-
-%.o: %.c
- @$(CC) $(CFLAGS) $<
- @$(AS) -g -o $@ $(AFLAGS) $(*).s
-
-%.o: %.s
- @$(AS) -g -o $@ $(AFLAGS) $<
-
-#--------------------------------------------------------------------------
-# Object files
-
-C_OBJS = uncompress.o
-
-
-S_OBJS = adler32.o \
- crc32.o \
- inflatemem.o
-
-
-#--------------------------------------------------------------------------
-# Targets
-
-.PHONY: all clean zap
-
-all: $(C_OBJS) $(S_OBJS)
-
-clean:
- @rm -f *~
- @rm -f $(C_OBJS:.o=.s)
- @rm -f $(C_OBJS)
- @rm -f $(S_OBJS)
-
-zap: clean
-