mirror of
https://github.com/antoinevignau/source.git
synced 2024-11-15 13:05:18 +00:00
de8cad5750
How to detect & use the 4play peripheral card
450 lines
13 KiB
ArmAsm
450 lines
13 KiB
ArmAsm
*
|
|
* 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 \
|
|
|