1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-02 00:41:42 +00:00
kickc/src/test/ref/c64dtv-8bppchunkystretch.asm
2023-04-23 10:09:42 +02:00

372 lines
9.6 KiB
NASM

// C64DTV 8bpp charmode stretcher
/// @file
/// C64 DTV version 2 Registers and Constants
///
/// Sources
/// (J) https://www.c64-wiki.com/wiki/C64DTV_Programming_Guide
/// (H) http://dtvhacking.cbm8bit.com/dtv_wiki/images/d/d9/Dtv_registers_full.txt
// Commodore 64 PRG executable file
.file [name="c64dtv-8bppchunkystretch.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
/// $D011 Control Register #1 Bit#6: ECM Turn Extended Color Mode on/off
.const VICII_ECM = $40
/// $D011 Control Register #1 Bit#4: DEN Switch VIC-II output on/off
.const VICII_DEN = $10
/// $D011 Control Register #1 Bit#3: RSEL Switch betweem 25 or 24 visible rows
/// RSEL| Display window height | First line | Last line
/// ----+--------------------------+-------------+----------
/// 0 | 24 text lines/192 pixels | 55 ($37) | 246 ($f6)
/// 1 | 25 text lines/200 pixels | 51 ($33) | 250 ($fa)
.const VICII_RSEL = 8
/// $D016 Control register #2 Bit#4: MCM Turn Multicolor Mode on/off
.const VICII_MCM = $10
/// $D016 Control register #2 Bit#3: CSEL Switch betweem 40 or 38 visible columns
/// CSEL| Display window width | First X coo. | Last X coo.
/// ----+--------------------------+--------------+------------
/// 0 | 38 characters/304 pixels | 31 ($1f) | 334 ($14e)
/// 1 | 40 characters/320 pixels | 24 ($18) | 343 ($157)
.const VICII_CSEL = 8
/// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
.const PROCPORT_DDR_MEMORY_MASK = 7
/// RAM in 0xA000, 0xE000 I/O in 0xD000
.const PROCPORT_RAM_IO = 5
.const DTV_FEATURE_ENABLE = 1
.const DTV_LINEAR = 1
.const DTV_HIGHCOLOR = 4
.const DTV_COLORRAM_OFF = $10
.const DTV_BADLINE_OFF = $20
.const DTV_CHUNKY = $40
.const OFFSET_STRUCT_MOS6526_CIA_PORT_A_DDR = 2
/// $D012 RASTER Raster counter
.label RASTER = $d012
/// $D020 Border Color
.label BORDER_COLOR = $d020
/// $D011 Control Register #1
/// - Bit#0-#2: YSCROLL Screen Soft Scroll Vertical
/// - Bit#3: RSEL Switch betweem 25 or 24 visible rows
/// RSEL| Display window height | First line | Last line
/// ----+--------------------------+-------------+----------
/// 0 | 24 text lines/192 pixels | 55 ($37) | 246 ($f6)
/// 1 | 25 text lines/200 pixels | 51 ($33) | 250 ($fa)
/// - Bit#4: DEN Switch VIC-II output on/off
/// - Bit#5: BMM Turn Bitmap Mode on/off
/// - Bit#6: ECM Turn Extended Color Mode on/off
/// - Bit#7: RST8 9th Bit for $D012 Rasterline counter
/// Initial Value: %10011011
.label VICII_CONTROL1 = $d011
/// $D016 Control register 2
/// - Bit#0-#2: XSCROLL Screen Soft Scroll Horizontal
/// - Bit#3: CSEL Switch betweem 40 or 38 visible columns
/// CSEL| Display window width | First X coo. | Last X coo.
/// ----+--------------------------+--------------+------------
/// 0 | 38 characters/304 pixels | 31 ($1f) | 334 ($14e)
/// 1 | 40 characters/320 pixels | 24 ($18) | 343 ($157)
/// - Bit#4: MCM Turn Multicolor Mode on/off
/// - Bit#5-#7: not used
/// Initial Value: %00001000
.label VICII_CONTROL2 = $d016
/// $D018 VIC-II base addresses
/// - Bit#0: not used
/// - Bit#1-#3: CB Address Bits 11-13 of the Character Set (*2048)
/// - Bit#4-#7: VM Address Bits 10-13 of the Screen RAM (*1024)
/// Initial Value: %00010100
.label VICII_MEMORY = $d018
/// Processor port data direction register
.label PROCPORT_DDR = 0
/// Processor Port Register controlling RAM/ROM configuration and the datasette
.label PROCPORT = 1
/// The CIA#2: Serial bus, RS-232, VIC memory bank
.label CIA2 = $dd00
/// Feature enables or disables the extra C64 DTV features
.label DTV_FEATURE = $d03f
/// Controls the graphics modes of the C64 DTV
.label DTV_CONTROL = $d03c
/// Defines colors for the 16 first colors ($00-$0f)
.label DTV_PALETTE = $d200
/// Linear Graphics Plane B Counter Control
.label DTV_PLANEB_START_LO = $d049
.label DTV_PLANEB_START_MI = $d04a
.label DTV_PLANEB_START_HI = $d04b
.label DTV_PLANEB_STEP = $d04c
.label DTV_PLANEB_MODULO_LO = $d047
.label DTV_PLANEB_MODULO_HI = $d048
// Plane with all pixels
.label CHUNKY = $8000
.segment Code
main: {
// asm
sei
// *PROCPORT_DDR = PROCPORT_DDR_MEMORY_MASK
// Disable normal interrupt (prevent keyboard reading glitches and allows to hide basic/kernal)
// Disable kernal & basic
lda #PROCPORT_DDR_MEMORY_MASK
sta.z PROCPORT_DDR
// *PROCPORT = PROCPORT_RAM_IO
lda #PROCPORT_RAM_IO
sta.z PROCPORT
// gfx_init_chunky()
jsr gfx_init_chunky
// *DTV_FEATURE = DTV_FEATURE_ENABLE
// Enable DTV extended modes
lda #DTV_FEATURE_ENABLE
sta DTV_FEATURE
// *DTV_CONTROL = DTV_HIGHCOLOR | DTV_LINEAR | DTV_COLORRAM_OFF | DTV_CHUNKY | DTV_BADLINE_OFF
// 8BPP Pixel Cell Mode
lda #DTV_HIGHCOLOR|DTV_LINEAR|DTV_COLORRAM_OFF|DTV_CHUNKY|DTV_BADLINE_OFF
sta DTV_CONTROL
// *VICII_CONTROL1 = VICII_DEN | VICII_ECM | VICII_RSEL | 3
lda #VICII_DEN|VICII_ECM|VICII_RSEL|3
sta VICII_CONTROL1
// *VICII_CONTROL2 = VICII_MCM | VICII_CSEL
lda #VICII_MCM|VICII_CSEL
sta VICII_CONTROL2
// *DTV_PLANEB_START_LO = BYTE0(CHUNKY)
// Plane B: CHUNKY
lda #0
sta DTV_PLANEB_START_LO
// *DTV_PLANEB_START_MI = BYTE1(CHUNKY)
lda #>CHUNKY
sta DTV_PLANEB_START_MI
// *DTV_PLANEB_START_HI = 0
lda #0
sta DTV_PLANEB_START_HI
// *DTV_PLANEB_STEP = 8
lda #8
sta DTV_PLANEB_STEP
// *DTV_PLANEB_MODULO_LO = 0
lda #0
sta DTV_PLANEB_MODULO_LO
// *DTV_PLANEB_MODULO_HI = 0
sta DTV_PLANEB_MODULO_HI
// CIA2->PORT_A_DDR = %00000011
// VIC Graphics Bank
lda #3
sta CIA2+OFFSET_STRUCT_MOS6526_CIA_PORT_A_DDR
// CIA2->PORT_A = %00000011 ^ (byte)((word)CHUNKY/$4000)
// Set VIC Bank bits to output - all others to input
lda #3^CHUNKY/$4000
sta CIA2
// *VICII_MEMORY = (byte)((((word)CHUNKY)&$3fff)/$40) | ((BYTE1(((word)CHUNKY)&$3fff))/4)
// Set VIC Bank
// VIC memory
lda #0
sta VICII_MEMORY
tax
// DTV Palette - Grey Tones
__b1:
// DTV_PALETTE[j] = j
txa
sta DTV_PALETTE,x
// for(byte j : 0..$f)
inx
cpx #$10
bne __b1
__b2:
// asm
// Stabilize Raster
ldx #$ff
rff:
cpx RASTER
bne rff
stabilize:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
cpx RASTER
beq eat+0
eat:
inx
cpx #8
bne stabilize
// *VICII_CONTROL1 = VICII_DEN | VICII_ECM | VICII_RSEL | 3
lda #VICII_DEN|VICII_ECM|VICII_RSEL|3
sta VICII_CONTROL1
// *BORDER_COLOR = 0
lda #0
sta BORDER_COLOR
__b3:
// while(*RASTER!=rst)
lda #$42
cmp RASTER
bne __b3
// asm
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
__b5:
// rst = *RASTER
ldx RASTER
// rst&7
txa
and #7
// VICII_DEN | VICII_ECM | VICII_RSEL | (rst&7)
ora #VICII_DEN|VICII_ECM|VICII_RSEL
// *VICII_CONTROL1 = VICII_DEN | VICII_ECM | VICII_RSEL | (rst&7)
sta VICII_CONTROL1
// rst*$10
txa
asl
asl
asl
asl
// *BORDER_COLOR = rst*$10
sta BORDER_COLOR
// asm
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
// while (rst!=$f2)
cpx #$f2
bne __b5
jmp __b2
}
// Initialize Plane with 8bpp chunky
gfx_init_chunky: {
.label __5 = 6
.label gfxb = 2
.label x = 4
.label y = 8
// dtvSetCpuBankSegment1(gfxbCpuBank++)
lda #CHUNKY/$4000
jsr dtvSetCpuBankSegment1
ldx #($ff&CHUNKY/$4000)+1
lda #0
sta.z y
lda #<$4000
sta.z gfxb
lda #>$4000
sta.z gfxb+1
__b1:
lda #<0
sta.z x
sta.z x+1
__b2:
// if(gfxb==$8000)
lda.z gfxb+1
cmp #>$8000
bne __b3
lda.z gfxb
cmp #<$8000
bne __b3
// dtvSetCpuBankSegment1(gfxbCpuBank++)
txa
jsr dtvSetCpuBankSegment1
// dtvSetCpuBankSegment1(gfxbCpuBank++);
inx
lda #<$4000
sta.z gfxb
lda #>$4000
sta.z gfxb+1
__b3:
// x+y
lda.z y
clc
adc.z x
sta.z __5
lda #0
adc.z x+1
sta.z __5+1
// byte c = (byte)(x+y)
lda.z __5
// *gfxb++ = c
ldy #0
sta (gfxb),y
// *gfxb++ = c;
inc.z gfxb
bne !+
inc.z gfxb+1
!:
// for (word x : 0..319)
inc.z x
bne !+
inc.z x+1
!:
lda.z x+1
cmp #>$140
bne __b2
lda.z x
cmp #<$140
bne __b2
// for(byte y : 0..50)
inc.z y
lda #$33
cmp.z y
bne __b1
// dtvSetCpuBankSegment1((byte)($4000/$4000))
// Reset CPU BANK segment to $4000
lda #$4000/$4000
jsr dtvSetCpuBankSegment1
// }
rts
}
// Set the memory pointed to by CPU BANK 1 SEGMENT ($4000-$7fff)
// This sets which actual memory is addressed when the CPU reads/writes to $4000-$7fff
// The actual memory addressed will be $4000*cpuSegmentIdx
// void dtvSetCpuBankSegment1(__register(A) char cpuBankIdx)
dtvSetCpuBankSegment1: {
// Move CPU BANK 1 SEGMENT ($4000-$7fff)
.label cpuBank = $ff
// *cpuBank = cpuBankIdx
sta.z cpuBank
// asm
.byte $32, $dd
lda.z $ff
.byte $32, 0
// }
rts
}