From 81f2d3f683c25159d8d4de53d66d74657fed8742 Mon Sep 17 00:00:00 2001 From: marcobaye Date: Sun, 28 Jul 2019 22:16:51 +0000 Subject: [PATCH] ACME_Lib: a bit more info on CIAs and VIC git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@114 4df02467-bbd4-4a76-a152-e7ce94205b78 --- ACME_Lib/cbm/c128/vic.a | 17 +++-- ACME_Lib/cbm/c64/cia1.a | 42 ++++++----- ACME_Lib/cbm/c64/cia2.a | 42 +++++------ ACME_Lib/cbm/c64/vic.a | 150 ++++++++++++++++++++++++++-------------- ACME_Lib/cbm/cia.a | 109 +++++++++++++++++++++++++++++ 5 files changed, 261 insertions(+), 99 deletions(-) create mode 100644 ACME_Lib/cbm/cia.a diff --git a/ACME_Lib/cbm/c128/vic.a b/ACME_Lib/cbm/c128/vic.a index 812a2f4..66e65a9 100644 --- a/ACME_Lib/cbm/c128/vic.a +++ b/ACME_Lib/cbm/c128/vic.a @@ -1,19 +1,22 @@ -;ACME 0.95 +;ACME 0.96.4 !ifdef lib_cbm_c128_vic_a !eof lib_cbm_c128_vic_a = 1 !source ; registers 0..2e -!address { ; registers only present in the C128 variant of this chip: - vic_keyboard = $d02f - vic_clock = $d030 + vic_keyboard = vic_base + $2f + ; %76543... always set + ; %.....210 output pins for extended keyboard layout + vic_clock = vic_base + $30 + ; %765432.. always set + ; %......1. "test" bit: 0 = normal, 1 = system clock changes raster line + ; %.......0 system clock: 0 = 1 MHz, 1 = 2 MHz (VIC bus cycles will be given to CPU instead) ; the c128 ROMs contain two copies of a look-up table to convert vic color ; values to their corresponding petscii color codes: ; rom4_* needs "low rom area" enabled ($4000..$7fff) ; romc_* needs "high rom area" enabled ($c000..$ffff) - rom4_vic_to_petscii_color_table = $76b5 ; 90 05 1c 9f 9c 1e 1f 9e 81 95 96 97 98 99 9a 9b - romc_vic_to_petscii_color_table = $ce4c ; 90 05 1c 9f 9c 1e 1f 9e 81 95 96 97 98 99 9a 9b -} +!addr rom4_vic_to_petscii_color_table = $76b5 ; 90 05 1c 9f 9c 1e 1f 9e 81 95 96 97 98 99 9a 9b +!addr romc_vic_to_petscii_color_table = $ce4c ; 90 05 1c 9f 9c 1e 1f 9e 81 95 96 97 98 99 9a 9b diff --git a/ACME_Lib/cbm/c64/cia1.a b/ACME_Lib/cbm/c64/cia1.a index 920bacd..53cdb61 100644 --- a/ACME_Lib/cbm/c64/cia1.a +++ b/ACME_Lib/cbm/c64/cia1.a @@ -1,23 +1,27 @@ -;ACME 0.95 +;ACME 0.96.4 !ifdef lib_cbm_c64_cia1_a !eof lib_cbm_c64_cia1_a = 1 -!address { - cia1_pra = $dc00 - cia1_prb = $dc01 - cia1_ddra = $dc02 - cia1_ddrb = $dc03 - cia1_ta_lo = $dc04 - cia1_ta_hi = $dc05 - cia1_tb_lo = $dc06 - cia1_tb_hi = $dc07 - cia1_tod10ths = $dc08 - cia1_todsec = $dc09 - cia1_todmin = $dc0a - cia1_todhr = $dc0b - cia1_sdr = $dc0c - cia1_icr = $dc0d - cia1_cra = $dc0e - cia1_crb = $dc0f -} +!source ; chip stuff (same for both cias) +; stuff for cia 1 only: +!addr cia1_base = $dc00 + cia1_pra = cia1_base + cia_port_a ; PA0..PA4 are joy port 2 PA6+PA7 select paddle port(s) + cia1_prb = cia1_base + cia_port_b ; PB0..PB4 are joy port 1 + ; both ports are used for keyboard matrix + cia1_ddra = cia1_base + cia_data_direction_a + cia1_ddrb = cia1_base + cia_data_direction_b + cia1_ta_lo = cia1_base + cia_timer_a_low + cia1_ta_hi = cia1_base + cia_timer_a_high + cia1_tb_lo = cia1_base + cia_timer_b_low + cia1_tb_hi = cia1_base + cia_timer_b_high + cia1_tod10ths = cia1_base + cia_timeofday_10ths + cia1_todsec = cia1_base + cia_timeofday_seconds + cia1_todmin = cia1_base + cia_timeofday_minutes + cia1_todhr = cia1_base + cia_timeofday_hours + cia1_sdr = cia1_base + cia_serial_data + cia1_icr = cia1_base + cia_interrupt_control + cia1_cra = cia1_base + cia_control_a + cia1_crb = cia1_base + cia_control_b +; the interrupt output is connected to CPU's /IRQ input +; in the C128, the shift register is used for the fast serial port (burst mode) diff --git a/ACME_Lib/cbm/c64/cia2.a b/ACME_Lib/cbm/c64/cia2.a index cf2690a..bbabba3 100644 --- a/ACME_Lib/cbm/c64/cia2.a +++ b/ACME_Lib/cbm/c64/cia2.a @@ -1,30 +1,32 @@ -;ACME 0.95 +;ACME 0.96.4 !ifdef lib_cbm_c64_cia2_a !eof lib_cbm_c64_cia2_a = 1 -!address { - cia2_pra = $dd00 +!source ; chip stuff (same for both cias) +; stuff for cia 2 only: +!addr cia2_base = $dd00 + cia2_pra = cia2_base + cia_port_a ; %7....... DATA in (0 means GND) ; %.6...... CLK in (0 means GND) ; %..5..... DATA out (inverted, 1 means GND) ; %...4.... CLK out (inverted, 1 means GND) ; %....3... ATN out (inverted, 1 means GND) ; %.....2.. PA2 (pin M at user port, 0 means GND) - ; %......10 VIC bank (inverted, so value $3 means address $0000) - cia2_prb = $dd01 - cia2_ddra = $dd02 - cia2_ddrb = $dd03 - cia2_ta_lo = $dd04 - cia2_ta_hi = $dd05 - cia2_tb_lo = $dd06 - cia2_tb_hi = $dd07 - cia2_tod10ths = $dd08 - cia2_todsec = $dd09 - cia2_todmin = $dd0a - cia2_todhr = $dd0b - cia2_sdr = $dd0c - cia2_icr = $dd0d - cia2_cra = $dd0e - cia2_crb = $dd0f -} + ; %......10 VIC bank (inverted, so value %11 means address $0000) + cia2_prb = cia2_base + cia_port_b + cia2_ddra = cia2_base + cia_data_direction_a + cia2_ddrb = cia2_base + cia_data_direction_b + cia2_ta_lo = cia2_base + cia_timer_a_low + cia2_ta_hi = cia2_base + cia_timer_a_high + cia2_tb_lo = cia2_base + cia_timer_b_low + cia2_tb_hi = cia2_base + cia_timer_b_high + cia2_tod10ths = cia2_base + cia_timeofday_10ths + cia2_todsec = cia2_base + cia_timeofday_seconds + cia2_todmin = cia2_base + cia_timeofday_minutes + cia2_todhr = cia2_base + cia_timeofday_hours + cia2_sdr = cia2_base + cia_serial_data + cia2_icr = cia2_base + cia_interrupt_control + cia2_cra = cia2_base + cia_control_a + cia2_crb = cia2_base + cia_control_b +; the interrupt output is connected to CPU's /NMI input diff --git a/ACME_Lib/cbm/c64/vic.a b/ACME_Lib/cbm/c64/vic.a index 6c840d8..2da0288 100644 --- a/ACME_Lib/cbm/c64/vic.a +++ b/ACME_Lib/cbm/c64/vic.a @@ -1,8 +1,25 @@ -;ACME 0.95 +;ACME 0.96.4 !ifdef lib_cbm_c64_vic_a !eof lib_cbm_c64_vic_a = 1 +; This is from Christian Bauer's VIC text: { +; 6566: designed for static RAM, never used in C64/128 +; 6567/8562: C64, NTSC +; 6569/8565: C64, PAL +; 6572: Drean C64, PAL-N +; 8564: C128, NTSC +; 8566: C128, PAL +; PAL chips generate 312 lines with 63 cycles per line. +; PAL-N chips generate 312 lines with 65 cycles per line. +; NTSC chips generate 263 lines with 65 cycles per line. +; Very early NTSC chips (6567R56A) have an off-by-one +; error, they generate 262 lines with 64 cycles per line. +; } + +; The c128 version is officially called "VIC-IIe". +; It has two additional registers and more pins. + ; color codes viccolor_BLACK = $0 viccolor_WHITE = $1 @@ -21,58 +38,85 @@ viccolor_LGREEN = $d viccolor_LBLUE = $e viccolor_GRAY3 = $f -!address { - ; register addresses - vic_xs0 = $d000 - vic_ys0 = $d001 - vic_xs1 = $d002 - vic_ys1 = $d003 - vic_xs2 = $d004 - vic_ys2 = $d005 - vic_xs3 = $d006 - vic_ys3 = $d007 - vic_xs4 = $d008 - vic_ys4 = $d009 - vic_xs5 = $d00a - vic_ys5 = $d00b - vic_xs6 = $d00c - vic_ys6 = $d00d - vic_xs7 = $d00e - vic_ys7 = $d00f - vic_msb_xs = $d010 - vic_controlv = $d011 ; vertical control (and much other stuff) - vic_line = $d012 ; raster line - vic_xlp = $d013 ; light pen coordinates - vic_ylp = $d014 - vic_sactive = $d015 ; sprites: active - vic_controlh = $d016 ; horizontal control (and much other stuff) - vic_sdy = $d017 ; sprites: double height - vic_ram = $d018 ; RAM pointer - vic_irq = $d019 - vic_irqmask = $d01a - vic_sback = $d01b ; sprites: background mode - vic_smc = $d01c ; sprites: multi color mode - vic_sdx = $d01d ; sprites: double width - vic_ss_collided = $d01e ; sprite-sprite collision detect - vic_sd_collided = $d01f ; sprite-data collision detect - ; color registers - vic_cborder = $d020 ; border color - vic_cbg = $d021 ; general background color - vic_cbg0 = $d021 - vic_cbg1 = $d022 ; background color 1 (for EBC and MC text mode) - vic_cbg2 = $d023 ; background color 2 (for EBC and MC text mode) - vic_cbg3 = $d024 ; background color 3 (for EBC mode) - vic_sc01 = $d025 ; sprite color for MC-bitpattern %01 - vic_sc11 = $d026 ; sprite color for MC-bitpattern %11 - vic_cs0 = $d027 ; individual sprite colors - vic_cs1 = $d028 ; (in MC mode, these are used - vic_cs2 = $d029 ; for bit pattern %10) - vic_cs3 = $d02a - vic_cs4 = $d02b - vic_cs5 = $d02c - vic_cs6 = $d02d - vic_cs7 = $d02e -} +!addr vic_base = $d000 + ; sprite coordinates: + vic_xs0 = vic_base + $00 + vic_ys0 = vic_base + $01 + vic_xs1 = vic_base + $02 + vic_ys1 = vic_base + $03 + vic_xs2 = vic_base + $04 + vic_ys2 = vic_base + $05 + vic_xs3 = vic_base + $06 + vic_ys3 = vic_base + $07 + vic_xs4 = vic_base + $08 + vic_ys4 = vic_base + $09 + vic_xs5 = vic_base + $0a + vic_ys5 = vic_base + $0b + vic_xs6 = vic_base + $0c + vic_ys6 = vic_base + $0d + vic_xs7 = vic_base + $0e + vic_ys7 = vic_base + $0f + vic_msb_xs = vic_base + $10 ; bit 8 of x position (one bit per sprite) + vic_controlv = vic_base + $11 ; vertical control and other stuff: + ; %7....... "bit 8" of $d012 + ; %.6...... extended background color mode (1=on) + ; %..5..... 0 = text mode, 1 = bitmap mode + ; %...4.... display enable: 0 = disable (border only), 1 = enable VIC only checks this once per frame! + ; %....3... lines: 0 = 24, 1 = 25 ; if set, upper and lower border gain 4 pixels each + ; %.....210 vertical smooth scroll (default %011), screen contents are moved down by this amount + vic_line = vic_base + $12 ; raster line (also see bit 7 of $d011) reading returns current value, writing sets interrupt value + vic_xlp = vic_base + $13 ; light pen coordinates, x (only half the resolution) + vic_ylp = vic_base + $14 ; light pen coordinates, y + vic_sactive = vic_base + $15 ; sprite enable (one bit per sprite) + vic_controlh = vic_base + $16 ; horizontal control and other stuff: + ; %76...... always set + ; %..5..... "test", should be 0 + ; %...4.... 0 = hires, 1 = multicolor + ; %....3... columns: 0 = 38, 1 = 40 ; if set, left border gains 7 pixels and right border gains 9 pixels + ; %.....210 horizontal smooth scroll (default %000), screen contents are moved to the right by this amount + vic_sdy = vic_base + $17 ; sprites, double height (one bit per sprite) + vic_ram = vic_base + $18 ; RAM pointer + ; %7654.... which K of VIC bank is video ram (default %0001) + ; %....321. text: which 2K of VIC bank is character set (default %010) + ; %.......0 text: unused + ; %....3... bitmap: which 8K of VIC bank is bitmap + ; %.....210 bitmap: unused + vic_irq = vic_base + $19 ; writing back acknowledges! + ; %7....... 1: VIC requested interrupt + ; %.654.... always set + ; %....3... 1: light pen active + ; %.....2.. 1: sprite-sprite collision + ; %......1. 1: sprite-data collision + ; %.......0 1: raster interrupt + vic_irqmask = vic_base + $1a + ; %7654.... always set + ; %....3... 1: enable lightpen interrupt + ; %.....2.. 1: enable sprite-sprite collision interrupt + ; %......1. 1: enable sprite-data collision interrupt + ; %.......0 1: enable raster interrupt + vic_sback = vic_base + $1b ; sprites, background (one bit per sprite) + vic_smc = vic_base + $1c ; sprites, multicolor (one bit per sprite) + vic_sdx = vic_base + $1d ; sprites, double width (one bit per sprite) + vic_ss_collided = vic_base + $1e ; sprites, sprite collision (one bit per sprite) reading clears register! + vic_sd_collided = vic_base + $1f ; sprites, data collision (one bit per sprite) reading clears register! + ; color registers (high nibbles are always %1111): + vic_cborder = vic_base + $20 ; border color + vic_cbg = vic_base + $21 ; general background color + vic_cbg0 = vic_base + $21 + vic_cbg1 = vic_base + $22 ; background color 1 (for EBC and MC text mode) + vic_cbg2 = vic_base + $23 ; background color 2 (for EBC and MC text mode) + vic_cbg3 = vic_base + $24 ; background color 3 (for EBC mode) + vic_sc01 = vic_base + $25 ; sprite color for MC-bitpattern %01 + vic_sc11 = vic_base + $26 ; sprite color for MC-bitpattern %11 + ; individual sprite colors (in MC mode, these are used for bit pattern %10): + vic_cs0 = vic_base + $27 ; sprite 0 color + vic_cs1 = vic_base + $28 ; sprite 1 color + vic_cs2 = vic_base + $29 ; sprite 2 color + vic_cs3 = vic_base + $2a ; sprite 3 color + vic_cs4 = vic_base + $2b ; sprite 4 color + vic_cs5 = vic_base + $2c ; sprite 5 color + vic_cs6 = vic_base + $2d ; sprite 6 color + vic_cs7 = vic_base + $2e ; sprite 7 color ; See for the C128's two additional registers at $d02f/$d030. ; They are accessible even in C64 mode and $d030 can garble the video output, ; so be careful not to write to it accidentally in a C64 program! diff --git a/ACME_Lib/cbm/cia.a b/ACME_Lib/cbm/cia.a new file mode 100644 index 0000000..c503b5c --- /dev/null +++ b/ACME_Lib/cbm/cia.a @@ -0,0 +1,109 @@ +;ACME 0.96.4 + +!ifdef lib_cbm_cia_a !eof +lib_cbm_cia_a = 1 + +; CBM's "complex interface adapter" chip, known as 6526. +; A newer version of this chip was initially called 8521, but later the name was +; changed back to 6526 again. + +; There are two of these in a C64/128 computer, and one in 1570/1571 drives. + +; pinout: +; ____ ____ +; | V | +; GND | 1 40 | cnt clock for shift register +; / pa0 | 2 39 | sp data for shift register +; | pa1 | 3 38 | a0 \ +; | pa2 | 4 37 | a1 |_ address +; Port _| pa3 | 5 36 | a2 | bus +; A | pa4 | 6 35 | a3 / +; | pa5 | 7 34 | /reset +; | pa6 | 8 33 | d0 \ +; \ pa7 | 9 32 | d1 | +; / pb0 | 10 31 | d2 | +; | pb1 | 11 30 | d3 |_ data +; | pb2 | 12 29 | d4 | bus +; Port _| pb3 | 13 28 | d5 | +; B | pb4 | 14 27 | d6 | +; | pb5 | 15 26 | d7 / +; | pb6 | 16 25 | 0in clock +; \ pb7 | 17 24 | /flag +; /pc | 18 23 | /cs chip select +; tod_clk | 19 22 | r/w +; +5V | 20 21 | /irq +; |_________| + + +; register offsets: + ; two 8-bit ports: + cia_port_a = $0 + cia_port_b = $1 + cia_data_direction_a = $2 ; clear means input, + cia_data_direction_b = $3 ; set means output + + ; two 16-bit timers, can be combined to form a single 32-bit timer: + cia_timer_a_low = $4 + cia_timer_a_high = $5 + cia_timer_b_low = $6 + cia_timer_b_high = $7 + ; reading returns current counter value, + ; writing sets start value. + ; in 32-bit mode, timer A is "low word" and timer B is "high word". + + ; TOD (time of day) clock, clocked with 50 or 60 Hz: + ; (CAUTION, registers use binary coded decimal format) + cia_timeofday_10ths = $8 ; %....3210 0..9, counts 10ths of seconds + cia_timeofday_seconds = $9 ; %.6543210 0..59, as two BCD digits: + ; %.654.... 0..5 "tens" + ; %....3210 0..9 "ones" + cia_timeofday_minutes = $a ; %.6543210 0..59, as two BCD digits: + ; %.654.... 0..5 "tens" + ; %....3210 0..9 "ones" + cia_timeofday_hours = $b ; %7..43210 AM/PM and 1..12 as two BCD digits: + ; %7....... 0 means AM, 1 means PM + ; %...4.... 0..1 "tens" + ; %....3210 0..9 "ones" + ; when reading or writing time, start with hours and end with 10ths: + ; accessing hours uncouples registers from clock, accessing 10ths re-couples them. + ; if your read access does not start with the hours register, + ; you have a race condition! + + ; shift register: + ; msb is sent/received first. send clock is half of timer A's underflow rate. + cia_serial_data = $c + + ; control registers: + cia_interrupt_control = $d + ; %7....... read: 1 = interrupt requested + ; write: 0 = disable interrupts indicated by set bits + ; 1 = enable interrupts indicated by set bits + ; %.65..... unused + ; %...4.... negative edge on /flag detected + ; %....3... shift register has finished sending or receiving + ; %.....2.. time of day alarm + ; %......1. timer B underflow + ; %.......0 timer A underflow + + cia_control_a = $e + ; %7....... TOD clock: 0 means 60 Hz, 1 means 50 Hz + ; %.6...... shift register direction: 0 = input, 1 = output + ; %..5..... timer A clock: 0 = system clock, 1 = CNT + ; %...4.... 1 = force load timer start value + ; %....3... timer mode: 0 = continuous, 1 = one-shot (needs restart via bit 0) + ; %.....2.. 0 = pulse on PB6, 1 = invert PB6 + ; %......1. 1 = timer underflow shows on PB6 (this forces PB6 to output) + ; %.......0 0 stops timer, 1 starts timer + + cia_control_b = $f + ; %7....... TOD write mode: 0 = actual time, 1 = alarm time (it is not possible to _read_ the alarm time!) + ; %.65..... timer B clock: + ; %00 = system clock + ; %01 = CNT + ; %10 = underflow of timer A + ; %11 = combination of %01 and %10 + ; %...4.... 1 = force load timer start value + ; %....3... timer mode: 0 = continuous, 1 = one-shot (needs restart via bit 0) + ; %.....2.. 0 = pulse on PB7, 1 = invert PB7 + ; %......1. 1 = timer underflow shows on PB7 (this forces PB7 to output) + ; %.......0 0 stops timer, 1 starts timer