From 4964382c67bb3cc2d74df95a39516ae8042d3fed Mon Sep 17 00:00:00 2001 From: cuz Date: Thu, 14 Oct 2004 16:50:50 +0000 Subject: [PATCH] Added joystick and tgi driver by Karri Kaksonen git-svn-id: svn://svn.cc65.org/cc65/trunk@3246 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- libsrc/Makefile | 4 +- libsrc/lynx/Makefile | 6 +- libsrc/lynx/lynx-160-102-16.s | 549 ++++++++++++++++++++++++++++++++++ libsrc/lynx/lynx-stdjoy.s | 97 ++++++ 4 files changed, 652 insertions(+), 4 deletions(-) create mode 100644 libsrc/lynx/lynx-160-102-16.s create mode 100644 libsrc/lynx/lynx-stdjoy.s diff --git a/libsrc/Makefile b/libsrc/Makefile index 9134df1f4..4d6ae5f49 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -264,7 +264,9 @@ lynxlib: $(AR) a lynx.lib $$i/*.o;\ done mv lynx/crt0.o lynx.o - + cp lynx/*.joy . + cp lynx/*.tgi . + #----------------------------------------------------------------------------- # NES diff --git a/libsrc/lynx/Makefile b/libsrc/lynx/Makefile index d974d2916..d4f96dd48 100644 --- a/libsrc/lynx/Makefile +++ b/libsrc/lynx/Makefile @@ -34,20 +34,20 @@ # Object files OBJS = crt0.o \ - framerate.o + framerate.o #-------------------------------------------------------------------------- # Drivers EMDS = -JOYS = +JOYS = lynx-stdjoy.joy MOUS = SERS = -TGIS = +TGIS = lynx-160-102-16.tgi #-------------------------------------------------------------------------- # Targets diff --git a/libsrc/lynx/lynx-160-102-16.s b/libsrc/lynx/lynx-160-102-16.s new file mode 100644 index 000000000..d9899271f --- /dev/null +++ b/libsrc/lynx/lynx-160-102-16.s @@ -0,0 +1,549 @@ +; +; Graphics driver for the 160x102x16 mode on the Lynx. +; +; Based on Stephen L. Judds GRLIB code +; + + .include "zeropage.inc" + + .include "tgi-kernel.inc" + .include "tgi-mode.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 1 ; Number of screens available + .byte 8 ; System font X size + .byte 8 ; System font Y size + .res 4, $00 ; Reserved for future extensions + +; Next comes the jump table. Currently all entries must be valid and may point +; to an RTS for test versions (function not implemented). 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. + + .word INSTALL + .word UNINSTALL + .word INIT + .word DONE + .word GETERROR + .word CONTROL + .word CLEAR + .word SETVIEWPAGE + .word SETDRAWPAGE + .word SETCOLOR + .word SETPALETTE + .word GETPALETTE + .word GETDEFPALETTE + .word SETPIXEL + .word GETPIXEL + .word LINE + .word BAR + .word CIRCLE + .word TEXTSTYLE + .word OUTTEXT + +; ------------------------------------------------------------------------ +; 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 + +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 + +DRAWINDEX: .res 1 ; Pen to use for drawing +VIEWPAGEL: .res 1 +VIEWPAGEH: .res 1 + +; INIT/DONE +OLDD018: .res 1 ; Old register value + +; Line routine stuff +DX: .res 2 +DY: .res 2 + +; Circle routine stuff, overlaid by BAR variables +X1SAVE: +CURX: .res 1 +CURY: .res 1 +Y1SAVE: +BROW: .res 1 ; Bottom row +TROW: .res 1 ; Top row +X2SAVE: +LCOL: .res 1 ; Left column +RCOL: .res 1 ; Right column +Y2SAVE: +CHUNK1: .res 1 +OLDCH1: .res 1 +CHUNK2: .res 1 +OLDCH2: .res 1 + +; Text output stuff +TEXTMAGX: .res 1 +TEXTMAGY: .res 1 +TEXTDIR: .res 1 + +; Constants and tables + +.rodata + +DEFPALETTE: .byte >$000 + .byte >$007 + .byte >$070 + .byte >$700 + .byte >$077 + .byte >$770 + .byte >$707 + .byte >$777 + .byte >$333 + .byte >$00F + .byte >$0F0 + .byte >$F00 + .byte >$0FF + .byte >$FF0 + .byte >$F0F + .byte >$FFF + .byte <$000 + .byte <$007 + .byte <$070 + .byte <$700 + .byte <$077 + .byte <$770 + .byte <$707 + .byte <$777 + .byte <$333 + .byte <$00F + .byte <$0F0 + .byte <$F00 + .byte <$0FF + .byte <$FF0 + .byte <$F0F + .byte <$FFF + +PALETTESIZE = * - DEFPALETTE + +BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01 +BITCHUNK: .byte $FF,$7F,$3F,$1F,$0F,$07,$03,$01 + +VBASE = $E000 ; Video memory base address +CBASE = $D000 ; Color 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: +; 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 +; + +CONTROL: + lda #TGI_ERR_INV_FUNC + sta ERROR + rts + +; ------------------------------------------------------------------------ +; CLEAR: Clears the screen. +; +; Must set an error code: NO +; + +.rodata +pixel_bitmap: + .byte 3,%10000100,%00000000, $0 ; A pixel bitmap +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 +draw_sprite: + sta $fc10 + stx $fc11 + lda #1 + sta $fc91 + stz $fd90 +@L3: stz CPUSLEEP + lda $fc92 + lsr + bcs @L3 + stz $fd90 + 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: + beq @L1 + lda #<$fe00-8160-8160 + ldx #>$fe00-8160-8160 + bra @L2 +@L1: lda #<$fe00-8160 + ldx #>$fe00-8160 +@L2: sta DISPADRL ; $FD94 + sta VIEWPAGEL + stx DISPADRH ; $FD95 + sta VIEWPAGEH + 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: + beq @L1 + lda #<$fe00-8160-8160 + ldx #>$fe00-8160-8160 + bra @L2 +@L1: lda #<$fe00-8160 + ldx #>$fe00-8160 +@L2: sta VIDBASL ; $FD94 + stx VIDBASH ; $FD95 + 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 + 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 + 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_sprite: + .byte %00000001 ; A pixel sprite + .byte %00010000 + .byte %00100000 + .addr 0,pixel_bitmap +pix_x: .word 0 +pix_y: .word 0 + .word $0100 + .word $0100 +pix_c: .byte $00 + +.code +SETPIXEL: + lda X1 + sta pix_x + lda Y1 + sta pix_y + lda DRAWINDEX + sta pix_c + lda #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 (ptr1),y + 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. +; +; 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: + 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 +; + +.data +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 + sta bar_sx+1 + lda Y2 + sec + sbc Y1 + sta bar_sy+1 + lda DRAWINDEX + sta bar_c + lda #bar_sprite + jmp draw_sprite + +; ------------------------------------------------------------------------ +; CIRCLE: Draw a circle around the center X1/Y1 (= ptr1/ptr2) with the +; radius in tmp1 and the current drawing color. +; +; Must set an error code: NO +; + +CIRCLE: + 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: + rts + diff --git a/libsrc/lynx/lynx-stdjoy.s b/libsrc/lynx/lynx-stdjoy.s new file mode 100644 index 000000000..ad7be4840 --- /dev/null +++ b/libsrc/lynx/lynx-stdjoy.s @@ -0,0 +1,97 @@ +; +; 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) + + .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. + + .word INSTALL + .word UNINSTALL + .word COUNT + .word READ + +; ------------------------------------------------------------------------ +; 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 +; 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 + rts + +; ------------------------------------------------------------------------ +; READ: Read a particular joystick passed in A. + +READ: + ldx #$00 ; Clear high byte + lda JOYSTICK ; Read joystick + rts + + -- 2.39.5