Ading 4play

How to detect & use the 4play peripheral card
This commit is contained in:
Antoine Vignau
2022-10-29 21:20:41 +02:00
parent ba8b564bab
commit de8cad5750
11 changed files with 1859 additions and 0 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
4play/.DS_Store vendored Normal file

Binary file not shown.

BIN
4play/4play.2mg Normal file

Binary file not shown.

432
4play/DGR.DRIVER.S Normal file
View File

@@ -0,0 +1,432 @@
*
* A simple DGR driver
* (c) 2016, Brutal Deluxe Software
* http://www.brutaldeluxe.fr/
*
* Use them at your own risk ;-)
*
mx %11
org $1800
lst off
*---------- Some info
*
* The DGR page is similar to the 80-col screen
* Even columns on aux RAM, odd ones on main RAM
*
* There are two pixels per byte:
* - four high bits for the first pixel
* - four low bits for the second pixel
* - and so on...
* So, we have 80x48 pixels and 16 colors
*
* The routines are not optimized!
* There can be a second DGR page for
* flipping, use TXTPAGE1 or TXTPAGE2
* I did not code them here, sorry ;-)
*
*---------- Entry point
jmp DGROn ; Turn DGR on
jmp DGROff ; Turn DGR off
jmp DGRClear ; Clear screen
jmp DGRPutPixel ; Draw a pixel on screen
jmp DGRPutPixel2 ; Alt draw a pixel on screen
jmp DGRGetPixel ; Get the color of a pixel on screen
jmp DGRGetPixel2 ; Alt get the color of a pixel on screen
jmp DGRSetColor ; Set the pen color
jmp DGRSetXY ; Set X1/Y1 coordinates
jmp DGRSetXY2 ; Set X2/Y2 coordinates
jmp DGRSetPage ; Set page1/page2 data
jmp DGRDrawHLine ; Draw an horizontal line
jmp DGRDrawHLine2 ; Alt draw an horizontal line
jmp DGRDrawVLine ; Draw a vertical line
jmp DGRDrawVLine2 ; Alt draw a vertical line
*---------- Information
asc 8d
asc "DGR routines v1.0"8d
asc "(c) 2016, Brutal Deluxe"
asc 8d
*---------- Equates
maskHIGH = %11110000 ; Get high bits
maskLOW = %00001111 ; Get low bits
page1 = $04 ; High RAM ptr of DGR page 1 ($400..$7FF)
page2 = $08 ; same for page 2 ($800..$BFF)
dpSCREEN = $fe ; My usage of the zero page ;-)
minX = 0 ; 80px wide
maxX = 80
minY = 0 ; 48px height
maxY = 48
*--- Values
theCOLOR ds 1 ; color of
theCOLORHIGH ds 1 ; color for high bits (2 pixels per byte)
theCOLORFULL ds 1 ; 8-bit color (ORA of the two previous)
theX1 ds 1 ; where to draw a point
theY1 ds 1 ; again
theX2 ds 1 ; same for H and V lines
theY2 ds 1
thePAGE ds 1 ; may contain $04 (page 1) or $08 (page 2)
*--- Softswitches
KBD = $c000 ; the first softswitch
CLR80COL = $c000
SET80COL = $c001
RDMAINRAM = $c002
RDCARDRAM = $c003
WRMAINRAM = $c004
WRCARDRAM = $c005
SETSLOTCXROM = $c006
SETINTCXROM = $c007
SETSTDZP = $c008
SETALTZP = $c009
SETINTC3ROM = $c00a
SETSLOTC3ROM = $c00b
CLR80VID = $c00c
SET80VID = $c00d
TXTCLR = $c050
TXTSET = $c051
MIXCLR = $c052
MIXSET = $c053
TXTPAGE1 = $c054
TXTPAGE2 = $c055
LORES = $c056
HIRES = $c057
SETAN3 = $c05e
CLRAN3 = $c05f
*---------- Tables
ptrSCRl hex 0080008000800080
hex 28a828a828a828a8
hex 50d050d050d050d0
ptrSCRh hex 0000010102020303
hex 0000010102020303
hex 0000010102020303
*---------------------------
* DGROn
* Turn the DGR screen on
* Current video conf is not saved
*
DGROn = *
sta SET80COL ; enable 80 column store
sta SET80VID ; enable 80 column hardware
sta TXTCLR ; switch in graphics (not text)
sta MIXCLR ; clear mixed mode
sta LORES ; low-resolution graphics
sta SETAN3 ; clear annunciator 3
lda #page1 ; exit by forcing page 1
jmp DGRSetPage
*---------------------------
* DGROff
* Turn the DGR screen off
* Previous video conf is not restored
*
DGROff = *
sta CLRAN3 ; set annunciator 3
sta TXTPAGE1 ; switch in text page 1
sta MIXSET ; set mixed mode (4 lines text)
sta TXTSET ; switch in text (not graphics)
sta CLR80VID ; disable 80-column hardware
sta CLR80COL ; disable 80-column store
rts
*---------------------------
* DGRClear
* Clear the entire DGR screen
* with color A (ie. HOME)
*
* We assume we are on main RAM
* We erase in two passes
* to preserve the text holes
* - $0x00..$0x77
* - $0x80..$0xF7
*
DGRClear = *
jsr DGRSetColor ; set the colors
lda #0 ; point to the first page
sta dpSCREEN ; of the DGR screen
clear1 lda thePAGE ; on PAGE1 or PAGE2
sta dpSCREEN+1
lda theCOLORFULL ; get the full 8-bit color
ldx #4-1 ; number of pages to clear
clear2 ldy #127-8 ; we clear the main RAM page
]lp sta (dpSCREEN),y
dey
bpl ]lp
ldy #255-8 ; we clear the main RAM page
]lp sta (dpSCREEN),y
dey
bmi ]lp
sta WRCARDRAM ; we clear the aux RAM page
ldy #127-8
]lp sta (dpSCREEN),y
dey
bpl ]lp
ldy #255-8 ; we clear the aux RAM page
]lp sta (dpSCREEN),y
dey
bmi ]lp
sta WRMAINRAM ; go back to main RAM
inc dpSCREEN+1 ; next page
dex ; until the
bpl clear2 ; four are done
rts ; we're done
*---------------------------
* DGRPutPixel / DGRPutPixel2
* Draw a pixel on screen
* of color A and coords X,Y
*
DGRPutPixel = *
jsr DGRSetColor ; Save color
stx theX1 ; and coordinates
sty theY1
DGRPutPixel2 = *
lda theY1 ; Set the RAM pointer
lsr ; of the Y line
php ; save the carry!
tax
lda ptrSCRl,x
sta dpSCREEN
lda ptrSCRh,x
clc
adc thePAGE ; don't forget the page
sta dpSCREEN+1
*--- Put a pixel in main or aux RAM?
lda theX1 ; Now, determine where
lsr ; to put the pixel
tay
bcs putpixel1 ; odd means main RAM
sta WRCARDRAM ; we want aux RAM
putpixel1 plp ; we restore the carry to
bcs putpixel2 ; determine where to put the pixel
*--- Put in low bits
lda (dpSCREEN),y ; get the pixel
and #maskHIGH ; keep high bits
ora theCOLOR ; add the color
sta (dpSCREEN),y ; put the pixel
sta WRMAINRAM ; back in main RAM
rts
*--- Put in high bits
putpixel2 lda (dpSCREEN),y ; get the pixel
and #maskLOW ; keep low bits
ora theCOLORHIGH ; add the color
sta (dpSCREEN),y ; put the color
sta WRMAINRAM ; back in main RAM
rts
*---------------------------
* DGRGetPixel / DGRGetPixel2
* Get the color of a pixel
* at coords X,Y and return
* it in the Accumulator
*
DGRGetPixel = *
stx theX1
sty theY1
DGRGetPixel2 = *
lda theY1 ; Set the RAM pointer
lsr ; of the Y line
php ; save the carry!
tax
lda ptrSCRl,x
sta dpSCREEN
lda ptrSCRh,x
clc
adc thePAGE ; don't forget the page
sta dpSCREEN+1
*--- Get a pixel from main or aux RAM?
lda theX1 ; Now, determine where
lsr ; to put the pixel
tay
bcs getpixel1 ; odd means main RAM
sta RDCARDRAM ; we want aux RAM
getpixel1 plp ; we restore the carry to
bcs getpixel2 ; determine where to put the pixel
*--- Get in low bits
lda (dpSCREEN),y ; get the pixel
and #maskLOW ; keep high bits
sta RDMAINRAM ; back in main RAM
rts
*--- Get in high bits
getpixel2 lda (dpSCREEN),y ; get the pixel
and #maskHIGH ; keep high bits
lsr
lsr
lsr
lsr ; and return
sta RDMAINRAM ; back in main RAM
rts
*---------------------------
* DGRSetColor
* Define the pen color
* provided in the Accumulator
*
DGRSetColor = *
and #maskLOW ; keep low 4 bits
sta theCOLOR ; save color
asl ; calculate
asl ; color for
asl ; other pixel
asl ; in the same byte
sta theCOLORHIGH ; save it
ora theCOLOR ; add lower color
sta theCOLORFULL ; save the full one
rts
*---------------------------
* DGRSetXY
* Set X/Y coords for all actions
* through registers X and Y
*
DGRSetXY = *
stx theX1
sty theY1
rts
*---------------------------
* DGRSetXY2
* Set X2/Y2 coords for line drawing
* through registers X and Y
*
DGRSetXY2 = *
stx theX2
sty theY2
rts
*---------------------------
* DGRSetPage
* Set PAGE1 or PAGE2
* as the default DGR screen
* The routine does not force
* the page, it sets a value only
*
DGRSetPage = *
sta thePAGE
rts
*---------------------------
* DGRDrawHLine / DGRDrawHLine2
* Draw a line of color A
* from X1/Y1 to coords in registers X/Y
*
* Incorrect coordinates are NOT checked
*
DGRDrawHLine = *
jsr DGRSetColor
stx theX2
sty theY2
DGRDrawHLine2 = *
lda theY1 ; are Y the same?
cmp theY2
beq drawh1
sec ; error
rts
drawh1 lda theX2 ; X2>X1?
cmp theX1
bcs drawh2 ; OK
ldx theX1 ; exchange
stx theX2 ; the two
sta theX1 ; X coords
drawh2 jsr DGRPutPixel2 ; put a pixel
inc theX1 ; next X
lda theX1
cmp theX2 ; until the last
bcc drawh2
beq drawh2
rts
*---------------------------
* DGRDrawVLine / DGRDrawVLine2
* Draw a line of color A
* from X1/Y1 to coords in registers X/Y
*
* Incorrect coordinates are NOT checked
*
DGRDrawVLine = *
jsr DGRSetColor
stx theX2
sty theY2
DGRDrawVLine2 = *
lda theX1 ; are X the same?
cmp theX2
beq drawv1
sec ; error
rts
drawv1 lda theY2 ; Y2>Y1?
cmp theY1
bcs drawv2 ; OK
ldx theY1 ; exchange
stx theY2 ; the two
sta theY1 ; Y coords
drawv2 jsr DGRPutPixel2 ; put a pixel
inc theY1 ; next Y
lda theY1
cmp theY2 ; until the last
bcc drawv2
beq drawv2
rts
*--- End of code
ds \

449
4play/DGR.DRIVER2.S Normal file
View File

@@ -0,0 +1,449 @@
*
* A simple DGR driver
* (c) 2016, Brutal Deluxe Software
* http://www.brutaldeluxe.fr/
*
* Use them at your own risk ;-)
*
mx %11
org $1800
lst off
*---------- Some info
*
* The DGR page is similar to the 80-col screen
* Even columns on aux RAM, odd ones on main RAM
*
* There are two pixels per byte:
* - four high bits for the first pixel
* - four low bits for the second pixel
* - and so on...
* So, we have 80x48 pixels and 16 colors
*
* The routines are not optimized!
* There can be a second DGR page for
* flipping, use TXTPAGE1 or TXTPAGE2
* I did not code them here, sorry ;-)
*
*---------- Entry point
jmp DGROn ; Turn DGR on
jmp DGROff ; Turn DGR off
jmp DGRClear ; Clear screen
jmp DGRPutPixel ; Draw a pixel on screen
jmp DGRPutPixel2 ; Alt draw a pixel on screen
jmp DGRGetPixel ; Get the color of a pixel on screen
jmp DGRGetPixel2 ; Alt get the color of a pixel on screen
jmp DGRSetColor ; Set the pen color
jmp DGRSetXY ; Set X1/Y1 coordinates
jmp DGRSetXY2 ; Set X2/Y2 coordinates
jmp DGRSetPage ; Set page1/page2 data
jmp DGRDrawHLine ; Draw an horizontal line
jmp DGRDrawHLine2 ; Alt draw an horizontal line
jmp DGRDrawVLine ; Draw a vertical line
jmp DGRDrawVLine2 ; Alt draw a vertical line
*---------- Information
asc 8d
asc "DGR routines v1.0"8d
asc "(c) 2016, Brutal Deluxe"
asc 8d
*---------- Equates
maskHIGH = %11110000 ; Get high bits
maskLOW = %00001111 ; Get low bits
page1 = $04 ; High RAM ptr of DGR page 1 ($400..$7FF)
page2 = $08 ; same for page 2 ($800..$BFF)
dpSCREEN = $fe ; My usage of the zero page ;-)
minX = 0 ; 80px wide
maxX = 80
minY = 0 ; 48px height
maxY = 48
*--- Values
theCOLOR ds 1 ; color of
theCOLORHIGH ds 1 ; color for high bits (2 pixels per byte)
theCOLORFULL ds 1 ; 8-bit color (ORA of the two previous)
theX1 ds 1 ; where to draw a point
theY1 ds 1 ; again
theX2 ds 1 ; same for H and V lines
theY2 ds 1
thePAGE ds 1 ; may contain $04 (page 1) or $08 (page 2)
*--- Softswitches
KBD = $c000 ; the first softswitch
CLR80COL = $c000
SET80COL = $c001
RDMAINRAM = $c002
RDCARDRAM = $c003
WRMAINRAM = $c004
WRCARDRAM = $c005
SETSLOTCXROM = $c006
SETINTCXROM = $c007
SETSTDZP = $c008
SETALTZP = $c009
SETINTC3ROM = $c00a
SETSLOTC3ROM = $c00b
CLR80VID = $c00c
SET80VID = $c00d
TXTCLR = $c050
TXTSET = $c051
MIXCLR = $c052
MIXSET = $c053
TXTPAGE1 = $c054
TXTPAGE2 = $c055
LORES = $c056
HIRES = $c057
SETAN0 = $c058
CLRAN0 = $c059
SETAN1 = $c05a
CLRAN1 = $c05b
SETAN2 = $c05c
CLRAN2 = $c05d
SETAN3 = $c05e
CLRAN3 = $c05f
*---------- Tables
ptrSCRl hex 0080008000800080
hex 28a828a828a828a8
hex 50d050d050d050d0
ptrSCRh hex 0404050506060707
hex 0404050506060707
hex 0404050506060707
*---------------------------
* DGROn
* Turn the DGR screen on
* Current video conf is not saved
*
DGROn = *
sta TXTCLR ; switch in graphics (not text)
sta MIXCLR ; clear mixed mode
sta TXTPAGE1 ; page 1
sta LORES ; low-resolution graphics
ldx #2
]lp sta SET80COL ; enable 80 column store
sta CLRAN2 ; set annunciator 2
sta CLR80VID ; disable 80 column hardware
sta SETAN3 ; clear annunciator 3
sta CLRAN3 ; set annunciator 3
sta SET80VID ; enable 80 column hardware
sta SETAN3 ; clear annunciator 3
dex
bne ]lp
rts
*---------------------------
* DGROff
* Turn the DGR screen off
* Previous video conf is not restored
*
DGROff = *
sta CLRAN3 ; set annunciator 3
sta TXTPAGE1 ; switch in text page 1
sta MIXSET ; set mixed mode (4 lines text)
sta TXTSET ; switch in text (not graphics)
sta CLR80VID ; disable 80-column hardware
sta CLR80COL ; disable 80-column store
rts
*---------------------------
* DGRClear
* Clear the entire DGR screen
* with color A (ie. HOME)
*
* We assume we are on main RAM
* We erase in two passes
* to preserve the text holes
* - $0x00..$0x77
* - $0x80..$0xF7
*
DGRClear = *
jsr DGRSetColor ; set the colors
* lda #$00 ; point to the first page
* sta dpSCREEN ; of the DGR screen
*clear1 lda #$04 ; on PAGE1 or PAGE2
* sta dpSCREEN+1
lda #0
sta clearX+1
sta clearY+1
clear1 lda #4
sta clearX+2
sta clearY+2
lda theCOLORFULL ; get the full 8-bit color
ldx #4-1 ; number of pages to clear
clear2 ldy #127-8 ; we clear the main RAM page
clearX sta $bdbd,y
dey
bpl clearX
sta WRCARDRAM ; we clear the aux RAM page
ldy #127-8
clearY sta $bdbd,y
dey
bpl clearY
sta WRMAINRAM ; go back to main RAM
inc clearX+2 ; next page
inc clearY+2
dex ; until the
bpl clear2 ; four are done
lda clearX+1 ; check if we have done
bmi clear3 ; the second pass
lda #$80 ; no, so prepare it
sta clearX+1 ; and...
sta clearY+1
bne clear1 ; ...loop
clear3 rts ; we're done
*---------------------------
* DGRPutPixel / DGRPutPixel2
* Draw a pixel on screen
* of color A and coords X,Y
*
DGRPutPixel = *
jsr DGRSetColor ; Save color
stx theX1 ; and coordinates
sty theY1
DGRPutPixel2 = *
lda theY1 ; Set the RAM pointer
lsr ; of the Y line
php ; save the carry!
tax
lda ptrSCRl,x
sta dpSCREEN
lda ptrSCRh,x
* clc
* adc thePAGE ; don't forget the page
sta dpSCREEN+1
*--- Put a pixel in main or aux RAM?
lda theX1 ; Now, determine where
lsr ; to put the pixel
tay
bcs putpixel1 ; odd means main RAM
sta TXTPAGE2 ; we want aux RAM
putpixel1 plp ; we restore the carry to
bcc putpixel2 ; determine where to put the pixel
*--- Put in low bits
lda (dpSCREEN),y ; get the pixel
and #maskHIGH ; keep high bits
ora theCOLOR ; add the color
sta (dpSCREEN),y ; put the pixel
sta TXTPAGE1 ; back in main RAM
rts
*--- Put in high bits
putpixel2 lda (dpSCREEN),y ; get the pixel
and #maskLOW ; keep low bits
ora theCOLORHIGH ; add the color
sta (dpSCREEN),y ; put the color
sta TXTPAGE1 ; back in main RAM
rts
*---------------------------
* DGRGetPixel / DGRGetPixel2
* Get the color of a pixel
* at coords X,Y and return
* it in the Accumulator
*
DGRGetPixel = *
stx theX1
sty theY1
DGRGetPixel2 = *
lda theY1 ; Set the RAM pointer
lsr ; of the Y line
php ; save the carry!
tax
lda ptrSCRl,x
sta dpSCREEN
lda ptrSCRh,x
* clc
* adc thePAGE ; don't forget the page
sta dpSCREEN+1
*--- Get a pixel from main or aux RAM?
lda theX1 ; Now, determine where
lsr ; to put the pixel
tay
bcs getpixel1 ; odd means main RAM
sta TXTPAGE2 ; we want aux RAM
getpixel1 plp ; we restore the carry to
bcc getpixel2 ; determine where to put the pixel
*--- Get in low bits
lda (dpSCREEN),y ; get the pixel
and #maskLOW ; keep high bits
sta TXTPAGE1 ; back in main RAM
rts
*--- Get in high bits
getpixel2 lda (dpSCREEN),y ; get the pixel
and #maskHIGH ; keep high bits
lsr
lsr
lsr
lsr ; and return
sta TXTPAGE1 ; back in main RAM
rts
*---------------------------
* DGRSetColor
* Define the pen color
* provided in the Accumulator
*
DGRSetColor = *
and #maskLOW ; keep low 4 bits
sta theCOLOR ; save color
asl ; calculate
asl ; color for
asl ; other pixel
asl ; in the same byte
sta theCOLORHIGH ; save it
ora theCOLOR ; add lower color
sta theCOLORFULL ; save the full one
rts
*---------------------------
* DGRSetXY
* Set X/Y coords for all actions
* through registers X and Y
*
DGRSetXY = *
stx theX1
sty theY1
rts
*---------------------------
* DGRSetXY2
* Set X2/Y2 coords for line drawing
* through registers X and Y
*
DGRSetXY2 = *
stx theX2
sty theY2
rts
*---------------------------
* DGRSetPage
* Set PAGE1 or PAGE2
* as the default DGR screen
* The routine does not force
* the page, it sets a value only
*
DGRSetPage = *
sta thePAGE
rts
*---------------------------
* DGRDrawHLine / DGRDrawHLine2
* Draw a line of color A
* from X1/Y1 to coords in registers X/Y
*
* Incorrect coordinates are NOT checked
*
DGRDrawHLine = *
jsr DGRSetColor
stx theX2
sty theY2
DGRDrawHLine2 = *
lda theY1 ; are Y the same?
cmp theY2
beq drawh1
sec ; error
rts
drawh1 lda theX2 ; X2>X1?
cmp theX1
bcs drawh2 ; OK
ldx theX1 ; exchange
stx theX2 ; the two
sta theX1 ; X coords
drawh2 jsr DGRPutPixel2 ; put a pixel
inc theX1 ; next X
lda theX1
cmp theX2 ; until the last
bcc drawh2
beq drawh2
rts
*---------------------------
* DGRDrawVLine / DGRDrawVLine2
* Draw a line of color A
* from X1/Y1 to coords in registers X/Y
*
* Incorrect coordinates are NOT checked
*
DGRDrawVLine = *
jsr DGRSetColor
stx theX2
sty theY2
DGRDrawVLine2 = *
lda theX1 ; are X the same?
cmp theX2
beq drawv1
sec ; error
rts
drawv1 lda theY2 ; Y2>Y1?
cmp theY1
bcs drawv2 ; OK
ldx theY1 ; exchange
stx theY2 ; the two
sta theY1 ; Y coords
drawv2 jsr DGRPutPixel2 ; put a pixel
inc theY1 ; next Y
lda theY1
cmp theY2 ; until the last
bcc drawv2
beq drawv2
rts
*--- End of code
ds \

349
4play/FP.DRIVER.S Normal file
View File

@@ -0,0 +1,349 @@
*
* Alex Lukazi's 4play routines
* http://lukazi.blogspot.com/
*
* (c) 2016, Brutal Deluxe Software
* http://www.brutaldeluxe.fr/
*
* Use them at your own risk ;-)
*
mx %11
org $1000
lst off
*---------- Entry point
jmp FPInitAll ; Clear tables and variables
jmp FPFindAll ; Find all 4play cards
jmp FPFindIt ; Return 1st 4play card found (if any)
jmp FPLoopIt ; ...and you can continue looping
jmp FPReadDigital ; Read the joystick the new way
jmp FPSetAnalogClampValues ; Set the values for the old way
jmp FPReadAnalog ; Read the joystick the old way
jmp FPReadTrigger ; Read buttons
jmp FPReadTrigger1 ; Read buttons
jmp FPReadTrigger2 ; Read buttons
jmp FPReadTrigger3 ; Read buttons
jmp FPSetSlot ; Force 4play slot for...
jmp FPDirectRead ; ...a direct read of a joystick
*---------- Information
asc 8d
asc "6502 4play routines v1.0"8d
asc "(c) 2016, Brutal Deluxe Software"
asc 8d
*---------- Equates
*--- Mask bits
fpUP = %00000001 ; active high
fpDOWN = %00000010 ; active high
fpLEFT = %00000100 ; active high
fpRIGHT = %00001000 ; active high
fpNOTUSED = %00010000
fpTRIGGER3 = %00100000 ; active low
fpTRIGGER2 = %01000000 ; active high
fpTRIGGER1 = %10000000 ; active high
maskBIT0 = %11111110 ; #$FE masks bit 0
maskBIT1 = %11111101 ; #$FD masks bit 1
maskBIT2 = %11111011 ; #$FB masks bit 2
maskBIT3 = %11110111 ; #$F7 masks bit 3
maskBIT4 = %11101111 ; #$EF masks bit 4
maskBIT5 = %11011111 ; #$DF masks bit 5
maskBIT6 = %10111111 ; #$BF masks bit 6
maskBIT7 = %01111111 ; #$7F masks bit 7
*--- Values
fpDFTVALUE = $20 ; dft value for Rev. B
*--- Softswitches
KBD = $c000 ; the first softswitch
swSLOT0 = $80 ; as in $C080...
swSLOT7 = $F0 ; as in $C0F0...
swSLOT8 = $00 ; as in $C100... ahem...
*--- Zero page
dpF0 = $F0 ; For indirect access to a card
; $F2 for slot 1
; $FE for slot 7
*---------- Tables
curINDEX ds 1
fpTABLE ds 7 ; We can have up to 7 cards
fpTABLE2 ds 7 ; One entry per slot
*--- This table serves in digital to analog read
fpCLAMPTBL dfb $80 ; no movement
dfb $00 ; min up or left
dfb $ff ; max down or right
dfb $80 ; no movement
*---------------------------
* FPInitAll
* Do what is necessary
* to clear all data
*
FPInitAll = *
ldx #fpTABLE2-fpTABLE
lda #0
sta curINDEX ; reset index
]lp sta fpTABLE,x ; and the
sta fpTABLE2,x ; two tables
sta |dpF0,x ; beware on the IIgs
sta |dpF0+1,x ; beware on the IIgs
dex
bpl ]lp
rts
*---------------------------
* FPFindAll
* Find all the 4play cards
* in your Apple II computer
* by looking through the slots
*
* On exit:
* A: number of cards found
* Carry clear: we have 1+ card(s)
* set: no card found
*
FPFindAll = *
jsr FPFindIt ; try to find a 4play card
bcc FPLoopAll ; we have found one
lda curINDEX ; it is normally zero
rts ; no card found tell it
FPLoopAll ldy curINDEX ; when one found
sta fpTABLE,y ; save its slot
inc curINDEX
pha ; slot becomes index
asl ; 1=>2, 2=>4
tay ; the index
txa ; slot*16
sta |dpF0,y ; is stored in DP
lda #>KBD ; and the high value
sta |dpF0+1,y ; also
pla ; restore slot
tay ; slot becomes index
dey ; minus 1 (because table is 7b)
txa ; slot*16 in A
sta fpTABLE2,y ; save slot*16 in fpTABLE2,A
jsr FPLoopIt ; loop again (X is preserved)
bcc FPLoopAll ; another one found
lda curINDEX ; tell the number of cards found
clc ; tell we've found one at least
rts
*---------------------------
* FPFindIt
* Loop through the softswitches
* $C0s0..$C0s3 for 4 consecutive
* default value (see above)
*
* On exit:
* A: slot
* X: slot*16
* Carry clear: card found
* set: card not found
*
FPFindIt = *
ldx #swSLOT8
FPLoopIt = * ; Search for the default value
txa ; previous slot
sec
sbc #$10
tax
cpx #swSLOT0 ; until slot 0
bne FPLoopIt1 ; see if there is a card
sec ; no 4play card
rts
FPLoopIt1 lda KBD,x ; $C0s0
cmp #fpDFTVALUE
bne FPLoopIt
lda KBD+1,x ; $C0s1
cmp #fpDFTVALUE
bne FPLoopIt
lda KBD+2,x ; $C0s2
cmp #fpDFTVALUE
bne FPLoopIt
lda KBD+3,x ; $C0s3
cmp #fpDFTVALUE
bne FPLoopIt ; card not found
txa ; 4play card found
and #maskBIT7 ; mask bit 7 (= -#$80)
lsr
lsr
lsr
lsr ; X= slot*16
clc ; A= slot
rts ; done
*---------------------------
* FPSetSlot
*
* Set the slot of the 4play card
* to allow the FPDirectRead to
* read joystick values rapidly
*
* On entry:
* X: slot (1..7) of the 4play card
*
FPSetSlot = *
lda fpTABLE2-1,x ; coz slot 1 is offset 0
beq FPSetSlot1 ; no card, exit
sta FPDRPatch+1
clc ; with success
rts
FPSetSlot1 sec ; with error
rts
*---------------------------
* FPDirectRead
*
* This routine reads the
* indexed joystick data
*
* On entry:
* X: player's joystick (1..4)
*
FPDirectRead = *
dex ; from 1..4 to 0..3
FPDRPatch lda KBD,x ; $C090 for S1 .. $C0F0 for S7
inx ; from 0..3 to 1..4
rts
*---------------------------
* FPReadDigital
*
* On entry:
* X: joystick to read (1..4)
*
FPReadDigital = *
jmp FPDirectRead
*---------------------------
* FPSetAnalogClampValues
*
* This routine sets the clamp values
* used in the analog mode
*
* On entry:
* A: no movement value
* X: minimal value (up or left)
* Y: maximal value (down or right)
*
FPSetAnalogClampValues = *
sta fpCLAMPTBL
sta fpCLAMPTBL+3
stx fpCLAMPTBL+1
sty fpCLAMPTBL+2
rts
*---------------------------
* FPReadAnalog
*
* This routine returns analog values
* from a digital read. It is not similar
* to PREAD, the routine in ROM
*
* On entry:
* X: joystick to read (1..4)
*
* On exit:
* X: analog value for left/right
* Y: analog value for up/down
*
FPReadAnalog = *
jsr FPDirectRead
pha ; save joystick value
and #fpUP+fpDOWN ; keep up/down
tax ; get it in our table
lda fpCLAMPTBL,x
tay ; return in Y
pla ; restore joystick value
and #fpLEFT+fpRIGHT ; keep left/right
lsr ; /2
lsr ; /2
tax ; get it in our table
lda fpCLAMPTBL,x
tax ; return in X
rts
*---------------------------
* FPReadTrigger
*
* A set of routines to read the triggers
* (or buttons)
* Note that we read /TRIGGER3 (active low)
* whereas we read TRIGGER1 and TRIGGER2 (active high)
*
* The routines must be adapted according to your needs
*
* On entry:
* X: joystick to read (1..4)
*
FPReadTrigger = *
jsr FPDirectRead
and #fpTRIGGER1+fpTRIGGER2+fpTRIGGER3
clc ; <= if useless, remove
rts
FPReadTrigger1 = *
jsr FPDirectRead
and #fpTRIGGER1 ; because it is TRIGGER1
rts
FPReadTrigger2 = *
jsr FPDirectRead
and #fpTRIGGER2 ; because it is TRIGGER2
asl ; bit 6 > bit 7
rts
FPReadTrigger3 = *
jsr FPDirectRead
and #fpTRIGGER3
eor #fpTRIGGER3 ; because we read /TRIGGER3
asl ; bit 5 > bit 6
asl ; bit 6 > bit 7
rts
ds \

393
4play/GR.DRIVER.S Normal file
View File

@@ -0,0 +1,393 @@
*
* A simple GR driver
* (c) 2016, Brutal Deluxe Software
* http://www.brutaldeluxe.fr/
*
* Use them at your own risk ;-)
*
mx %11
org $1800
lst off
*---------- Some info
*
* The GR page is similar to the 40-col screen
*
* There are two pixels per byte:
* - four high bits for the first pixel
* - four low bits for the second pixel
* - and so on...
* So, we have 40x48 pixels and 16 colors
*
* The routines are not optimized!
*
*---------- Entry point
jmp GROn ; Turn GR on
jmp GROff ; Turn GR off
jmp GRClear ; Clear screen
jmp GRPutPixel ; Draw a pixel on screen
jmp GRPutPixel2 ; Alt draw a pixel on screen
jmp GRGetPixel ; Get the color of a pixel on screen
jmp GRGetPixel2 ; Alt get the color of a pixel on screen
jmp GRSetColor ; Set the pen color
jmp GRSetXY ; Set X1/Y1 coordinates
jmp GRSetXY2 ; Set X2/Y2 coordinates
jmp GRSetPage ; Set page1/page2 data
jmp GRDrawHLine ; Draw an horizontal line
jmp GRDrawHLine2 ; Alt draw an horizontal line
jmp GRDrawVLine ; Draw a vertical line
jmp GRDrawVLine2 ; Alt draw a vertical line
*---------- Information
asc 8d
asc "GR routines v1.0"8d
asc "(c) 2016, Brutal Deluxe"
asc 8d
*---------- Equates
maskHIGH = %11110000 ; Get high bits
maskLOW = %00001111 ; Get low bits
page1 = $04 ; High RAM ptr of GR page 1 ($400..$7FF)
page2 = $08 ; same for page 2 ($800..$BFF)
dpSCREEN = $fe ; My usage of the zero page ;-)
minX = 0 ; 80px wide
maxX = 40
minY = 0 ; 48px height
maxY = 48
*--- Values
theCOLOR ds 1 ; color of
theCOLORHIGH ds 1 ; color for high bits (2 pixels per byte)
theCOLORFULL ds 1 ; 8-bit color (ORA of the two previous)
theX1 ds 1 ; where to draw a point
theY1 ds 1 ; again
theX2 ds 1 ; same for H and V lines
theY2 ds 1
thePAGE ds 1 ; may contain $04 (page 1) or $08 (page 2)
*--- Softswitches
KBD = $c000 ; the first softswitch
CLR80COL = $c000
SET80COL = $c001
RDMAINRAM = $c002
RDCARDRAM = $c003
WRMAINRAM = $c004
WRCARDRAM = $c005
SETSLOTCXROM = $c006
SETINTCXROM = $c007
SETSTDZP = $c008
SETALTZP = $c009
SETINTC3ROM = $c00a
SETSLOTC3ROM = $c00b
CLR80VID = $c00c
SET80VID = $c00d
TXTCLR = $c050
TXTSET = $c051
MIXCLR = $c052
MIXSET = $c053
TXTPAGE1 = $c054
TXTPAGE2 = $c055
LORES = $c056
HIRES = $c057
SETAN3 = $c05e
CLRAN3 = $c05f
*---------- Tables
ptrSCRl hex 0080008000800080
hex 28a828a828a828a8
hex 50d050d050d050d0
ptrSCRh hex 0000010102020303
hex 0000010102020303
hex 0000010102020303
*---------------------------
* GROn
* Turn the GR screen on
* Current video conf is not saved
*
GROn = *
sta TXTCLR ; switch in graphics (not text)
sta MIXCLR ; clear mixed mode
sta TXTPAGE1 ; force page 1
sta LORES ; low-resolution graphics
lda #page1 ; exit by forcing page 1
jmp GRSetPage
*---------------------------
* GROff
* Turn the GR screen off
* Previous video conf is not restored
*
GROff = *
sta TXTPAGE1 ; switch in text page 1
sta MIXSET ; set mixed mode (4 lines text)
sta TXTSET ; switch in text (not graphics)
rts
*---------------------------
* GRClear
* Clear the entire GR screen
* with color A (ie. HOME)
*
* We preserve the text holes
* - $0x00..$0x77
* - $0x80..$0xF7
*
GRClear = *
jsr GRSetColor ; set the colors
lda #0 ; point to the first page
sta dpSCREEN ; of the GR screen
lda thePAGE ; on PAGE1 or PAGE2
sta dpSCREEN+1
lda theCOLORFULL ; get the full 8-bit color
ldx #4-1 ; number of pages to clear
clear2 ldy #127-8 ; we clear the RAM page
]lp sta (dpSCREEN),y
dey
bpl ]lp
ldy #255-8 ; we clear the RAM page
]lp sta (dpSCREEN),y
dey
bmi ]lp
inc dpSCREEN+1 ; next page
dex ; until the
bpl clear2 ; four are done
rts ; we're done
*---------------------------
* GRPutPixel / GRPutPixel2
* Draw a pixel on screen
* of color A and coords X,Y
*
GRPutPixel = *
jsr GRSetColor ; Save color
stx theX1 ; and coordinates
sty theY1
GRPutPixel2 = *
lda theY1 ; Set the RAM pointer
lsr ; of the Y line
php ; save the carry!
tax
lda ptrSCRl,x
sta dpSCREEN
lda ptrSCRh,x
clc
adc thePAGE ; don't forget the page
sta dpSCREEN+1
*--- Put a pixel
ldy theX1 ; Now, determine where to put the pixel
plp ; we restore the carry to
bcs putpixel2 ; determine where to put the pixel
*--- Put in low bits
lda (dpSCREEN),y ; get the pixel
and #maskHIGH ; keep high bits
ora theCOLOR ; add the color
sta (dpSCREEN),y ; put the pixel
rts
*--- Put in high bits
putpixel2 lda (dpSCREEN),y ; get the pixel
and #maskLOW ; keep low bits
ora theCOLORHIGH ; add the color
sta (dpSCREEN),y ; put the color
rts
*---------------------------
* GRGetPixel / GRGetPixel2
* Get the color of a pixel
* at coords X,Y and return
* it in the Accumulator
*
GRGetPixel = *
stx theX1
sty theY1
GRGetPixel2 = *
lda theY1 ; Set the RAM pointer
lsr ; of the Y line
php ; save the carry!
tax
lda ptrSCRl,x
sta dpSCREEN
lda ptrSCRh,x
clc
adc thePAGE ; don't forget the page
sta dpSCREEN+1
*--- Get a pixel
ldy theX1 ; Now, determine where to get the pixel
plp ; we restore the carry to
bcs getpixel2 ; determine where to get the pixel
*--- Get in low bits
lda (dpSCREEN),y ; get the pixel
and #maskLOW ; keep high bits
rts
*--- Get in high bits
getpixel2 lda (dpSCREEN),y ; get the pixel
and #maskHIGH ; keep high bits
lsr
lsr
lsr
lsr ; and return
rts
*---------------------------
* GRSetColor
* Define the pen color
* provided in the Accumulator
*
GRSetColor = *
and #maskLOW ; keep low 4 bits
sta theCOLOR ; save color
asl ; calculate
asl ; color for
asl ; other pixel
asl ; in the same byte
sta theCOLORHIGH ; save it
ora theCOLOR ; add lower color
sta theCOLORFULL ; save the full one
rts
*---------------------------
* GRSetXY
* Set X/Y coords for all actions
* through registers X and Y
*
GRSetXY = *
stx theX1
sty theY1
rts
*---------------------------
* GRSetXY2
* Set X2/Y2 coords for line drawing
* through registers X and Y
*
GRSetXY2 = *
stx theX2
sty theY2
rts
*---------------------------
* GRSetPage
* Set PAGE1 or PAGE2
* as the default GR screen
* The routine does not force
* the page, it sets a value only
*
GRSetPage = *
sta thePAGE
rts
*---------------------------
* GRDrawHLine / GRDrawHLine2
* Draw a line of color A
* from X1/Y1 to coords in registers X/Y
*
* Incorrect coordinates are NOT checked
*
GRDrawHLine = *
jsr GRSetColor
stx theX2
sty theY2
GRDrawHLine2 = *
lda theY1 ; are Y the same?
cmp theY2
beq drawh1
sec ; error
rts
drawh1 lda theX2 ; X2>X1?
cmp theX1
bcs drawh2 ; OK
ldx theX1 ; exchange
stx theX2 ; the two
sta theX1 ; X coords
drawh2 jsr GRPutPixel2 ; put a pixel
inc theX1 ; next X
lda theX1
cmp theX2 ; until the last
bcc drawh2
beq drawh2
rts
*---------------------------
* GRDrawVLine / GRDrawVLine2
* Draw a line of color A
* from X1/Y1 to coords in registers X/Y
*
* Incorrect coordinates are NOT checked
*
GRDrawVLine = *
jsr GRSetColor
stx theX2
sty theY2
GRDrawVLine2 = *
lda theX1 ; are X the same?
cmp theX2
beq drawv1
sec ; error
rts
drawv1 lda theY2 ; Y2>Y1?
cmp theY1
bcs drawv2 ; OK
ldx theY1 ; exchange
stx theY2 ; the two
sta theY1 ; Y coords
drawv2 jsr GRPutPixel2 ; put a pixel
inc theY1 ; next Y
lda theY1
cmp theY2 ; until the last
bcc drawv2
beq drawv2
rts
*--- End of code
ds \

1
4play/ReadMeFirst Normal file
View File

@@ -0,0 +1 @@
4play source code (c) 2016, Brutal Deluxe Software

82
4play/TEST.DGR.S Normal file
View File

@@ -0,0 +1,82 @@
*
* DGR test program
*
* (c) 2016, Brutal Deluxe Software
* http://www.brutaldeluxe.fr/
*
* Use them at your own risk ;-)
*
mx %11
org $300
lst off
*---------- Entry point
KBD = $C000
KBDSTROBE = $C010
*---------- Driver equates
DGROn = $1800 ; Turn DGR on
DGROff = DGROn+3 ; Turn DGR off
DGRClear = DGROff+3 ; Clear screen
DGRPutPixel = DGRClear+3 ; Draw a pixel on screen
DGRPutPixel2 = DGRPutPixel+3 ; Alt draw a pixel on screen
DGRGetPixel = DGRPutPixel2+3 ; Get the color of a pixel on screen
DGRGetPixel2 = DGRGetPixel+3 ; Alt get the color of a pixel on screen
DGRSetColor = DGRGetPixel2+3 ; Set the pen color
DGRSetXY = DGRSetColor+3 ; Set X1/Y1 coordinates
DGRSetXY2 = DGRSetXY+3 ; Set X2/Y2 coordinates
DGRSetPage = DGRSetXY2+3 ; Set page1/page2 data
DGRDrawHLine = DGRSetPage+3 ; Draw an horizontal line
DGRDrawHLine2 = DGRDrawHLine+3 ; Alt draw an horizontal line
DGRDrawVLine = DGRDrawHLine2+3 ; Draw a vertical line
DGRDrawVLine2 = DGRDrawVLine+3 ; Alt draw a vertical line
*---------- The code
jsr DGROn ; Turn DGR on
lda #$00 ; Set color to black
sta theCOLOR
clearLOOP lda theCOLOR ; Please erase the screen
jsr DGRClear
]lp lda KBD ; Wait for a keypress
bpl ]lp
bit KBDSTROBE
inc theCOLOR ; Next color, please
lda theCOLOR ; There are 16 of them
cmp #16
bne clearLOOP
*--- Test 2
ldx #0
ldy #0
jsr DGRSetXY
lda #6
ldx #79
ldy #0
jsr DGRDrawHLine
ldx #79
ldy #0
jsr DGRSetXY
lda #6
ldx #79
ldy #47
jsr DGRDrawVLine
jsr $fd0c
jsr DGROff ; Turn DGR off
rts ; Exit
*--- My test data
theCOLOR ds 1

71
4play/TEST.FP.S Normal file
View File

@@ -0,0 +1,71 @@
*
* Alex Lukazi's 4play routines
* http://lukazi.blogspot.com/
*
* (c) 2016, Brutal Deluxe Software
* http://www.brutaldeluxe.fr/
*
* Use them at your own risk ;-)
*
mx %11
org $300
lst off
*---------- Entry point
KBD = $C000
KBDSTROBE = $C010
PRBYTE = $FDDA
COUT = $FDED
*---------- Driver equates
FPInitAll = $1000 ; Clear tables and variables
FPFindAll = FPInitAll+3 ; Find all 4play cards
FPFindIt = FPFindAll+3 ; Return 1st 4play card found (if any)
FPLoopIt = FPFindIt+3 ; ...and you can continue looping
FPReadDigital = FPLoopIt+3 ; Read the joystick the new way
FPSetAnalogClampValues = FPReadDigital+3 ; Set the values for the old way
FPReadAnalog = FPSetAnalogClampValues+3 ; Read the joystick the old way
FPReadTrigger = FPReadAnalog+3 ; Read buttons
FPReadTrigger1 = FPReadTrigger+3 ; Read buttons
FPReadTrigger2 = FPReadTrigger1+3 ; Read buttons
FPReadTrigger3 = FPReadTrigger2+3 ; Read buttons
FPSetSlot = FPReadTrigger3+3 ; Force 4play slot for...
FPDirectRead = FPSetSlot+3 ; ...a direct read of a joystick
*---------- The code
jsr FPInitAll ; Clear all
jsr FPFindAll ; Find all 4play cards
lda $F9 ; Get slot high
jsr PRBYTE
lda $F8 ; Get slot low
jsr PRBYTE
ldx #$04 ; Force slot 4
jsr FPSetSlot
*---
]lp lda #$8D
jsr COUT
ldx #$01 ; Read first joystick
jsr FPDirectRead
jsr PRBYTE ; display its value
lda #$A0
jsr COUT
ldx #$02 ; Read second joystick
jsr FPDirectRead
jsr PRBYTE ; display its value
lda KBD ; loop until a
bpl ]lp ; key is pressed
bit KBDSTROBE ; exit
rts

82
4play/TEST.GR.S Normal file
View File

@@ -0,0 +1,82 @@
*
* GR test program
*
* (c) 2016, Brutal Deluxe Software
* http://www.brutaldeluxe.fr/
*
* Use them at your own risk ;-)
*
mx %11
org $300
lst off
*---------- Entry point
KBD = $C000
KBDSTROBE = $C010
*---------- Driver equates
GROn = $1800 ; Turn DGR on
GROff = GROn+3 ; Turn DGR off
GRClear = GROff+3 ; Clear screen
GRPutPixel = GRClear+3 ; Draw a pixel on screen
GRPutPixel2 = GRPutPixel+3 ; Alt draw a pixel on screen
GRGetPixel = GRPutPixel2+3 ; Get the color of a pixel on screen
GRGetPixel2 = GRGetPixel+3 ; Alt get the color of a pixel on screen
GRSetColor = GRGetPixel2+3 ; Set the pen color
GRSetXY = GRSetColor+3 ; Set X1/Y1 coordinates
GRSetXY2 = GRSetXY+3 ; Set X2/Y2 coordinates
GRSetPage = GRSetXY2+3 ; Set page1/page2 data
GRDrawHLine = GRSetPage+3 ; Draw an horizontal line
GRDrawHLine2 = GRDrawHLine+3 ; Alt draw an horizontal line
GRDrawVLine = GRDrawHLine2+3 ; Draw a vertical line
GRDrawVLine2 = GRDrawVLine+3 ; Alt draw a vertical line
*---------- The code
jsr GROn ; Turn DGR on
lda #$00 ; Set color to black
sta theCOLOR
clearLOOP lda theCOLOR ; Please erase the screen
jsr GRClear
]lp lda KBD ; Wait for a keypress
bpl ]lp
bit KBDSTROBE
inc theCOLOR ; Next color, please
lda theCOLOR ; There are 16 of them
cmp #16
bne clearLOOP
*--- Test 2
ldx #0
ldy #0
jsr GRSetXY
lda #6
ldx #39
ldy #0
jsr GRDrawHLine
ldx #39
ldy #0
jsr GRSetXY
lda #6
ldx #39
ldy #47
jsr GRDrawVLine
jsr $fd0c
jsr GROff ; Turn DGR off
rts ; Exit
*--- My test data
theCOLOR ds 1