How to read/write from/to VDC:
$D600 – address/status register – set number of VDC address/register, then:
wait:
BIT $D600 ;bit 7 indicates if is VDC ready to access
BPL wait ; if it's not ready try again
$D601 – data register – here are values to read/write from/to VDC register which is in $D600
- after reading or writting is auto - increment of address/register
And how to do it in BASIC V7?
Write:
BANK15
SYS DEC("CDCC"), value, register
or
BANK15
SYS 52684, value, register
where register is the number (0-36) of the internal VDC register you wish to access, and value is the value (0-255) you wish to place in that register.
To read the contents of an internal VDC register from BASIC, use a statement of the form:
BANK15
SYS DEC("CDDA"),, register : RREG A
or
BANK15
SYS 52698,, register : RREG A
Size of VDC-RAM:
Here's program to detect size of VDC-RAM:
1 rem fred's nifty program to determine size of 8563 dram
5 w=dec("cdcc"):r=dec("cdda")
10 bank15: ad=dec("d600"): da=ad+1 :rem setup ml
20 pokead,28: s=peek(da): pokeda,63 :rem select 64k
30 i=16896: sysw,i/256,18:sysw,iand255,19:sysw,85,31 :rem write $55
40 i=16896: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc1 :rem read here
50 i=17152: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc2 :rem and here
60 i=16896: sysw,i/256,18:sysw,iand255,19:sysw,170,31 :rem write $aa
70 i=16896: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc3 :rem read here
80 i=17152: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc4 :rem and here
90 pokead,28: pokeda,s:sysdec("ff62") :rem restore 16/64k
95 print chr$(14)chr$(147)
100 if c1=c2 and c3=c4 then print "16K": else print"64K" :rem did it echo?
110 end
But also exists more easily method:
SYS52698,,28 : RREGA = 64kB=63/16kB=47
Also detect of chip type and its size:
- register 28/$1C bit 4:
4164 RAM chip (1 × 64kb) or 4416 RAM chip (4 × 16kB)
- size of VDC-RAM:
0 = 16kB
1 = 64kB
Size of VDC-RAM in C64 mode:
;set VDC to 64K mode
0C000 A2 1C LDX #$1C ;charset / RAM register
0C002 20 90 C0 JSR $C090 ;read register
0C005 09 10 ORA #$10 ;assume 64K size
0C007 20 82 C0 JSR $C082 ;write register
;write 0 to address $0000
0C00A A2 12 LDX #$12 ;RAM address hi register
0C00C A9 00 LDA #$00 ;value/address
0C00E 20 82 C0 JSR $C082 ;write register hi
0C011 E8 INX
0C012 20 82 C0 JSR $C082 ;write register lo
0C015 20 80 C0 JSR $C080 ;write zero into RAM
;write $FF to address $8000
0C018 A2 12 LDX #$12 ;RAM address hi register
0C01A A9 80 LDA #$80 ;address hi
0C01C 20 82 C0 JSR $C082 ;write register hi
0C01F E8 INX
0C020 A9 00 LDA #$00 ;address low
0C022 20 82 C0 JSR $C082 ;write register lo
0C025 A9 FF LDA #$FF ;value
0C027 20 80 C0 JSR $C080 ;write $FF into RAM
;get back RAM from $0000
0C02A A2 12 LDX #$12 ;RAM register hi address
0C02C A9 00 LDA #$00 ;address
0C02E 20 82 C0 JSR $C082 ;write register lo
0C031 E8 INX
0C032 20 82 C0 JSR $C082 ;write register hi
0C035 20 8E C0 JSR $C08E ;read RAM at $0000
0C038 8D 46 C0 STA $C046 ;save in +49222
0C03B 60 RTS
;empty space here...
;VDC write routines taken from C128 Editor ROM
0C080 A2 1F LDX #$1F
0C082 8E 00 D6 STX $D600
0C085 2C 00 D6 BIT $D600
0C088 10 FB BPL $C085
0C08A 8D 01 D6 STA $D601
0C08D 60 RTS
;VDC read routines
0C08E A2 1F LDX #$1F
0C090 8E 00 D6 STX $D600
0C093 2C 00 D6 BIT $D600
0C096 10 FB BPL $C093
0C098 AD 01 D6 LDA $D601
0C09B 60 RTS
SYS49152:?PEEK(49222) where:
0 = 64kB
<>0 = 16kB
VDC registers are working in the same style like in C128 mode.
KERNAL routine PLOT ($FFF0) in 80 columns mode:
mmuhi=$ff00 ;MMU config
bsout=$ffd2 ;output primitive
plot=$fff0 ;position cursor
;
*=$2000 ;assemble at 8192
;
lda #%00001110
sta mmuhi ;map in kernel ROM
ldx #10 ;row
ldy #45 ;column
clc
jsr plot ;position
bcs error ;coordinates out of range
;
lda #'A'
jsr bsout ;print char
rts
Properties of 80 columns text:
First codes to upper/lower case:
CHR$(14) = to lower case
CHR$(142) = to upper case
Attribute of current VDC-character:
POKE241,X
bity:
-7-/-6-/-5-/-4-/-3-0
LCASE/RVS/UNDERLINE/FLASH/COLOR
128/64/32/16/0-15
VDC colors using following scheme:
bit 3 = RED
bit 2 = GREEN
bit 1 = BLUE
bit 0 = INTENSITY
...and codes of colors are:
00 = dark black
01 = light black (dark gray)
02 = dark blue
03 = light blue
04 = dark green
05 = light green
06 = dark cyan
07 = light cyan
08 = dark red
09 = light red
10 = dark purple
11 = light purple
12 = dark yellow
13 = light yellow
14 = dark white (light gray)
15 = light white
Copying charset to VDC-RAM:
C128 has routine in ROM.
It copies the Charset to the VDC.
It is at $CE0C.
Just replace the write (JSR $CDCA) with your own.
Please keep in mind that a VDC character is 16 bytes high,
so you can strip the additional 8 byte copy at $CE32.
VDC screen SAVE/LOAD to/from VDC unused area (cache):
vdc_prepare:
lda #$12
sta vdcstatus
lda hibyte
sta vdc_rw
lda #$13
sta vdcstatus
lda lobyte
sta vdc_rw
lda #$1f
sta vdcstatus
rts
vdc_write:
notyet: bit vdcstatus
bpl notyet
sta vdc_rw // writting to VDC
rts
vdc_read:
notyet1:bit vdcstatus
bpl notyet1
lda vdc_rw // reading from VDC
rts
vdc_save:
ldx #$00
ldy #$10
stx x_w
sty y_w
ldx #$00
ldy #$00
citaj: stx x_r
sty y_r
stx lobyte
sty hibyte
jsr vdc_prepare
jsr vdc_read
sta temp
ldx x_w
stx lobyte
ldy y_w
sty hibyte
jsr vdc_prepare
lda temp
jsr vdc_write
inx
stx x_r
stx x_w
ldy y_r
cpx #$00
bne citaj
ldy y_w
iny
sty y_w
tya
and #$0f
tay
sty y_r
cpy #$00
beq done
jmp citaj
done: rts
vdc_load:
ldx #$00
ldy #$00
stx x_w
sty y_w
ldx #$00
ldy #$10
citaj1: stx x_r
sty y_r
stx lobyte
sty hibyte
jsr vdc_prepare
jsr vdc_read
sta temp
ldx x_w
stx lobyte
ldy y_w
sty hibyte
jsr vdc_prepare
lda temp
jsr vdc_write
inx
stx x_r
stx x_w
ldy y_r
cpx #$00
bne citaj1
ldy y_r
iny
sty y_r
tya
and #$0f
tay
sty y_w
cpy #$00
beq done1
ldy y_r
jmp citaj1
done1: rts
Backup of VDC screen to unused VDC area:
by Payton Byrd (Copyright, used in CBM-Command)
;/**************************************************************
;Copyright (c) 2010, Payton Byrd
;All rights reserved.
;
;Redistribution and use in source and binary forms, with or
;without modification, are permitted provided that the following
;conditions are met:
;
;* Redistributions of source code must retain the above
; copyright notice, this list of conditions and the following
; disclaimer.
;
;* Redistributions in binary form must reproduce the above
; copyright notice, this list of conditions and the following
; disclaimer in the documentation and/or other materials
; provided with the distribution.
;
;* Neither the name of Payton Byrd nor the names of its
; contributors may be used to endorse or promote products
; derived from this software without specific prior written
; permission.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
;CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
;INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
;MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
;CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
;SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
;NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
;HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
;CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
;OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
;EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;***************************************************************/
.setcpu "6502"
.smart on
.autoimport on
.case on
.importzp sp, sreg, regsave, regbank, tmp1, ptr1, ptr2
.macpack longbranch
.export _writeVdcRegister
.export _readVdcRegister
.export _clearVdcScreen
.export _copyVdcScreen ; void copyScreen(
; unsigned char srcHi,
; unsigned char trgHi)
READ: STA $D600 ; Put the value into the register
RVR1: BIT $D600 ; Compare the top bit of the register
BPL RVR1 ; Branch if the top bit is low (0)
LDA $D601 ; Get the result into the accumulator
RTS
WRITE: STX $D600 ; Put the value into the register
WVR1: BIT $D600 ; Compare the top bit of the register
BPL WVR1 ; Branch if the top bit is low (0)
STA $D601 ; Store the accumulator in the register's value
RTS
.proc _copyVdcScreen
JSR pusha ; Store the accumulator
; Write target address
LDY #$00 ; Offset for second of two parameters
LDA (sp),y ; Load accumulator with parameter value
LDX #18
JSR WRITE ; Writes accumulator to register 18
LDA #00 ; Low bytes are at location 00
INX ; Next register
JSR WRITE ; Writes accumulator to register 19
; Issue block copy command
LDX #24 ; Get value of register 24
LDA #128 ; Set bit 7 hi
JSR WRITE ; Write register 24
; Write source address
LDY #$01 ; Offset for first of two parameters
LDA (sp),y ; Load accumulator with parameter value
LDX #32
JSR WRITE ; Writes accumulator to register 18
LDA #00 ; Low bytes are at location 00
INX ; Next register
JSR WRITE ; Writes accumulator to register 19
; Set block size
LDX #30 ; block size register
LDA #$00 ; Full block size of 256 bytes
JSR WRITE
; Loop until executed 16 times
LDY #$10 ; Copy 16 blocks
CLRPAG: JSR WRITE
DEY
BNE CLRPAG
; We're done, clean up
JSR incsp2
RTS
.endproc
.proc _clearVdcScreen
JSR pusha ; Store the accumulator
; Set the start location
LDY #$01 ; Offset for first of two parameters
LDA (sp),y ; Load accumulator with parameter value
LDX #18
JSR WRITE ; Writes accumulator to register 18
LDY #$00 ; Offset for the second of two parameters
LDA (sp),y ; Store the parameter in the accumulator
INX ; Now we are on register 19
JSR WRITE ; Write the accumulator to register 19
; Set address to clear
LDX #18
LDA #00
JSR WRITE
INX
JSR WRITE
; Clear the copy bit && Reverse Bit
LDX #24 ; Located in register 24
;JSR READ ; Read it to accumulator
;AND #$7F ; OR the accumulator
LDA #$00
JSR WRITE ; Write it back
; Set data byte
LDX #31 ; Located in register 31
JSR WRITE ; Set the register
LDX #30 ; Word count register?
LDA #$00
JSR WRITE
LDY #$10
LDA #00
CLRPAG: JSR WRITE
DEY
BNE CLRPAG
JSR incsp2
RTS
.endproc
;------------------------
; Write A to VDC Register
; stored in X
.proc _writeVdcRegister
JSR pusha ; Store the accumulator
LDY #$01 ; Offset for first of two parameters
LDA (sp),y ; Load accumulator with parameter value
TAX ; Copy accumulator to x
LDY #$00 ; Offset for the second of two parameters
LDA (sp),y ; Store the parameter in the accumulator
JSR WRITE
JSR incsp2 ; Finish our function
RTS
.endproc
;-------------------------
; Read A from VDC Register
; stored in X
.proc _readVdcRegister
JSR pusha ; Store the accumulator
LDY #$00 ; Offset for the parameter
LDA (sp),y ; Store the parameter in the accumulator
JSR READ
JSR incsp1 ; Increment the stack pointer by 1
RTS ; as the return value of the function?
.endproc
Interlaced VDC TEXT/BITMAP:
---------------------------------------------------------------------------
Interlaced Text
1 REM 80X50 TEXT SCREEN F.BOWEN 9/88
10 SYSDEC("CDCC"),DEC("34"),4
20 SYSDEC("CDCC"),DEC("32"),6
30 SYSDEC("CDCC"),DEC("33"),7
40 SYSDEC("CDCC"),3 ,8
50 SYSDEC("CDCC"),DEC("EA"),9
55 : rem Double screen & attribute areas and clear them
60 POKEDEC("A2F"),16:SYSDEC("CDCC"),16,20
70 POKEDEC("A2E"),8 :SYSDEC("CDCC"),8, 12:SCNCLR
80 POKEDEC("A2E"),0 :SYSDEC("CDCC"),0, 12:SCNCLR
90 LIST
---------------------------------------------------------------------------
Interlaced Bitmap
100 REM 640X480 BMM (REQ. 64K VIDEO RAM!) F.BOWEN 9/88
110 :
120 FAST: TRAP410
130 SYSDEC("CDCC"),DEC("7E"),0
140 SYSDEC("CDCC"),DEC("50"),1
150 SYSDEC("CDCC"),DEC("66"),2
160 SYSDEC("CDCC"),DEC("4C"),4
170 SYSDEC("CDCC"),6 ,5
180 SYSDEC("CDCC"),DEC("4C"),6
190 SYSDEC("CDCC"),DEC("47"),7
200 SYSDEC("CDCC"),3 ,8
210 SYSDEC("CDCC"),6 ,9
220 SYSDEC("CDCC"),0 ,24
230 SYSDEC("CDCC"),128+7 ,25
240 SYSDEC("CDCC"),0 ,27
250 SYSDEC("CDCC"),16 ,28
260 SYSDEC("CDCC"),0,12 :SYSDEC("CDCC"),0,13 :SYSDEC("CDCC"),240,26
270 : rem Clear the bitmap using block fills
280 SYSDEC("CDCC"),0,18 :SYSDEC("CDCC"),0,19 :SYSDEC("CDCC"),0,31
290 FORI=0TO255:SYSDEC("CDCC"),0,30 :NEXT
300 : rem Draw a box around the border, rendering into odd & even frames
310 FORI=1TO480/2: EVEN=0+I*80-1: EH=INT(EV/256):EW=(EV-EH*256)
320 : ODD=21360+I*80-1:OH=INT(OD/256):OL=(OD-OH*256)
330 :SYSDEC("CDCC"),OH,18:SYSDEC("CDCC"),OL,19:SYSDEC("CDCA"),1:SYSDEC("CDCA"),
128
340 :SYSDEC("CDCC"),EH,18:SYSDEC("CDCC"),EW,19:SYSDEC("CDCA"),1:SYSDEC("CDCA"),
128
350 :NEXT
360 SYSDEC("CDCC"),0,18:SYSDEC("CDCC"),0,19
370 SYSDEC("CDCC"),255,31 :SYSDEC("CDCC"),79,30: rem use block fill for top of box
380 SYSDEC("CDCC"),OH,18:SYSDEC("CDCC"),OL+1,19
390 SYSDEC("CDCC"),255,31 :SYSDEC("CDCC"),79,30: rem ditto for bottom of box
400 GETKEYA$
410 SYSDEC("E179") :SYSDEC("FF62"): SCNCLR : rem restore screen, d/l chr def's