1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +00:00

Added doxygen standard library documentation. #672

This commit is contained in:
jespergravgaard 2021-06-19 20:49:14 +02:00
parent 8a0d9d3708
commit 9408902136
69 changed files with 22500 additions and 19857 deletions

View File

@ -24,3 +24,14 @@ release:
- ./kickc/LICENSE*
- ./kickc/NOTICE*
- ./kickc/*.pdf
pages:
script:
- apk update && apk add doxygen graphviz ttf-freefont
- doxygen src/main/doxygen/doxygen.conf
- mv target/doxygen/html/ public/
artifacts:
paths:
- public
only:
- feature/add-gitlab-pages-support

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,244 @@
//KICKC FRAGMENT CACHE f6e6ad7e1 f6e6af848
//KICKC FRAGMENT CACHE f6e6ad792 f6e6af7f9
//FRAGMENT vbuzz=vbuc1
ldz #{c1}
//FRAGMENT vbuzz_lt_vbuc1_then_la1
cpz #{c1}
bcc {la1}
//FRAGMENT pbuc1_derefidx_vbuzz=vbuzz
tza
tax
sta {c1},x
//FRAGMENT vbuzz=_inc_vbuzz
inz
//FRAGMENT vbsz1=_deref_pbsc1
lda {c1}
sta {z1}
//FRAGMENT vbsz1=_neg_vbsz2
lda {z2}
neg
sta {z1}
//FRAGMENT _deref_pbsc1=vbsz1
lda {z1}
sta {c1}
//FRAGMENT vbsz1=vbsz2_ror_2
lda {z2}
asr
asr
sta {z1}
//FRAGMENT vbsaa=_deref_pbsc1
lda {c1}
//FRAGMENT vbsxx=_deref_pbsc1
ldx {c1}
//FRAGMENT vbsz1=_neg_vbsaa
neg
sta {z1}
//FRAGMENT vbsz1=_neg_vbsxx
txa
neg
sta {z1}
//FRAGMENT vbsz1=_neg_vbsyy
tya
neg
sta {z1}
//FRAGMENT vbsz1=_neg_vbszz
tza
neg
sta {z1}
//FRAGMENT vbsaa=_neg_vbsz1
lda {z1}
neg
//FRAGMENT vbsaa=_neg_vbsaa
neg
//FRAGMENT vbsaa=_neg_vbsxx
txa
neg
//FRAGMENT vbsaa=_neg_vbsyy
tya
neg
//FRAGMENT vbsaa=_neg_vbszz
tza
neg
//FRAGMENT vbsxx=_neg_vbsz1
lda {z1}
neg
tax
//FRAGMENT vbsxx=_neg_vbsaa
neg
tax
//FRAGMENT vbsxx=_neg_vbsxx
txa
neg
tax
//FRAGMENT vbsxx=_neg_vbsyy
tya
neg
tax
//FRAGMENT vbsxx=_neg_vbszz
tza
neg
tax
//FRAGMENT vbsyy=_neg_vbsz1
lda {z1}
neg
tay
//FRAGMENT vbsyy=_neg_vbsaa
neg
tay
//FRAGMENT vbsyy=_neg_vbsxx
txa
neg
tay
//FRAGMENT vbsyy=_neg_vbsyy
tya
neg
tay
//FRAGMENT vbsyy=_neg_vbszz
tza
neg
tay
//FRAGMENT vbszz=_neg_vbsz1
lda {z1}
neg
taz
//FRAGMENT vbszz=_neg_vbsaa
neg
taz
//FRAGMENT vbszz=_neg_vbsxx
txa
neg
taz
//FRAGMENT vbszz=_neg_vbsyy
tya
neg
taz
//FRAGMENT vbszz=_neg_vbszz
tza
neg
taz
//FRAGMENT _deref_pbsc1=vbsaa
sta {c1}
//FRAGMENT vbsz1=vbsaa_ror_2
asr
asr
sta {z1}
//FRAGMENT vbsz1=vbsxx_ror_2
txa
asr
asr
sta {z1}
//FRAGMENT vbsz1=vbsyy_ror_2
tya
asr
asr
sta {z1}
//FRAGMENT vbsz1=vbszz_ror_2
tza
asr
asr
sta {z1}
//FRAGMENT vbsaa=vbsz1_ror_2
lda {z1}
asr
asr
//FRAGMENT vbsaa=vbsaa_ror_2
asr
asr
//FRAGMENT vbsaa=vbsxx_ror_2
txa
asr
asr
//FRAGMENT vbsaa=vbsyy_ror_2
tya
asr
asr
//FRAGMENT vbsaa=vbszz_ror_2
tza
asr
asr
//FRAGMENT vbsxx=vbsz1_ror_2
lda {z1}
asr
asr
tax
//FRAGMENT vbsxx=vbsaa_ror_2
asr
asr
tax
//FRAGMENT vbsxx=vbsxx_ror_2
txa
asr
asr
tax
//FRAGMENT vbsxx=vbsyy_ror_2
tya
asr
asr
tax
//FRAGMENT vbsxx=vbszz_ror_2
tza
asr
asr
tax
//FRAGMENT vbsyy=vbsz1_ror_2
lda {z1}
asr
asr
tay
//FRAGMENT vbsyy=vbsaa_ror_2
asr
asr
tay
//FRAGMENT vbsyy=vbsxx_ror_2
txa
asr
asr
tay
//FRAGMENT vbsyy=vbsyy_ror_2
tya
asr
asr
tay
//FRAGMENT vbsyy=vbszz_ror_2
tza
asr
asr
tay
//FRAGMENT vbszz=vbsz1_ror_2
lda {z1}
asr
asr
taz
//FRAGMENT vbszz=vbsaa_ror_2
asr
asr
taz
//FRAGMENT vbszz=vbsxx_ror_2
txa
asr
asr
taz
//FRAGMENT vbszz=vbsyy_ror_2
tya
asr
asr
taz
//FRAGMENT vbszz=vbszz_ror_2
tza
asr
asr
taz
//FRAGMENT vbsyy=_deref_pbsc1
ldy {c1}
//FRAGMENT vbszz=_deref_pbsc1
lda {c1}
taz
//FRAGMENT _deref_pbsc1=vbsxx
stx {c1}
//FRAGMENT _deref_pbsc1=vbsyy
sty {c1}
//FRAGMENT _deref_pbsc1=vbszz
tza
sta {c1}
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}
@ -1871,8 +2111,6 @@ cpx {z1}
bcs {la1}
//FRAGMENT vbuxx=vbuc1
ldx #{c1}
//FRAGMENT vbuzz=vbuc1
ldz #{c1}
//FRAGMENT vbuzz=vbuz1
ldz {z1}
//FRAGMENT vbuz1=vbuzz
@ -1887,8 +2125,6 @@ inx
ldy #{c1}
//FRAGMENT vbuyy=_inc_vbuyy
iny
//FRAGMENT vbuzz=_inc_vbuzz
inz
//FRAGMENT vbuz1_ge_vbuxx_then_la1
lda {z1}
stx $ff
@ -1945,9 +2181,6 @@ bcc {la1}
cpy #{c1}
bcc {la1}
beq {la1}
//FRAGMENT vbuzz_lt_vbuc1_then_la1
cpz #{c1}
bcc {la1}
//FRAGMENT vbuzz_le_vbuc1_then_la1
cpz #{c1}
bcc {la1}
@ -2174,236 +2407,3 @@ sta {z1}+1
asw {z1}
asw {z1}
asw {z1}
//FRAGMENT pbuc1_derefidx_vbuzz=vbuzz
tza
tax
sta {c1},x
//FRAGMENT vbsz1=_deref_pbsc1
lda {c1}
sta {z1}
//FRAGMENT vbsz1=_neg_vbsz2
lda {z2}
neg
sta {z1}
//FRAGMENT _deref_pbsc1=vbsz1
lda {z1}
sta {c1}
//FRAGMENT vbsz1=vbsz2_ror_2
lda {z2}
asr
asr
sta {z1}
//FRAGMENT vbsaa=_deref_pbsc1
lda {c1}
//FRAGMENT vbsxx=_deref_pbsc1
ldx {c1}
//FRAGMENT vbsz1=_neg_vbsaa
neg
sta {z1}
//FRAGMENT vbsz1=_neg_vbsxx
txa
neg
sta {z1}
//FRAGMENT vbsz1=_neg_vbsyy
tya
neg
sta {z1}
//FRAGMENT vbsz1=_neg_vbszz
tza
neg
sta {z1}
//FRAGMENT vbsaa=_neg_vbsz1
lda {z1}
neg
//FRAGMENT vbsaa=_neg_vbsaa
neg
//FRAGMENT vbsaa=_neg_vbsxx
txa
neg
//FRAGMENT vbsaa=_neg_vbsyy
tya
neg
//FRAGMENT vbsaa=_neg_vbszz
tza
neg
//FRAGMENT vbsxx=_neg_vbsz1
lda {z1}
neg
tax
//FRAGMENT vbsxx=_neg_vbsaa
neg
tax
//FRAGMENT vbsxx=_neg_vbsxx
txa
neg
tax
//FRAGMENT vbsxx=_neg_vbsyy
tya
neg
tax
//FRAGMENT vbsxx=_neg_vbszz
tza
neg
tax
//FRAGMENT vbsyy=_neg_vbsz1
lda {z1}
neg
tay
//FRAGMENT vbsyy=_neg_vbsaa
neg
tay
//FRAGMENT vbsyy=_neg_vbsxx
txa
neg
tay
//FRAGMENT vbsyy=_neg_vbsyy
tya
neg
tay
//FRAGMENT vbsyy=_neg_vbszz
tza
neg
tay
//FRAGMENT vbszz=_neg_vbsz1
lda {z1}
neg
taz
//FRAGMENT vbszz=_neg_vbsaa
neg
taz
//FRAGMENT vbszz=_neg_vbsxx
txa
neg
taz
//FRAGMENT vbszz=_neg_vbsyy
tya
neg
taz
//FRAGMENT vbszz=_neg_vbszz
tza
neg
taz
//FRAGMENT _deref_pbsc1=vbsaa
sta {c1}
//FRAGMENT vbsz1=vbsaa_ror_2
asr
asr
sta {z1}
//FRAGMENT vbsz1=vbsxx_ror_2
txa
asr
asr
sta {z1}
//FRAGMENT vbsz1=vbsyy_ror_2
tya
asr
asr
sta {z1}
//FRAGMENT vbsz1=vbszz_ror_2
tza
asr
asr
sta {z1}
//FRAGMENT vbsaa=vbsz1_ror_2
lda {z1}
asr
asr
//FRAGMENT vbsaa=vbsaa_ror_2
asr
asr
//FRAGMENT vbsaa=vbsxx_ror_2
txa
asr
asr
//FRAGMENT vbsaa=vbsyy_ror_2
tya
asr
asr
//FRAGMENT vbsaa=vbszz_ror_2
tza
asr
asr
//FRAGMENT vbsxx=vbsz1_ror_2
lda {z1}
asr
asr
tax
//FRAGMENT vbsxx=vbsaa_ror_2
asr
asr
tax
//FRAGMENT vbsxx=vbsxx_ror_2
txa
asr
asr
tax
//FRAGMENT vbsxx=vbsyy_ror_2
tya
asr
asr
tax
//FRAGMENT vbsxx=vbszz_ror_2
tza
asr
asr
tax
//FRAGMENT vbsyy=vbsz1_ror_2
lda {z1}
asr
asr
tay
//FRAGMENT vbsyy=vbsaa_ror_2
asr
asr
tay
//FRAGMENT vbsyy=vbsxx_ror_2
txa
asr
asr
tay
//FRAGMENT vbsyy=vbsyy_ror_2
tya
asr
asr
tay
//FRAGMENT vbsyy=vbszz_ror_2
tza
asr
asr
tay
//FRAGMENT vbszz=vbsz1_ror_2
lda {z1}
asr
asr
taz
//FRAGMENT vbszz=vbsaa_ror_2
asr
asr
taz
//FRAGMENT vbszz=vbsxx_ror_2
txa
asr
asr
taz
//FRAGMENT vbszz=vbsyy_ror_2
tya
asr
asr
taz
//FRAGMENT vbszz=vbszz_ror_2
tza
asr
asr
taz
//FRAGMENT vbsyy=_deref_pbsc1
ldy {c1}
//FRAGMENT vbszz=_deref_pbsc1
lda {c1}
taz
//FRAGMENT _deref_pbsc1=vbsxx
stx {c1}
//FRAGMENT _deref_pbsc1=vbsyy
sty {c1}
//FRAGMENT _deref_pbsc1=vbszz
tza
sta {c1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE f6e6ad7e1 f6e6af848
//KICKC FRAGMENT CACHE f6e6ad792 f6e6af7f9
//FRAGMENT _deref_pbuc1=vbuc2
lda #{c2}
sta {c1}
@ -1161,79 +1161,6 @@ inc
stx {c1}
//FRAGMENT _deref_pbuc1=vbuzz
stz {c1}
//FRAGMENT 0_neq_pbuc1_derefidx_vbuz1_then_la1
ldy {z1}
lda {c1},y
cmp #0
bne {la1}
//FRAGMENT pbuc1_derefidx_vbuz1=vbuz1
ldy {z1}
tya
sta {c1},y
//FRAGMENT 0_neq_pbuc1_derefidx_vbuaa_then_la1
tay
lda {c1},y
cmp #0
bne {la1}
//FRAGMENT 0_neq_pbuc1_derefidx_vbuxx_then_la1
lda {c1},x
cmp #0
bne {la1}
//FRAGMENT 0_neq_pbuc1_derefidx_vbuyy_then_la1
lda {c1},y
cmp #0
bne {la1}
//FRAGMENT 0_neq_pbuc1_derefidx_vbuzz_then_la1
tza
tay
lda {c1},y
cmp #0
bne {la1}
//FRAGMENT pbuc1_derefidx_vbuxx=vbuxx
txa
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuyy=vbuyy
tya
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuzz=vbuzz
tza
tax
sta {c1},x
//FRAGMENT vduz1=vduc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
lda #<{c1}>>$10
sta {z1}+2
lda #>{c1}>>$10
sta {z1}+3
//FRAGMENT _deref_pduc1=vduz1
ldq {z1}
stq {c1}
//FRAGMENT vduz1=vduz1_plus_vduz2
clc
ldq {z1}
adcq {z2}
stq {z1}
//FRAGMENT vduz1=vduz1_plus_vbuz2
lda {z2}
clc
adc {z1}
sta {z1}
lda {z1}+1
adc #0
sta {z1}+1
lda {z1}+2
adc #0
sta {z1}+2
lda {z1}+3
adc #0
sta {z1}+3
//FRAGMENT vduz1=vwuc1
NO_SYNTHESIS
//FRAGMENT vduz1=vwsc1
NO_SYNTHESIS
//FRAGMENT vbuz1=_deref_pbuc1_plus_1
lda {c1}
inc
@ -1820,6 +1747,15 @@ tay
tza
sty $ff
ora $ff
//FRAGMENT vduz1=vduc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
lda #<{c1}>>$10
sta {z1}+2
lda #>{c1}>>$10
sta {z1}+3
//FRAGMENT vduz1=vbuc1
lda #{c1}
sta {z1}
@ -2562,3 +2498,67 @@ sta {c1},x
tay
//FRAGMENT vbuzz=vbuaa
taz
//FRAGMENT 0_neq_pbuc1_derefidx_vbuz1_then_la1
ldy {z1}
lda {c1},y
cmp #0
bne {la1}
//FRAGMENT pbuc1_derefidx_vbuz1=vbuz1
ldy {z1}
tya
sta {c1},y
//FRAGMENT 0_neq_pbuc1_derefidx_vbuaa_then_la1
tay
lda {c1},y
cmp #0
bne {la1}
//FRAGMENT 0_neq_pbuc1_derefidx_vbuxx_then_la1
lda {c1},x
cmp #0
bne {la1}
//FRAGMENT 0_neq_pbuc1_derefidx_vbuyy_then_la1
lda {c1},y
cmp #0
bne {la1}
//FRAGMENT 0_neq_pbuc1_derefidx_vbuzz_then_la1
tza
tay
lda {c1},y
cmp #0
bne {la1}
//FRAGMENT pbuc1_derefidx_vbuxx=vbuxx
txa
sta {c1},x
//FRAGMENT pbuc1_derefidx_vbuyy=vbuyy
tya
sta {c1},y
//FRAGMENT pbuc1_derefidx_vbuzz=vbuzz
tza
tax
sta {c1},x
//FRAGMENT _deref_pduc1=vduz1
ldq {z1}
stq {c1}
//FRAGMENT vduz1=vduz1_plus_vduz2
clc
ldq {z1}
adcq {z2}
stq {z1}
//FRAGMENT vduz1=vduz1_plus_vbuz2
lda {z2}
clc
adc {z1}
sta {z1}
lda {z1}+1
adc #0
sta {z1}+1
lda {z1}+2
adc #0
sta {z1}+2
lda {z1}+3
adc #0
sta {z1}+3
//FRAGMENT vduz1=vwuc1
NO_SYNTHESIS
//FRAGMENT vduz1=vwsc1
NO_SYNTHESIS

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE f6e6ad7e1 f6e6af848
//KICKC FRAGMENT CACHE f6e6ad792 f6e6af7f9
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,18 @@
// Simple functions wrapping 6502 instructions
/// @file
/// @brief Simple functions wrapping 6502 instructions
// Set the processor interrupt flag - disabling IRQ's.
// Uses the SEI instruction
/// @brief Set the processor interrupt flag - disabling IRQ's.
///
/// Uses the SEI instruction
inline void SEI();
// Clear the processor interrupt flag - enabling IRQ's.
// Uses the CLI instruction
/// @brief Clear the processor interrupt flag - enabling IRQ's.
///
/// Uses the CLI instruction
inline void CLI();
// Add a KickAssembler breakpoint.
// The breakpoint is compiled be KickAssembler to the output files.
// If you use VICE or C64Debugger they can automatically load the breakpoints when starting.
/// @brief Add a KickAssembler breakpoint.
///
/// The breakpoint is compiled be KickAssembler to the output files.
/// If you use VICE or C64Debugger they can automatically load the breakpoints when starting.
inline void BREAK();

View File

@ -1,12 +1,15 @@
// Find atan2(x, y) using the CORDIC method
// See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf
/// @file
/// Find atan2(x, y) using the CORDIC method
/// See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf
// Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y)
// Finding the angle requires a binary search using CORDIC_ITERATIONS_16
// Returns the angle in hex-degrees (0=0, 0x8000=PI, 0x10000=2*PI)
/// @brief Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y)
///
/// Finding the angle requires a binary search using CORDIC_ITERATIONS_16
/// Returns the angle in hex-degrees (0=0, 0x8000=PI, 0x10000=2*PI)
unsigned int atan2_16(signed int x, signed int y);
// Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y)
// Finding the angle requires a binary search using CORDIC_ITERATIONS_8
// Returns the angle in hex-degrees (0=0, 0x80=PI, 0x100=2*PI)
/// @brief Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y)
///
/// Finding the angle requires a binary search using CORDIC_ITERATIONS_8
/// Returns the angle in hex-degrees (0=0, 0x80=PI, 0x100=2*PI)
char atan2_8(signed char x, signed char y);

View File

@ -1,7 +1,7 @@
// ATARI Alphanumeric Television Interface Controller (ANTIC)
// Used in Atari 5200 and the 8-bit series (400, 800, XL, XE)
// https://en.wikipedia.org/wiki/ANTIC
// https://playermissile.com/dli_tutorial/
/// ATARI Alphanumeric Television Interface Controller (ANTIC)
/// Used in Atari 5200 and the 8-bit series (400, 800, XL, XE)
/// https://en.wikipedia.org/wiki/ANTIC
/// https://playermissile.com/dli_tutorial/
struct ATARI_ANTIC {
@ -112,62 +112,62 @@ struct ATARI_ANTIC {
};
// ANTIC Display List Instruction Set
/// ANTIC Display List Instruction Set
// 2: High Resolution Text Mode. 8 scanlines per char, 32/40/48 chars wide. bit 7 controls inversion or blinking, based on modes in CHACTL.
/// 2: High Resolution Text Mode. 8 scanlines per char, 32/40/48 chars wide. bit 7 controls inversion or blinking, based on modes in CHACTL.
const char MODE2 = 0x02;
// 3: High Resolution Text Mode. 10 scanlines per char, 32/40/48 chars wide
/// 3: High Resolution Text Mode. 10 scanlines per char, 32/40/48 chars wide
const char MODE3 = 0x03;
// 4: Multicolor text. 8 scanlines per char, 32/40/48 chars wide.
/// 4: Multicolor text. 8 scanlines per char, 32/40/48 chars wide.
const char MODE4 = 0x04;
// 5: Multicolor text. 16 scanlines per char, 32/40/48 chars wide. each character is instead 4x8 with pixels twice as wide. Normally each pair of bits produces either the background color (00) or PF0-PF2 (01-11). If bit 7 is set, however, the 11 pair produces PF3 instead of PF2.
/// 5: Multicolor text. 16 scanlines per char, 32/40/48 chars wide. each character is instead 4x8 with pixels twice as wide. Normally each pair of bits produces either the background color (00) or PF0-PF2 (01-11). If bit 7 is set, however, the 11 pair produces PF3 instead of PF2.
const char MODE5 = 0x05;
// 6: Single color text in five colors. 8 scanlines per char, 16/20/24 chars wide. the upper two bits are used to select the foreground color used by 1 bits, with 00-11 producing PF0-PF3.
/// 6: Single color text in five colors. 8 scanlines per char, 16/20/24 chars wide. the upper two bits are used to select the foreground color used by 1 bits, with 00-11 producing PF0-PF3.
const char MODE6 = 0x06;
// 7: Single color text in five colors. 16 scanlines per char, 16/20/24 chars wide. the upper two bits are used to select the foreground color used by 1 bits, with 00-11 producing PF0-PF3.
/// 7: Single color text in five colors. 16 scanlines per char, 16/20/24 chars wide. the upper two bits are used to select the foreground color used by 1 bits, with 00-11 producing PF0-PF3.
const char MODE7 = 0x07;
// 8: Bitmap mode with 8x8 pixels. 40 pixel screen. four-color mode.
/// 8: Bitmap mode with 8x8 pixels. 40 pixel screen. four-color mode.
const char MODE8 = 0x08;
// 9: Bitmap mode with 4x4 pixels. 80 pixel screen. two-color mode.
/// 9: Bitmap mode with 4x4 pixels. 80 pixel screen. two-color mode.
const char MODE9 = 0x09;
// A: Bitmap mode with 4x4 pixels. 80 pixel screen. four-color mode.
/// A: Bitmap mode with 4x4 pixels. 80 pixel screen. four-color mode.
const char MODEA = 0x0a;
// B: Bitmap mode with 2x2 pixels. 160 pixel screen. two-color mode.
/// B: Bitmap mode with 2x2 pixels. 160 pixel screen. two-color mode.
const char MODEB = 0x0b;
// C: Bitmap mode with 2x1 pixels. 160 pixel screen. two-color mode.
/// C: Bitmap mode with 2x1 pixels. 160 pixel screen. two-color mode.
const char MODEC = 0x0c;
// D: Bitmap mode with 2x2 pixels. 160 pixel screen. four-color mode.
/// D: Bitmap mode with 2x2 pixels. 160 pixel screen. four-color mode.
const char MODED = 0x0d;
// E: Bitmap mode with 2x1 pixels. 160 pixel screen. four-color mode.
/// E: Bitmap mode with 2x1 pixels. 160 pixel screen. four-color mode.
const char MODEE = 0x0e;
// F: Bitmap mode with 1x1 pixels. 320 pixel screen. two-color mode.
/// F: Bitmap mode with 1x1 pixels. 320 pixel screen. two-color mode.
const char MODEF = 0x0f;
// Display list interrupt - Interrupt CPU at beginning of last scan line. Can be combined with mode or blank instructions by OR.
/// Display list interrupt - Interrupt CPU at beginning of last scan line. Can be combined with mode or blank instructions by OR.
const char DLI = 0x80;
// Load memory scan counter (LMS operation) - Load memory scan counter with new 16-bit address. Can be combined with mode instructions by OR.
/// Load memory scan counter (LMS operation) - Load memory scan counter with new 16-bit address. Can be combined with mode instructions by OR.
const char LMS = 0x40;
// Vertical scroll - Enable vertical scrolling. Can be combined with mode or blank instructions by OR.
/// Vertical scroll - Enable vertical scrolling. Can be combined with mode or blank instructions by OR.
const char VS = 0x20;
// Horizontal scroll - Enable horizontal scrolling. Can be combined with mode or blank instructions by OR.
/// Horizontal scroll - Enable horizontal scrolling. Can be combined with mode or blank instructions by OR.
const char HS = 0x10;
// Jump command - followed by two bytes indicating the new instruction pointer for the display list.
/// Jump command - followed by two bytes indicating the new instruction pointer for the display list.
const char JMP = 0x01;
// Jump and wait for Vertical Blank - suspends the display list until vertical blank and then jumps. This is usually used to terminate the display list and restart it for the next frame.
/// Jump and wait for Vertical Blank - suspends the display list until vertical blank and then jumps. This is usually used to terminate the display list and restart it for the next frame.
const char JVB = 0x41;
// Blank 1 line
/// Blank 1 line
const char BLANK1 = 0x00;
// Blank 2 lines
/// Blank 2 lines
const char BLANK2 = 0x10;
// Blank 3 lines
/// Blank 3 lines
const char BLANK3 = 0x20;
// Blank 4 lines
/// Blank 4 lines
const char BLANK4 = 0x30;
// Blank 5 lines
/// Blank 5 lines
const char BLANK5 = 0x40;
// Blank 6 lines
/// Blank 6 lines
const char BLANK6 = 0x50;
// Blank 7 lines
/// Blank 7 lines
const char BLANK7 = 0x60;
// Blank 8 lines
/// Blank 8 lines
const char BLANK8 = 0x70;

View File

@ -1,6 +1,6 @@
// ATARI Graphic Television Interface Adaptor (GTIA)
// Used in Atari 5200 and the 8-bit series (400, 800, XL, XE)
// https://en.wikipedia.org/wiki/CTIA_and_GTIA
/// ATARI Graphic Television Interface Adaptor (GTIA)
/// Used in Atari 5200 and the 8-bit series (400, 800, XL, XE)
/// https://en.wikipedia.org/wiki/CTIA_and_GTIA
struct ATARI_GTIA_READ {
// Missile 0 to Playfield collisions Read $D000

View File

@ -1,6 +1,6 @@
// ATARI Graphic Television Interface Adaptor (GTIA)
// Used in Atari 5200 and the 8-bit series (400, 800, XL, XE)
// https://en.wikipedia.org/wiki/CTIA_and_GTIA
/// ATARI Graphic Television Interface Adaptor (GTIA)
/// Used in Atari 5200 and the 8-bit series (400, 800, XL, XE)
/// https://en.wikipedia.org/wiki/CTIA_and_GTIA
struct ATARI_POKEY_READ {
// Potentiometer (Paddle) 0 Read $D200 53760 PADDL0 $0270 624

View File

@ -1,18 +1,18 @@
// Atari Television Interface Adaptor (TIA)
// https://en.wikipedia.org/wiki/Television_Interface_Adaptor
// http://www.qotile.net/minidig/docs/stella.pdf
// Based on https://github.com/munsie/dasm/blob/master/machines/atari2600/vcs.h
/// Atari Television Interface Adaptor (TIA)
/// https://en.wikipedia.org/wiki/Television_Interface_Adaptor
/// http://www.qotile.net/minidig/docs/stella.pdf
/// Based on https://github.com/munsie/dasm/blob/master/machines/atari2600/vcs.h
// The number of CPU cycles per scanline
/// The number of CPU cycles per scanline
const char CYCLES_PER_SCANLINE = 76;
// The TIA WSYNC register (for access from inline ASM)
/// The TIA WSYNC register (for access from inline ASM)
char* const TIA_WSYNC = (char*)0x02;
// The TIA RESP0 register (for access from inline ASM)
/// The TIA RESP0 register (for access from inline ASM)
char* const TIA_RESP0 = (char*)0x10;
// The TIA RESP1 register (for access from inline ASM)
/// The TIA RESP1 register (for access from inline ASM)
char* const TIA_RESP1 = (char*)0x11;
// The TIA HMP0 register (for access from inline ASM)
/// The TIA HMP0 register (for access from inline ASM)
char* const TIA_HMP0 = (char*)0x20;
struct ATARI_TIA_WRITE {

View File

@ -1,5 +1,5 @@
// Atari 8-bit 400/800/XL/XE Registers and Constants
// https://en.wikipedia.org/wiki/Atari_8-bit_family
/// Atari 8-bit 400/800/XL/XE Registers and Constants
/// https://en.wikipedia.org/wiki/Atari_8-bit_family
#ifndef __ATARIXL__
#error "Target platform must be atarixl"
@ -9,64 +9,64 @@
#include <atari-gtia.h>
#include <atari-pokey.h>
// Atari GTIA write registers
/// Atari GTIA write registers
struct ATARI_GTIA_WRITE * const GTIA = (struct ATARI_GTIA_WRITE *)0xd000;
// Atari GTIA read registers
/// Atari GTIA read registers
struct ATARI_GTIA_READ * const GTIA_READ = (struct ATARI_GTIA_READ *)0xd000;
// Atari POKEY write registers
/// Atari POKEY write registers
struct ATARI_POKEY_WRITE * const POKEY = (struct ATARI_POKEY_WRITE *)0xd200;
// Atari POKEY read registers
/// Atari POKEY read registers
struct ATARI_POKEY_READ * const POKEY_READ = (struct ATARI_POKEY_READ *)0xd200;
// Atari ANTIC registers
/// Atari ANTIC registers
struct ATARI_ANTIC * const ANTIC = (struct ATARI_ANTIC *)0xd400;
// Atari ZP registers
// 1-byte cursor row
/// Atari ZP registers
/// 1-byte cursor row
char * ROWCRS = (char*)0x54;
// 2-byte cursor column
/// 2-byte cursor column
word * COLCRS = (word*)0x55;
// 2-byte saved memory scan counter
/// 2-byte saved memory scan counter
char ** const SAVMSC = (char**)0x58;
// data under cursor
/// data under cursor
char * const OLDCHR = (char*)0x5D;
// 2-byte saved cursor memory address
/// 2-byte saved cursor memory address
char ** const OLDADR = (char**)0x5E;
// Atari OS Shadow registers
// OS Shadow ANTIC Direct Memory Access Control ($D400)
/// Atari OS Shadow registers
/// OS Shadow ANTIC Direct Memory Access Control ($D400)
char * const SDMCTL = (char*)0x022f;
// OS Shadow ANTIC Character Control ($D401)
/// OS Shadow ANTIC Character Control ($D401)
char * const CHART = (char*)0x02f3;
// OS Shadow ANTIC Display List Pointer ($D402)
/// OS Shadow ANTIC Display List Pointer ($D402)
char ** const SDLST = (char**)0x0230;
// OS Shadow ANTIC Character Set Base Address (D409)
/// OS Shadow ANTIC Character Set Base Address (D409)
char * CHBAS = (char*)0x02f4;
// OS Shadow ANTIC Light Pen Horizontal Position ($D40C)
/// OS Shadow ANTIC Light Pen Horizontal Position ($D40C)
char * LPENH = (char*)0x234;
// OS Shadow ANTIC Light Pen Vertical Position ($D40D)
/// OS Shadow ANTIC Light Pen Vertical Position ($D40D)
char * LPENV = (char*)0x235;
// Color register zero, color of playfield zero. Shadow for 53270 ($D016)
/// Color register zero, color of playfield zero. Shadow for 53270 ($D016)
char * const COLOR0 = (char*)0x2C4;
// Shadow for 53271 ($D017). Text color in Gr.0
/// Shadow for 53271 ($D017). Text color in Gr.0
char * const COLOR1 = (char*)0x2C5;
// Shadow for 53272 ($D018). Background color in GR.0
/// Shadow for 53272 ($D018). Background color in GR.0
char * const COLOR2 = (char*)0x2C6;
// Shadow for 53273 ($D019)
/// Shadow for 53273 ($D019)
char * const COLOR3 = (char*)0x2C7;
// Shadow for 53274 ($D01A). Border color in GR.0
/// Shadow for 53274 ($D01A). Border color in GR.0
char * const COLOR4 = (char*)0x2C8;
// Cursor inhibit flag, 0 turns on, any other number turns off. Cursor doesn't change until it moves next.
/// Cursor inhibit flag, 0 turns on, any other number turns off. Cursor doesn't change until it moves next.
char * const CRSINH = (char*)0x2F0;
// Internal hardware value for the last key pressed. Set to 0xFF to clear.
/// Internal hardware value for the last key pressed. Set to 0xFF to clear.
char * const CH = (char*)0x2FC;
// Atari colours - names from Mapping the Atari.
// Add luminance values 0-14 (even only) to increase brightness
/// Atari colours - names from Mapping the Atari.
/// Add luminance values 0-14 (even only) to increase brightness
const char BLACK = 0x00;
const char RUST = 0x10;
const char RED_ORANGE = 0x20;

View File

@ -1,5 +1,5 @@
// Atari 2600 Registers and Constants
// https://web.archive.org/web/20170215054248/http://www.atariguide.com/pdfs/Atari_2600_VCS_Domestic_Field_Service_Manual.pdf
/// Atari 2600 Registers and Constants
/// https://web.archive.org/web/20170215054248/http://www.atariguide.com/pdfs/Atari_2600_VCS_Domestic_Field_Service_Manual.pdf
#ifndef __ATARI2600__
#error "Target platform must be atari2600"
@ -8,12 +8,12 @@
#include <atari-tia.h>
#include <mos6532.h>
// Atari TIA write registers
/// Atari TIA write registers
struct ATARI_TIA_WRITE * const TIA = (struct ATARI_TIA_WRITE *)0x00;
// Atari TIA read registers
/// Atari TIA read registers
struct ATARI_TIA_READ * const TIA_READ = (struct ATARI_TIA_READ *)0x00;
// Atari RIOT registers
/// Atari RIOT registers
struct MOS6532_RIOT * const RIOT = (struct MOS6532_RIOT *)0x280;

View File

@ -1,5 +1,5 @@
// Commodore 128 Registers and Memory
// https://archive.org/details/C128_Programmers_Reference_Guide_1986_Bamtam_Books/page/n299/mode/2up
/// Commodore 128 Registers and Memory
/// https://archive.org/details/C128_Programmers_Reference_Guide_1986_Bamtam_Books/page/n299/mode/2up
#ifndef __C128__
#error "Target platform must be C128"
#endif

View File

@ -1,128 +1,128 @@
// Library wrapping the BASIC floating point functions
// See https://www.c64-wiki.com/wiki/Floating_point_arithmetic
// See http://www.pagetable.com/c64rom/c64rom_sc.html
/// Library wrapping the BASIC floating point functions
/// See https://www.c64-wiki.com/wiki/Floating_point_arithmetic
/// See http://www.pagetable.com/c64rom/c64rom_sc.html
// Prepare MEM pointers for operations using MEM
/// Prepare MEM pointers for operations using MEM
inline void prepareMEM(unsigned int mem);
// FAC = unsigned int
// Set the FAC (floating point accumulator) to the integer value of a 16bit unsigned int
/// FAC = unsigned int
/// Set the FAC (floating point accumulator) to the integer value of a 16bit unsigned int
void setFAC(unsigned int w);
// unsigned int = FAC
// Get the value of the FAC (floating point accumulator) as an integer 16bit unsigned int
// Destroys the value in the FAC in the process
/// unsigned int = FAC
/// Get the value of the FAC (floating point accumulator) as an integer 16bit unsigned int
/// Destroys the value in the FAC in the process
unsigned int getFAC();
// ARG = FAC
// Set the ARG (floating point argument) to the value of the FAC (floating point accumulator)
/// ARG = FAC
/// Set the ARG (floating point argument) to the value of the FAC (floating point accumulator)
void setARGtoFAC();
// FAC = ARG
// Set the FAC (floating point accumulator) to the value of the ARG (floating point argument)
/// FAC = ARG
/// Set the FAC (floating point accumulator) to the value of the ARG (floating point argument)
void setFACtoARG();
// MEM = FAC
// Stores the value of the FAC to memory
// Stores 5 chars (means it is necessary to allocate 5 chars to avoid clobbering other data using eg. char[] mem = {0, 0, 0, 0, 0};)
/// MEM = FAC
/// Stores the value of the FAC to memory
/// Stores 5 chars (means it is necessary to allocate 5 chars to avoid clobbering other data using eg. char[] mem = {0, 0, 0, 0, 0};)
void setMEMtoFAC(char* mem);
// FAC = MEM
// Set the FAC to value from MEM (float saved in memory)
// Reads 5 chars
/// FAC = MEM
/// Set the FAC to value from MEM (float saved in memory)
/// Reads 5 chars
void setFACtoMEM(char* mem);
// FAC = PI/2
// Set the FAC to PI/2
// Reads 5 chars from the BASIC ROM
/// FAC = PI/2
/// Set the FAC to PI/2
/// Reads 5 chars from the BASIC ROM
void setFACtoPIhalf();
// FAC = 2*PI
// Set the FAC to 2*PI
// Reads 5 chars from the BASIC ROM
/// FAC = 2*PI
/// Set the FAC to 2*PI
/// Reads 5 chars from the BASIC ROM
void setFACto2PI();
// ARG = MEM
// Load the ARG from memory
// Reads 5 chars
/// ARG = MEM
/// Load the ARG from memory
/// Reads 5 chars
void setARGtoMEM(char* mem);
// FAC = MEM+FAC
// Set FAC to MEM (float saved in memory) plus FAC (float accumulator)
// Reads 5 chars from memory
/// FAC = MEM+FAC
/// Set FAC to MEM (float saved in memory) plus FAC (float accumulator)
/// Reads 5 chars from memory
void addMEMtoFAC(char* mem);
// FAC = ARG+FAC
// Add ARG (floating point argument) to FAC (floating point accumulator)
/// FAC = ARG+FAC
/// Add ARG (floating point argument) to FAC (floating point accumulator)
void addARGtoFAC();
// FAC = MEM-FAC
// Set FAC to MEM (float saved in memory) minus FAC (float accumulator)
// Reads 5 chars from memory
/// FAC = MEM-FAC
/// Set FAC to MEM (float saved in memory) minus FAC (float accumulator)
/// Reads 5 chars from memory
void subFACfromMEM(char* mem);
// FAC = ARG-FAC
// Set FAC to ARG minus FAC
/// FAC = ARG-FAC
/// Set FAC to ARG minus FAC
void subFACfromARG();
// FAC = MEM/FAC
// Set FAC to MEM (float saved in memory) divided by FAC (float accumulator)
// Reads 5 chars from memory
/// FAC = MEM/FAC
/// Set FAC to MEM (float saved in memory) divided by FAC (float accumulator)
/// Reads 5 chars from memory
void divMEMbyFAC(char* mem);
// FAC = MEM*FAC
// Set FAC to MEM (float saved in memory) multiplied by FAC (float accumulator)
// Reads 5 chars from memory
/// FAC = MEM*FAC
/// Set FAC to MEM (float saved in memory) multiplied by FAC (float accumulator)
/// Reads 5 chars from memory
void mulFACbyMEM(char* mem);
// FAC = MEM^FAC
// Set FAC to MEM (float saved in memory) raised to power of FAC (float accumulator)
// Reads 5 chars from memory
/// FAC = MEM^FAC
/// Set FAC to MEM (float saved in memory) raised to power of FAC (float accumulator)
/// Reads 5 chars from memory
void pwrMEMbyFAC(char* mem);
// FAC = int(FAC)
// Set FAC to integer part of the FAC - int(FAC)
// The integer part is defined as the next lower integer - like java floor()
/// FAC = int(FAC)
/// Set FAC to integer part of the FAC - int(FAC)
/// The integer part is defined as the next lower integer - like java floor()
void intFAC();
// FAC = sin(FAC)
// Set FAC to sine of the FAC - sin(FAC)
// Sine is calculated on radians (0-2*PI)
/// FAC = sin(FAC)
/// Set FAC to sine of the FAC - sin(FAC)
/// Sine is calculated on radians (0-2*PI)
void sinFAC();
// FAC = cos(FAC)
// Set FAC to cosine of the FAC - cos(FAC)
// Cosine is calculated on radians (0-2*PI)
/// FAC = cos(FAC)
/// Set FAC to cosine of the FAC - cos(FAC)
/// Cosine is calculated on radians (0-2*PI)
void cosFAC();
// FAC = tan(FAC)
// Set FAC to the tangens of FAC - tan(FAC)
// Tangens is calculated on radians (0-2*PI)
/// FAC = tan(FAC)
/// Set FAC to the tangens of FAC - tan(FAC)
/// Tangens is calculated on radians (0-2*PI)
void tanFAC();
// FAC = atn(FAC)
// Set FAC to the arc tangens of FAC - atn(FAC)
// Arc Tangens is calculated on radians (0-2*PI)
/// FAC = atn(FAC)
/// Set FAC to the arc tangens of FAC - atn(FAC)
/// Arc Tangens is calculated on radians (0-2*PI)
void atnFAC();
// FAC = sqr(FAC)
// Set FAC to the square root of FAC - sqr(FAC)
/// FAC = sqr(FAC)
/// Set FAC to the square root of FAC - sqr(FAC)
void sqrFAC();
// FAC = exp(FAC)
// Set FAC to the exponential function of FAC - exp(FAC)
// Exp is based on the natural logarithm e=2.71828183
/// FAC = exp(FAC)
/// Set FAC to the exponential function of FAC - exp(FAC)
/// Exp is based on the natural logarithm e=2.71828183
void expFAC();
// FAC = log(FAC)
// Set FAC to the logarithm of FAC - log(FAC)
// Log is based on the natural logarithm e=2.71828183
/// FAC = log(FAC)
/// Set FAC to the logarithm of FAC - log(FAC)
/// Log is based on the natural logarithm e=2.71828183
void logFAC();
// FAC = FAC/10
// Set FAC to FAC divided by 10
/// FAC = FAC/10
/// Set FAC to FAC divided by 10
void divFACby10();
// FAC = FAC*10
// Set FAC to FAC multiplied by 10
/// FAC = FAC*10
/// Set FAC to FAC multiplied by 10
void mulFACby10();

View File

@ -1,14 +1,14 @@
// Simple single-color (320x200) bitmap routines
// Initialize bitmap plotting tables
/// Simple single-color (320x200) bitmap routines
/// Initialize bitmap plotting tables
void bitmap_init(char* gfx, char* screen);
// Clear all graphics on the bitmap
// bgcol - the background color to fill the screen with
// fgcol - the foreground color to fill the screen with
/// Clear all graphics on the bitmap
/// bgcol - the background color to fill the screen with
/// fgcol - the foreground color to fill the screen with
void bitmap_clear(char bgcol, char fgcol);
// Plot a single dot in the bitmap
/// Plot a single dot in the bitmap
void bitmap_plot(unsigned int x, char y);
// Draw a line on the bitmap using bresenhams algorithm
/// Draw a line on the bitmap using bresenhams algorithm
void bitmap_line(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2);

View File

@ -1,24 +1,24 @@
// Simple Keyboard Input Library
// C64 Keyboard Matrix Reference - from http://codebase64.org/doku.php?id=base:reading_the_keyboard
// Keyboard Codes are %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// +----+----------------------+-------------------------------------------------------------------------------------------------------+
// | | Write | Read $dc01 (C64 screen code in parenthesis): |
// |row:| $dc00: row bits +------------+------------+------------+------------+------------+------------+------------+------------+
// | | | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0 |
// +----+----------------------+------------+------------+------------+------------+------------+------------+------------+------------+
// |0. | #%11111110 (254/$fe) | DOWN ($ )| F5 ($ )| F3 ($ )| F1 ($ )| F7 ($ )| RIGHT ($ )| RETURN($ )|DELETE ($ )|
// |1. | #%11111101 (253/$fd) |LEFT-SH($ )| e ($05)| s ($13)| z ($1a)| 4 ($34)| a ($01)| w ($17)| 3 ($33)|
// |2. | #%11111011 (251/$fb) | x ($18)| t ($14)| f ($06)| c ($03)| 6 ($36)| d ($04)| r ($12)| 5 ($35)|
// |3. | #%11110111 (247/$f7) | v ($16)| u ($15)| h ($08)| b ($02)| 8 ($38)| g ($07)| y ($19)| 7 ($37)|
// |4. | #%11101111 (239/$ef) | n ($0e)| o ($0f)| k ($0b)| m ($0d)| 0 ($30)| j ($0a)| i ($09)| 9 ($39)|
// |5. | #%11011111 (223/$df) | , ($2c)| @ ($00)| : ($3a)| . ($2e)| - ($2d)| l ($0c)| p ($10)| + ($2b)|
// |6. | #%10111111 (191/$bf) | / ($2f)| ^ ($1e)| = ($3d)|RGHT-SH($ )| HOME ($ )| ; ($3b)| * ($2a)| £ ($1c)|
// |7. | #%01111111 (127/$7f) | STOP ($ )| q ($11)|COMMODR($ )| SPACE ($20)| 2 ($32)|CONTROL($ )| <- ($1f)| 1 ($31)|
// +----+----------------------+------------+------------+------------+------------+------------+------------+------------+------------+
/// Simple Keyboard Input Library
/// C64 Keyboard Matrix Reference - from http://codebase64.org/doku.php?id=base:reading_the_keyboard
/// Keyboard Codes are %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
/// +----+----------------------+-------------------------------------------------------------------------------------------------------+
/// | | Write | Read $dc01 (C64 screen code in parenthesis): |
/// |row:| $dc00: row bits +------------+------------+------------+------------+------------+------------+------------+------------+
/// | | | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0 |
/// +----+----------------------+------------+------------+------------+------------+------------+------------+------------+------------+
/// |0. | #%11111110 (254/$fe) | DOWN ($ )| F5 ($ )| F3 ($ )| F1 ($ )| F7 ($ )| RIGHT ($ )| RETURN($ )|DELETE ($ )|
/// |1. | #%11111101 (253/$fd) |LEFT-SH($ )| e ($05)| s ($13)| z ($1a)| 4 ($34)| a ($01)| w ($17)| 3 ($33)|
/// |2. | #%11111011 (251/$fb) | x ($18)| t ($14)| f ($06)| c ($03)| 6 ($36)| d ($04)| r ($12)| 5 ($35)|
/// |3. | #%11110111 (247/$f7) | v ($16)| u ($15)| h ($08)| b ($02)| 8 ($38)| g ($07)| y ($19)| 7 ($37)|
/// |4. | #%11101111 (239/$ef) | n ($0e)| o ($0f)| k ($0b)| m ($0d)| 0 ($30)| j ($0a)| i ($09)| 9 ($39)|
/// |5. | #%11011111 (223/$df) | , ($2c)| @ ($00)| : ($3a)| . ($2e)| - ($2d)| l ($0c)| p ($10)| + ($2b)|
/// |6. | #%10111111 (191/$bf) | / ($2f)| ^ ($1e)| = ($3d)|RGHT-SH($ )| HOME ($ )| ; ($3b)| * ($2a)| £ ($1c)|
/// |7. | #%01111111 (127/$7f) | STOP ($ )| q ($11)|COMMODR($ )| SPACE ($20)| 2 ($32)|CONTROL($ )| <- ($1f)| 1 ($31)|
/// +----+----------------------+------------+------------+------------+------------+------------+------------+------------+------------+
// Keyboard Codes for all 63 keys.
// Keyboard Codes are %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7).
// See C64 Keyboard Matrix Reference http://codebase64.org/doku.php?id=base:reading_the_keyboard
/// Keyboard Codes for all 63 keys.
/// Keyboard Codes are %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7).
/// See C64 Keyboard Matrix Reference http://codebase64.org/doku.php?id=base:reading_the_keyboard
const char KEY_DEL = $00;
const char KEY_RETURN = $01;
const char KEY_CRSR_RIGHT = $02;
@ -84,57 +84,57 @@ const char KEY_COMMODORE = $3d;
const char KEY_Q = $3e;
const char KEY_RUNSTOP = $3f;
// Initialize keyboard reading by setting CIA#$ Data Direction Registers
/// Initialize keyboard reading by setting CIA#$ Data Direction Registers
void keyboard_init();
// Check if any key is currently pressed on the keyboard matrix
// Return 0 if no key is pressed and not 0 if any key is pressed
/// Check if any key is currently pressed on the keyboard matrix
/// Return 0 if no key is pressed and not 0 if any key is pressed
char keyboard_matrix_any(void);
// Read a single row of the keyboard matrix
// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
// Returns the keys pressed on the row as bits according to the C64 key matrix.
// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
/// Read a single row of the keyboard matrix
/// The row ID (0-7) of the keyboard matrix row to read. See the C64 key matrix for row IDs.
/// Returns the keys pressed on the row as bits according to the C64 key matrix.
/// Notice: If the C64 normal interrupt is still running it will occasionally interrupt right between the read & write
/// leading to erroneous readings. You must disable kill the normal interrupt or sei/cli around calls to the keyboard matrix reader.
char keyboard_matrix_read(char rowid);
// Determines whether a specific key is currently pressed by accessing the matrix directly
// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
// All keys exist as as KEY_XXX constants.
// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
/// Determines whether a specific key is currently pressed by accessing the matrix directly
/// The key is a keyboard code defined from the keyboard matrix by %00rrrccc, where rrr is the row ID (0-7) and ccc is the column ID (0-7)
/// All keys exist as as KEY_XXX constants.
/// Returns zero if the key is not pressed and a non-zero value if the key is currently pressed
char keyboard_key_pressed(char key);
// Get the keycode corresponding to a specific screen code character
// ch is the character to get the key code for ($00-$3f)
// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
/// Get the keycode corresponding to a specific screen code character
/// ch is the character to get the key code for ($00-$3f)
/// Returns the key code corresponding to the passed character. Only characters with a non-shifted key are handled.
/// If there is no non-shifted key representing the char $3f is returned (representing RUN/STOP) .
char keyboard_get_keycode(char ch);
// Current keyboard modifiers (left shift, right shift, ctrl, commodore)
/// Current keyboard modifiers (left shift, right shift, ctrl, commodore)
extern char keyboard_modifiers;
// Left shift is pressed
/// Left shift is pressed
extern const char KEY_MODIFIER_LSHIFT;
// Right shift is pressed
/// Right shift is pressed
extern const char KEY_MODIFIER_RSHIFT;
// CTRL is pressed
/// CTRL is pressed
extern const char KEY_MODIFIER_CTRL;
// Commodore is pressed
/// Commodore is pressed
extern const char KEY_MODIFIER_COMMODORE;
// Any shift is pressed
/// Any shift is pressed
extern const char KEY_MODIFIER_SHIFT;
// Scans the entire matrix to determine which keys have been pressed/depressed.
// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get().
// Handles debounce and only generates events when the status of a key changes.
// Also stores current status of modifiers in keyboard_modifiers.
/// Scans the entire matrix to determine which keys have been pressed/depressed.
/// Generates keyboard events into the event buffer. Events can be read using keyboard_event_get().
/// Handles debounce and only generates events when the status of a key changes.
/// Also stores current status of modifiers in keyboard_modifiers.
void keyboard_event_scan();
// Determine if a specific key is currently pressed based on the last keyboard_event_scan()
// Returns 0 is not pressed and non-0 if pressed
/// Determine if a specific key is currently pressed based on the last keyboard_event_scan()
/// Returns 0 is not pressed and non-0 if pressed
char keyboard_event_pressed(char keycode);
// Get the next event from the keyboard event buffer.
// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process.
// The buffer is filled by keyboard_event_scan()
/// Get the next event from the keyboard event buffer.
/// Returns $ff if there is no event waiting. As all events are <$7f it is enough to examine bit 7 when determining if there is any event to process.
/// The buffer is filled by keyboard_event_scan()
char keyboard_event_get();

View File

@ -1,66 +1,66 @@
// A flexible sprite multiplexer routine for 32 sprites.
// Usage:
// - Once:
// - plexInit(screen): Initialize the data structures and set the screen address
// Each frame:
// - Set x-pos, y-pos and pointer in PLEX_XPOS[id], PLEX_YPOS[id], PLEX_PTR[id]
// - plexSort() Sorts the sprites according to y-positions and prepares for showing them. This uses an insertion sort that is quite fast when the relative order of the sprites does not change very much.
// - plexShowSprite() Shows the next sprite by copying values from PLEX_XXX[] to an actual sprite. Actual sprites are used round-robin. This should be called once for each of the 24 virtual sprites.
// - plexFreeNextYpos() Returns the Y-position where the next sprite is available to be shown (ie. the next pos where the next sprite is no longer in use showing something else).
// - plexShowNextYpos() Returns the Y-position of the next sprite to show.
/// A flexible sprite multiplexer routine for 32 sprites.
/// Usage:
/// - Once:
/// - plexInit(screen): Initialize the data structures and set the screen address
/// Each frame:
/// - Set x-pos, y-pos and pointer in PLEX_XPOS[id], PLEX_YPOS[id], PLEX_PTR[id]
/// - plexSort() Sorts the sprites according to y-positions and prepares for showing them. This uses an insertion sort that is quite fast when the relative order of the sprites does not change very much.
/// - plexShowSprite() Shows the next sprite by copying values from PLEX_XXX[] to an actual sprite. Actual sprites are used round-robin. This should be called once for each of the 24 virtual sprites.
/// - plexFreeNextYpos() Returns the Y-position where the next sprite is available to be shown (ie. the next pos where the next sprite is no longer in use showing something else).
/// - plexShowNextYpos() Returns the Y-position of the next sprite to show.
//
// In practice a good method is to wait until the raster is beyond plexFreeNextYpos() and then call plexShowSprite(). Repeat until all 32 sprites have been shown.
// TODO: Let the caller specify the number of sprites to use (or add PLEX_ENABLE[PLEX_COUNT])
/// In practice a good method is to wait until the raster is beyond plexFreeNextYpos() and then call plexShowSprite(). Repeat until all 32 sprites have been shown.
/// TODO: Let the caller specify the number of sprites to use (or add PLEX_ENABLE[PLEX_COUNT])
#include <c64.h>
// The number of sprites in the multiplexer
/// The number of sprites in the multiplexer
extern const char PLEX_COUNT;
// The x-positions of the multiplexer sprites (0x000-0x1ff)
/// The x-positions of the multiplexer sprites (0x000-0x1ff)
extern unsigned int PLEX_XPOS[PLEX_COUNT];
// The y-positions of the multiplexer sprites.
/// The y-positions of the multiplexer sprites.
extern char PLEX_YPOS[PLEX_COUNT];
// The sprite pointers for the multiplexed sprites
/// The sprite pointers for the multiplexed sprites
extern char PLEX_PTR[PLEX_COUNT];
// The address of the sprite pointers on the current screen (screen+0x3f8).
/// The address of the sprite pointers on the current screen (screen+0x3f8).
extern char* volatile PLEX_SCREEN_PTR;
// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
/// Indexes of the plex-sprites sorted by sprite y-position. Each call to plexSort() will fix the sorting if changes to the Y-positions have ruined it.
extern char PLEX_SORTED_IDX[PLEX_COUNT];
// Initialize the multiplexer data structures
/// Initialize the multiplexer data structures
void plexInit(char* screen);
// Set the address of the current screen used for setting sprite pointers (at screen+0x3f8)
/// Set the address of the current screen used for setting sprite pointers (at screen+0x3f8)
inline void plexSetScreen(char* screen);
// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
// Uses an insertion sort:
// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
// 2a. If the next element after the marker is larger that the current element
// the marker can be moved forwards (as the sorting is correct).
// 2b. If the next element after the marker is smaller than the current element:
// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
// It is then inserted at the spot. Now the marker can move forward.
/// Ensure that the indices in PLEX_SORTED_IDX is sorted based on the y-positions in PLEX_YPOS
/// Assumes that the positions are nearly sorted already (as each sprite just moves a bit)
/// Uses an insertion sort:
/// 1. Moves a marker (m) from the start to end of the array. Every time the marker moves forward all elements before the marker are sorted correctly.
/// 2a. If the next element after the marker is larger that the current element
/// the marker can be moved forwards (as the sorting is correct).
/// 2b. If the next element after the marker is smaller than the current element:
/// elements before the marker are shifted right one at a time until encountering one smaller than the current one.
/// It is then inserted at the spot. Now the marker can move forward.
void plexSort();
// Show the next sprite.
// plexSort() prepares showing the sprites
/// Show the next sprite.
/// plexSort() prepares showing the sprites
void plexShowSprite();
// Get the y-position of the next sprite to show
/// Get the y-position of the next sprite to show
inline char plexShowNextYpos();
// Prepare for a new frame. Initialize free to zero for all sprites.
/// Prepare for a new frame. Initialize free to zero for all sprites.
inline void plexFreePrepare();
// Get the Y-position where the next sprite to be shown is free to use.
/// Get the Y-position where the next sprite to be shown is free to use.
inline char plexFreeNextYpos();
// Update the data structure to reflect that a sprite has been shown. This sprite will be free again after 21 lines.
/// Update the data structure to reflect that a sprite has been shown. This sprite will be free again after 21 lines.
inline void plexFreeAdd(char ypos);

View File

@ -1,80 +1,80 @@
// A lightweight library for printing on the C64.
// Printing with this library is done by calling print_ function for each element
/// A lightweight library for printing on the C64.
/// Printing with this library is done by calling print_ function for each element
// Print a number of zero-terminated strings, each followed by a newline.
// The sequence of lines is terminated by another zero.
/// Print a number of zero-terminated strings, each followed by a newline.
/// The sequence of lines is terminated by another zero.
void print_str_lines(char* str);
// Print a zero-terminated string followed by a newline
/// Print a zero-terminated string followed by a newline
void print_str_ln(char* str);
// Print a zero-terminated string
/// Print a zero-terminated string
void print_str(char* str);
// Print a string at a specific screen position
/// Print a string at a specific screen position
void print_str_at(char* str, char* at);
// Print a newline
/// Print a newline
void print_ln();
// Print a int as HEX
/// Print a int as HEX
void print_sint(signed int w);
// Print a signed char as HEX
/// Print a signed char as HEX
void print_schar(signed char b);
// Prints a signed char as HEX at a specific position on the screen
// row and col are 0-based indices
/// Prints a signed char as HEX at a specific position on the screen
/// row and col are 0-based indices
inline void print_schar_pos(signed char sb, char row, char col);
// Print a signed char as hex at a specific screen position
/// Print a signed char as hex at a specific screen position
void print_schar_at(signed char b, char* at);
// Print a unsigned int as HEX
/// Print a unsigned int as HEX
void print_uint(unsigned int w);
// Print a char as DECIMAL
/// Print a char as DECIMAL
void print_uchar_decimal(char b);
// Print a unsigned int as DECIMAL
/// Print a unsigned int as DECIMAL
void print_uint_decimal(unsigned int w);
// Print a signed int as DECIMAL
/// Print a signed int as DECIMAL
void print_sint_decimal(int w);
// Print a unsigned int as HEX at a specific position
/// Print a unsigned int as HEX at a specific position
void print_uint_at(unsigned int w, char* at);
// Print a unsigned long as HEX
/// Print a unsigned long as HEX
void print_ulong(unsigned long dw);
// Print a unsigned long as DECIMAL
/// Print a unsigned long as DECIMAL
void print_ulong_decimal(unsigned long w);
// Print a unsigned long as HEX at a specific position
/// Print a unsigned long as HEX at a specific position
void print_ulong_at(unsigned long dw, char* at);
// Print a signed long as HEX
/// Print a signed long as HEX
void print_slong(signed long dw);
// Print a char as HEX
/// Print a char as HEX
void print_uchar(char b);
// Prints a char as HEX at a specific position on the screen
// row and col are 0-based indices
/// Prints a char as HEX at a specific position on the screen
/// row and col are 0-based indices
void print_uchar_pos(char b, char row, char col);
// Print a char as HEX at a specific position
/// Print a char as HEX at a specific position
void print_uchar_at(char b, char* at);
// Print a single char
/// Print a single char
void print_char(char ch);
// Print a single char
/// Print a single char
void print_char_at(char ch, char* at);
// Clear the screen. Also resets current line/char cursor.
/// Clear the screen. Also resets current line/char cursor.
void print_cls();
// Set the screen to print on. Also resets current line/char cursor.
/// Set the screen to print on. Also resets current line/char cursor.
void print_set_screen(char* screen);

View File

@ -1,26 +1,26 @@
// C standard library time.h
// Functions to get and manipulate date and time information.
/// C standard library time.h
/// Functions to get and manipulate date and time information.
// Type suitable for storing the processor time.
/// Type suitable for storing the processor time.
typedef unsigned long clock_t;
// Clock cycles per frame (on a C64 PAL)
/// Clock cycles per frame (on a C64 PAL)
const unsigned int CLOCKS_PER_FRAME = 19656;
// Frames per second (on a C64 PAL)
/// Frames per second (on a C64 PAL)
const char FRAMES_PER_SEC = 60;
// Clock cycles per second (on a C64 PAL)
/// Clock cycles per second (on a C64 PAL)
const clock_t CLOCKS_PER_SEC = CLOCKS_PER_FRAME*FRAMES_PER_SEC;
// Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine.
// To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code.
/// Clock cycles used to start & read the cycle clock by calling clock_start() and clock() once. Can be subtracted when calculating the number of cycles used by a routine.
/// To make precise cycle measurements interrupts and the display must be disabled so neither steals any cycles from the code.
const unsigned long CLOCKS_PER_INIT = 0x12;
// Returns the processor clock time used since the beginning of an implementation defined era (normally the beginning of the program).
// This uses CIA #2 Timer A+B on the C64, and must be initialized using clock_start()
/// Returns the processor clock time used since the beginning of an implementation defined era (normally the beginning of the program).
/// This uses CIA #2 Timer A+B on the C64, and must be initialized using clock_start()
clock_t clock(void);
// Reset & start the processor clock time. The value can be read using clock().
// This uses CIA #2 Timer A+B on the C64
/// Reset & start the processor clock time. The value can be read using clock().
/// This uses CIA #2 Timer A+B on the C64
void clock_start(void);

View File

@ -1,7 +1,7 @@
// Time-of-day helper
// Uses the MOS6526 CIA#1 on Commodore 64
/// Time-of-day helper
/// Uses the MOS6526 CIA#1 on Commodore 64
// Time-of-day 24 hour format
/// Time-of-day 24 hour format
struct TIME_OF_DAY {
// Time-of-day real-time-clock tenth seconds (BCD)
char TENTHS;
@ -13,15 +13,15 @@ struct TIME_OF_DAY {
char HOURS;
};
// Time of Day 00:00:00:00
/// Time of Day 00:00:00:00
struct TIME_OF_DAY TOD_ZERO = { 0,0,0,0 };
// Initialize time-of-day clock
// This uses the MOS6526 CIA#1
/// Initialize time-of-day clock
/// This uses the MOS6526 CIA#1
void tod_init(struct TIME_OF_DAY tod);
// Read time of day
/// Read time of day
struct TIME_OF_DAY tod_read();
// Convert time of day to a human-readable string "hh:mm:ss:10"
/// Convert time of day to a human-readable string "hh:mm:ss:10"
char* tod_str(struct TIME_OF_DAY tod);

View File

@ -1,4 +1,5 @@
// Commodore 64 Registers and Constants
/// @file
/// @brief Commodore 64 Registers and Constants
#ifndef __C64__
#error "Target platform must be C64"
#endif
@ -7,63 +8,63 @@
#include <mos6581.h>
// Processor port data direction register
/// Processor port data direction register
char* const PROCPORT_DDR = (char*)0x00;
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
/// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
const char PROCPORT_DDR_MEMORY_MASK = 0b00000111;
// Processor Port Register controlling RAM/ROM configuration and the datasette
/// Processor Port Register controlling RAM/ROM configuration and the datasette
char* const PROCPORT = (char*)0x01;
// RAM in all three areas 0xA000, 0xD000, 0xE000
/// RAM in all three areas 0xA000, 0xD000, 0xE000
const char PROCPORT_RAM_ALL = 0b00000000;
// RAM in 0xA000, 0xE000 I/O in 0xD000
/// RAM in 0xA000, 0xE000 I/O in 0xD000
const char PROCPORT_RAM_IO = 0b00000101;
// RAM in 0xA000, 0xE000 CHAR ROM in 0xD000
/// RAM in 0xA000, 0xE000 CHAR ROM in 0xD000
const char PROCPORT_RAM_CHARROM = 0b00000001;
// RAM in 0xA000, I/O in 0xD000, KERNEL in 0xE000
/// RAM in 0xA000, I/O in 0xD000, KERNEL in 0xE000
const char PROCPORT_KERNEL_IO = 0b00000110;
// BASIC in 0xA000, I/O in 0xD000, KERNEL in 0xE000
/// BASIC in 0xA000, I/O in 0xD000, KERNEL in 0xE000
const char PROCPORT_BASIC_KERNEL_IO = 0b00000111;
// The address of the CHARGEN character set
/// The address of the CHARGEN character set
char* const CHARGEN = (char*)0xd000;
// The SID MOS 6581/8580
/// The SID MOS 6581/8580
struct MOS6581_SID * const SID = (struct MOS6581_SID *)0xd400;
// The VIC-II MOS 6567/6569
/// The VIC-II MOS 6567/6569
struct MOS6569_VICII* const VICII = (struct MOS6569_VICII*)0xd000;
// Color Ram
/// Color Ram
char * const COLORRAM = (char*)0xd800;
// Color Ram
/// Color Ram
char * const COLS = (char*)0xd800;
// Default address of screen character matrix
/// Default address of screen character matrix
char * const DEFAULT_SCREEN = (char*)0x0400;
// Default address of the chargen font (upper case)
/// Default address of the chargen font (upper case)
char * const DEFAULT_FONT_UPPER = (char*)0x1000;
// Default address of the chargen font (mixed case)
/// Default address of the chargen font (mixed case)
char * const DEFAULT_FONT_MIXED = (char*)0x1800;
// The CIA#1: keyboard matrix, joystick #1/#2
/// The CIA#1: keyboard matrix, joystick #1/#2
struct MOS6526_CIA * const CIA1 = (struct MOS6526_CIA *)0xdc00;
// The CIA#2: Serial bus, RS-232, VIC memory bank
/// The CIA#2: Serial bus, RS-232, VIC memory bank
struct MOS6526_CIA * const CIA2 = (struct MOS6526_CIA *)0xdd00;
// CIA#1 Interrupt for reading in ASM
/// CIA#1 Interrupt for reading in ASM
char * const CIA1_INTERRUPT = (char*)0xdc0d;
// CIA#2 timer A&B as one single 32-bit value
/// CIA#2 timer A&B as one single 32-bit value
unsigned long* const CIA2_TIMER_AB = (unsigned long*)0xdd04;
// CIA#2 Interrupt for reading in ASM
/// CIA#2 Interrupt for reading in ASM
char * const CIA2_INTERRUPT = (char*)0xdd0d;
// Pointer to interrupt function
/// Pointer to interrupt function
typedef void (*IRQ_TYPE)(void);
// The vector used when the KERNAL serves IRQ interrupts
/// The vector used when the KERNAL serves IRQ interrupts
IRQ_TYPE * const KERNEL_IRQ = (IRQ_TYPE*)0x0314;
// The vector used when the KERNAL serves NMI interrupts
/// The vector used when the KERNAL serves NMI interrupts
IRQ_TYPE * const KERNEL_NMI = (IRQ_TYPE*)0x0318;
// The vector used when the HARDWARE serves IRQ interrupts
/// The vector used when the HARDWARE serves IRQ interrupts
IRQ_TYPE * const HARDWARE_IRQ = (IRQ_TYPE*)0xfffe;
// The colors of the C64
/// The colors of the C64
const char BLACK = 0x0;
const char WHITE = 0x1;
const char RED = 0x2;
@ -81,25 +82,29 @@ const char LIGHT_GREEN = 0xd;
const char LIGHT_BLUE = 0xe;
const char LIGHT_GREY = 0xf;
// Get the value to store into D018 to display a specific screen and charset/bitmap
// Optimized for ASM from (char)((((unsigned int)screen&0x3fff)/0x40)|(((unsigned int)charset&0x3fff)/0x400));
/// @brief Get the value to store into D018 to display a specific screen and charset/bitmap
///
/// Optimized for ASM from (char)((((unsigned int)screen&0x3fff)/0x40)|(((unsigned int)charset&0x3fff)/0x400));
char toD018(char* screen, char* gfx);
// Get the value to store into DD00 (CIA 2 port A) to choose a specific VIC bank
// Optimized for ASM from %00000011 ^ (char)((unsigned int)gfx/0x4000)
/// @brief Get the value to store into DD00 (CIA 2 port A) to choose a specific VIC bank
///
/// Optimized for ASM from %00000011 ^ (char)((unsigned int)gfx/0x4000)
char toDd00(char* gfx);
// Get the sprite pointer for a sprite.
// The sprite pointer is the index of the sprite within the graphics bank and equal to the sprite (char)(sprite_addr/64)
// The sprite pointers are stored SCREEN+0x3f8+sprite_id to set the pointer of each sprite
/// @brief Get the sprite pointer for a sprite.
///
/// The sprite pointer is the index of the sprite within the graphics bank and equal to the sprite (char)(sprite_addr/64)
/// The sprite pointers are stored SCREEN+0x3f8+sprite_id to set the pointer of each sprite
char toSpritePtr(char* sprite);
// Select a specific VIC graphics bank by setting the CIA 2 port A (0xdd00) as needed
/// Select a specific VIC graphics bank by setting the CIA 2 port A (0xdd00) as needed
void vicSelectGfxBank(char* gfx);
// Initialize SID voice 3 for random number generation
/// Initialize SID voice 3 for random number generation
void sid_rnd_init();
// Get a random number from the SID voice 3,
// Must be initialized with sid_rnd_init()
/// @brief Get a random number from the SID voice 3,
///
/// Must be initialized with sid_rnd_init()
char sid_rnd();

View File

@ -1,18 +1,18 @@
// C64 DTV version 2 Registers and Constants
/// 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
/// 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
#include <c64dtv.h>
#include <c64.h>
// Feature enables or disables the extra C64 DTV features
/// Feature enables or disables the extra C64 DTV features
char* const DTV_FEATURE = (char*)$d03f;
const char DTV_FEATURE_ENABLE = 1;
const char DTV_FEATURE_DISABLE_TIL_RESET = 2;
// Controls the graphics modes of the C64 DTV
/// Controls the graphics modes of the C64 DTV
char* const DTV_CONTROL = (char*)$d03c;
const char DTV_LINEAR = $01;
const char DTV_BORDER_OFF = $02;
@ -22,13 +22,13 @@ const char DTV_COLORRAM_OFF = $10;
const char DTV_BADLINE_OFF = $20;
const char DTV_CHUNKY = $40;
// Defines colors for the 16 first colors ($00-$0f)
/// Defines colors for the 16 first colors ($00-$0f)
char* const DTV_PALETTE = (char*)$d200;
// Default vallues for the palette
/// Default vallues for the palette
char DTV_PALETTE_DEFAULT[16] = { $00, $0f, $36, $be, $58, $db, $86, $ff, $29, $26, $3b, $05, $07, $df, $9a, $0a };
// Linear Graphics Plane A Counter Control
/// Linear Graphics Plane A Counter Control
char* const DTV_PLANEA_START_LO = (char*)$d03a;
char* const DTV_PLANEA_START_MI = (char*)$d03b;
char* const DTV_PLANEA_START_HI = (char*)$d045;
@ -36,7 +36,7 @@ char* const DTV_PLANEA_STEP = (char*)$d046;
char* const DTV_PLANEA_MODULO_LO = (char*)$d038;
char* const DTV_PLANEA_MODULO_HI = (char*)$d039;
// Linear Graphics Plane B Counter Control
/// Linear Graphics Plane B Counter Control
char* const DTV_PLANEB_START_LO = (char*)$d049;
char* const DTV_PLANEB_START_MI = (char*)$d04a;
char* const DTV_PLANEB_START_HI = (char*)$d04b;
@ -44,102 +44,102 @@ char* const DTV_PLANEB_STEP = (char*)$d04c;
char* const DTV_PLANEB_MODULO_LO = (char*)$d047;
char* const DTV_PLANEB_MODULO_HI = (char*)$d048;
// Select memory bank where sprite data is fetched from (bits 5:0) - source only (J)
// Memory address of Sprite RAM is SpriteBank*$10000
/// Select memory bank where sprite data is fetched from (bits 5:0) - source only (J)
/// Memory address of Sprite RAM is SpriteBank*$10000
char* const DTV_SPRITE_BANK = (char*)$d04d;
// Select memory bank where color data is fetched from (bits 11:0)
// Memory address of Color RAM is ColorBank*$400
/// Select memory bank where color data is fetched from (bits 11:0)
/// Memory address of Color RAM is ColorBank*$400
char* const DTV_COLOR_BANK_LO = (char*)$d036;
char* const DTV_COLOR_BANK_HI = (char*)$d037;
const unsigned long DTV_COLOR_BANK_DEFAULT = $1d800;
// Selects memory bank for normal VIC color mode and lower data for high color modes. (bits 5:0)
// Memory address of VIC Graphics is GraphicsBank*$10000
/// Selects memory bank for normal VIC color mode and lower data for high color modes. (bits 5:0)
/// Memory address of VIC Graphics is GraphicsBank*$10000
char* const DTV_GRAPHICS_VIC_BANK = (char*)$d03d;
// Selects memory bank for upper data for high color modes. (bits 5:0) - source only (H)
/// Selects memory bank for upper data for high color modes. (bits 5:0) - source only (H)
char* const DTV_GRAPHICS_HICOL_BANK = (char*)$d03e;
// 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
/// 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(char cpuBankIdx);
// Blitter Source A Start
/// Blitter Source A Start
char* const DTV_BLITTER_SRCA_LO = (char*)$d320;
char* const DTV_BLITTER_SRCA_MI = (char*)$d321;
char* const DTV_BLITTER_SRCA_HI = (char*)$d322;
// Blitter Source A Modulo
/// Blitter Source A Modulo
char* const DTV_BLITTER_SRCA_MOD_LO = (char*)$d323;
char* const DTV_BLITTER_SRCA_MOD_HI = (char*)$d324;
// Blitter Source A Line Length
/// Blitter Source A Line Length
char* const DTV_BLITTER_SRCA_LIN_LO = (char*)$d325;
char* const DTV_BLITTER_SRCA_LIN_HI = (char*)$d326;
// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
/// Blitter Source A Step ([7:4] integral part, [3:0] fractional part)
char* const DTV_BLITTER_SRCA_STEP = (char*)$d327;
// Blitter Source B Start
/// Blitter Source B Start
char* const DTV_BLITTER_SRCB_LO = (char*)$d328;
char* const DTV_BLITTER_SRCB_MI = (char*)$d329;
char* const DTV_BLITTER_SRCB_HI = (char*)$d32a;
// Blitter Source B Modulo
/// Blitter Source B Modulo
char* const DTV_BLITTER_SRCB_MOD_LO = (char*)$d32b;
char* const DTV_BLITTER_SRCB_MOD_HI = (char*)$d32c;
// Blitter Source B Line Length
/// Blitter Source B Line Length
char* const DTV_BLITTER_SRCB_LIN_LO = (char*)$d32d;
char* const DTV_BLITTER_SRCB_LIN_HI = (char*)$d32e;
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
/// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
char* const DTV_BLITTER_SRCB_STEP = (char*)$d32f;
// Blitter Destination Start
/// Blitter Destination Start
char* const DTV_BLITTER_DEST_LO = (char*)$d330;
char* const DTV_BLITTER_DEST_MI = (char*)$d331;
char* const DTV_BLITTER_DEST_HI = (char*)$d332;
// Blitter Source B Modulo
/// Blitter Source B Modulo
char* const DTV_BLITTER_DEST_MOD_LO = (char*)$d333;
char* const DTV_BLITTER_DEST_MOD_HI = (char*)$d334;
// Blitter Source B Line Length
/// Blitter Source B Line Length
char* const DTV_BLITTER_DEST_LIN_LO = (char*)$d335;
char* const DTV_BLITTER_DEST_LIN_HI = (char*)$d336;
// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
/// Blitter Source B Step ([7:4] integral part, [3:0] fractional part)
char* const DTV_BLITTER_DEST_STEP = (char*)$d337;
// Blitter Blit Length
/// Blitter Blit Length
char* const DTV_BLITTER_LEN_LO = (char*)$d338;
char* const DTV_BLITTER_LEN_HI = (char*)$d339;
// Blitter Control
/// Blitter Control
char* const DTV_BLITTER_CONTROL = (char*)$d33a;
// Bit[0] Force Start Strobe when set
/// Bit[0] Force Start Strobe when set
const char DTV_BLIT_FORCE_START = %00000001;
// Bit[1] Source A Direction Positive when set
/// Bit[1] Source A Direction Positive when set
const char DTV_BLIT_SRCA_FWD = %00000010;
// Bit[2] Source B Direction Positive when set
/// Bit[2] Source B Direction Positive when set
const char DTV_BLIT_SRCB_FWD = %00000100;
// Bit[3] Destination Direction Positive when set
/// Bit[3] Destination Direction Positive when set
const char DTV_BLIT_DEST_FWD = %00001000;
// Bit[4] VIC IRQ Start when set
/// Bit[4] VIC IRQ Start when set
const char DTV_BLIT_VIC_IRQ = %00010000;
// Bit[5] CIA IRQ Start when set($DCXX CIA)
/// Bit[5] CIA IRQ Start when set($DCXX CIA)
const char DTV_BLIT_CIA_IRQ = %00100000;
// Bit[6] V Blank Start when set
/// Bit[6] V Blank Start when set
const char DTV_BLIT_VBLANK = %01000000;
// Bit[7] Blitter IRQ Enable when set
/// Bit[7] Blitter IRQ Enable when set
const char DTV_BLIT_IRQ_EN = %10000000;
// Blitter Transparency
/// Blitter Transparency
char* const DTV_BLITTER_TRANSPARANCY = (char*)$d33b;
// Bit[0] Disable Channel B.
// (data into b port of ALU is forced to %00000000. ALU functions as normal)
/// Bit[0] Disable Channel B.
/// (data into b port of ALU is forced to %00000000. ALU functions as normal)
const char DTV_BLIT_DISABLE_B = %00000001;
// Bit[1] Write Transparent Data when set
/// Bit[1] Write Transparent Data when set
//(Data will be written if source a data *IS* %00000000. This can be used with channel b and ALU set to OR to write Data masked by source A.) Cycles will be saved if No writes.
const char DTV_BLIT_WRITE_TRANSPARENT = %00000010;
// Bit[2] Write Non Transparent
// when set (Data will be written if SourceA fetched data is *NOT* %00000000. This may be used combined with channel b data and/or ALU) Cycles will be Saved if no write. Bit[2]==Bit[1]==0: write in any case
/// Bit[2] Write Non Transparent
/// when set (Data will be written if SourceA fetched data is *NOT* %00000000. This may be used combined with channel b data and/or ALU) Cycles will be Saved if no write. Bit[2]==Bit[1]==0: write in any case
const char DTV_BLIT_WRITE_NONTRANSPARENT = %00000100;
// No transparancy
// Bit[2]==Bit[1]==0: write in any case
/// No transparancy
/// Bit[2]==Bit[1]==0: write in any case
const char DTV_BLIT_TRANSPARANCY_NONE = %00000000;
// Controls the ALU operation
/// Controls the ALU operation
char* DTV_BLITTER_ALU = (char*)$d33e;
// Bit[2:0] Source A right Shift: 000 SourceA Data, 001 LastA[0],SourceA[7:1], ..., 111 LastA[6:0],SourceA[7]
/// Bit[2:0] Source A right Shift: 000 SourceA Data, 001 LastA[0],SourceA[7:1], ..., 111 LastA[6:0],SourceA[7]
const char DTV_BLIT_SHIFT0 = %00000000;
const char DTV_BLIT_SHIFT1 = %00000001;
const char DTV_BLIT_SHIFT2 = %00000010;
@ -148,7 +148,7 @@ const char DTV_BLIT_SHIFT4 = %00000100;
const char DTV_BLIT_SHIFT5 = %00000101;
const char DTV_BLIT_SHIFT6 = %00000110;
const char DTV_BLIT_SHIFT7 = %00000111;
// Bit[5:3] Minterms/ALU
/// Bit[5:3] Minterms/ALU
const char DTV_BLIT_AND = %00000000;
const char DTV_BLIT_NAND = %00001000;
const char DTV_BLIT_NOR = %00010000;
@ -157,17 +157,17 @@ const char DTV_BLIT_XOR = %00100000;
const char DTV_BLIT_XNOR = %00101000;
const char DTV_BLIT_ADD = %00110000;
const char DTV_BLIT_SUB = %00111000;
// Blitter Control 2
/// Blitter Control 2
char* const DTV_BLITTER_CONTROL2 = (char*)$d33f;
// Bit[0] Clear Blitter IRQ
/// Bit[0] Clear Blitter IRQ
const char DTV_BLIT_CLEAR_IRQ = %00000001;
// Bit[1] Source A Continue
/// Bit[1] Source A Continue
const char DTV_BLIT_SRCA_CONT = %00000010;
// Bit[2] Source B Continue
/// Bit[2] Source B Continue
const char DTV_BLIT_SRCB_CONT = %00000100;
// Bit[3] Destination Continue
/// Bit[3] Destination Continue
const char DTV_BLIT_DEST_CONT = %00001000;
// Bit[0] Busy when set (When reading)
/// Bit[0] Busy when set (When reading)
const char DTV_BLIT_STATUS_BUSY = %00000001;
// Bit[1] IRQ when set (When reading)
/// Bit[1] IRQ when set (When reading)
const char DTV_BLIT_STATUS_IRQ = %00000010;

View File

@ -1,14 +1,14 @@
// Commodore Kernal functions
// See http://www.c64os.com/post/c64kernalrom#iec_acptr
// Compatible with https://github.com/cc65/cc65/blob/master/include/cbm.h
/// Commodore Kernal functions
/// See http://www.c64os.com/post/c64kernalrom#iec_acptr
/// Compatible with https://github.com/cc65/cc65/blob/master/include/cbm.h
// Constants to use with cbm_open() for opening a file for reading or writing without the need to append ",r" or ",w" to the filename.
/// Constants to use with cbm_open() for opening a file for reading or writing without the need to append ",r" or ",w" to the filename.
#define CBM_READ 0 /* default is ",p" */
#define CBM_WRITE 1 /* ditto */
#define CBM_SEQ 2 /* default is ",r" -- or ",s" when writing */
// IEC
// Read one byte from talking device
/// IEC
/// Read one byte from talking device
unsigned char cbm_k_acptr (void);
unsigned char cbm_k_chkin (unsigned char FN);
@ -17,8 +17,8 @@ unsigned char cbm_k_ckout (unsigned char FN);
void cbm_k_clall (void);
void cbm_k_clrch (void);
// Read a byte from the input channel
// return: next byte in buffer or 0 if buffer is empty.
/// Read a byte from the input channel
/// return: next byte in buffer or 0 if buffer is empty.
unsigned char cbm_k_getin (void);
unsigned cbm_k_iobase (void);
@ -27,33 +27,33 @@ unsigned char cbm_k_readst (void);
void cbm_k_scnkey (void);
void cbm_k_second (unsigned char addr);
// Set logical file number, device number and secondary address
// lfn: logical file number
// dev: device number
// sa: secondary address
/// Set logical file number, device number and secondary address
/// lfn: logical file number
/// dev: device number
/// sa: secondary address
void cbm_k_setlfs(unsigned char lfn, unsigned char dev, unsigned char sa);
// Set filename or command string
// name: file name
/// Set filename or command string
/// name: file name
void cbm_k_setnam (const char* name);
// Open logical file
/// Open logical file
unsigned char cbm_k_open (void);
// Close logical file
// lfn: Logical file number
/// Close logical file
/// lfn: Logical file number
void cbm_k_close (unsigned char lfn);
// Load or Verify data
// flag: load=0, verify=1
// addr: pointer to start address
// returns pointer to last byte loaded
/// Load or Verify data
/// flag: load=0, verify=1
/// addr: pointer to start address
/// returns pointer to last byte loaded
char* cbm_k_load(unsigned char flag, char* addr);
// Save memory to disk/tape
// start: pointer to start address
// end: End address
// return:
/// Save memory to disk/tape
/// start: pointer to start address
/// end: End address
/// return:
unsigned char cbm_k_save(char* start, char* end);
void cbm_k_settim (unsigned long timer);

View File

@ -1,32 +1,32 @@
// Provides provide simple horisontal/vertical lines routines on top of conio.h
// For compatibility with CC65 https://github.com/cc65/cc65/blob/master/include/conio.h
/// Provides provide simple horisontal/vertical lines routines on top of conio.h
/// For compatibility with CC65 https://github.com/cc65/cc65/blob/master/include/conio.h
#include <conio.h>
// The horizontal line character
/// The horizontal line character
const char CH_HLINE = 0x40;
// The vertical line character
/// The vertical line character
const char CH_VLINE = 0x5d;
// The upper left corner character
/// The upper left corner character
const char CH_ULCORNER = 0x70;
// The upper right corner character
/// The upper right corner character
const char CH_URCORNER = 0x6e;
// The lower left corner character
/// The lower left corner character
const char CH_LLCORNER = 0x6d;
// The lower right corner character
/// The lower right corner character
const char CH_LRCORNER = 0x7d;
// The left T character
/// The left T character
const char CH_LTEE = 0x6b;
// The right T character
/// The right T character
const char CH_RTEE = 0x73;
// Output a horizontal line with the given length starting at the current cursor position.
/// Output a horizontal line with the given length starting at the current cursor position.
void chline(unsigned char length);
// Output a vertical line with the given length at the current cursor position.
/// Output a vertical line with the given length at the current cursor position.
void cvline(unsigned char length);
// Move cursor and output a vertical line with the given length
// Same as "gotoxy (x, y); cvline (length);"
/// Move cursor and output a vertical line with the given length
/// Same as "gotoxy (x, y); cvline (length);"
void cvlinexy(unsigned char x, unsigned char y, unsigned char length);

View File

@ -1,65 +1,65 @@
// Provides provide console input/output
// Implements similar functions as conio.h from CC65 for compatibility
// See https://github.com/cc65/cc65/blob/master/include/conio.h
/// Provides provide console input/output
/// Implements similar functions as conio.h from CC65 for compatibility
/// See https://github.com/cc65/cc65/blob/master/include/conio.h
//
// Currently C64/PLUS4/VIC20 platforms are supported
/// Currently C64/PLUS4/VIC20 platforms are supported
// clears the screen and moves the cursor to the upper left-hand corner of the screen.
/// clears the screen and moves the cursor to the upper left-hand corner of the screen.
void clrscr(void);
// Set the cursor to the specified position
/// Set the cursor to the specified position
void gotoxy(unsigned char x, unsigned char y);
// Return the X position of the cursor
/// Return the X position of the cursor
unsigned char wherex(void);
// Return the Y position of the cursor
/// Return the Y position of the cursor
unsigned char wherey(void);
// Return the current screen size.
/// Return the current screen size.
void screensize(unsigned char* x, unsigned char* y);
// Return the current screen size X width.
/// Return the current screen size X width.
char screensizex();
// Return the current screen size Y height.
/// Return the current screen size Y height.
char screensizey();
// Output one character at the current cursor position. Scroll the screen if needed.
/// Output one character at the current cursor position. Scroll the screen if needed.
void cputc(char c);
// Move teh cursor to the start of the next line. Scroll the screen if needed.
/// Move teh cursor to the start of the next line. Scroll the screen if needed.
void cputln();
// Move cursor and output one character
// Same as "gotoxy (x, y); cputc (c);"
/// Move cursor and output one character
/// Same as "gotoxy (x, y); cputc (c);"
void cputcxy(unsigned char x, unsigned char y, char c);
// Output a NUL-terminated string at the current cursor position
/// Output a NUL-terminated string at the current cursor position
void cputs(const char* s);
// Move cursor and output a NUL-terminated string
// Same as "gotoxy (x, y); puts (s);"
/// Move cursor and output a NUL-terminated string
/// Same as "gotoxy (x, y); puts (s);"
void cputsxy(unsigned char x, unsigned char y, const char* s);
// Set the color for text output. The old color setting is returned.
/// Set the color for text output. The old color setting is returned.
unsigned char textcolor(unsigned char color);
// Set the color for the background. The old color setting is returned.
/// Set the color for the background. The old color setting is returned.
unsigned char bgcolor(unsigned char color);
// Set the color for the border. The old color setting is returned.
/// Set the color for the border. The old color setting is returned.
unsigned char bordercolor(unsigned char color);
// Return true if there's a key waiting, return false if not
/// Return true if there's a key waiting, return false if not
unsigned char kbhit (void);
// If onoff is 1, a cursor is displayed when waiting for keyboard input.
// If onoff is 0, the cursor is hidden when waiting for keyboard input.
// The function returns the old cursor setting.
/// If onoff is 1, a cursor is displayed when waiting for keyboard input.
/// If onoff is 0, the cursor is hidden when waiting for keyboard input.
/// The function returns the old cursor setting.
unsigned char cursor(unsigned char onoff);
// If onoff is 1, scrolling is enabled when outputting past the end of the screen
// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
// The function returns the old scroll setting.
/// If onoff is 1, scrolling is enabled when outputting past the end of the screen
/// If onoff is 0, scrolling is disabled and the cursor instead moves to (0,0)
/// The function returns the old scroll setting.
unsigned char scroll(unsigned char onoff);

View File

@ -1,5 +1,5 @@
// Functions that are useful for testing and mapping characters.
/// Functions that are useful for testing and mapping characters.
// Convert lowercase alphabet to uppercase
// Returns uppercase equivalent to c, if such value exists, else c remains unchanged
/// Convert lowercase alphabet to uppercase
/// Returns uppercase equivalent to c, if such value exists, else c remains unchanged
char toupper(char ch);

View File

@ -1,13 +1,13 @@
// Plot and line drawing routines for HIRES bitmaps
// Currently it can only plot on the first 256 x-positions.
/// Plot and line drawing routines for HIRES bitmaps
/// Currently it can only plot on the first 256 x-positions.
// Initialize the bitmap plotter tables for a specific bitmap
/// Initialize the bitmap plotter tables for a specific bitmap
void bitmap_init(byte layer, dword address);
// Clear all graphics on the bitmap
/// Clear all graphics on the bitmap
void bitmap_clear();
void bitmap_plot(word x, word y, byte c);
// Draw a line on the bitmap
/// Draw a line on the bitmap
void bitmap_line(word x0, word x1, word y0, word y1, byte c);

View File

@ -1,15 +1,15 @@
// Kernal SETNAM function
// SETNAM. Set file name parameters.
/// Kernal SETNAM function
/// SETNAM. Set file name parameters.
void setnam(char* filename);
// SETLFS. Set file parameters.
/// SETLFS. Set file parameters.
void setlfs(char device);
// LOAD. Load or verify file. (Must call SETLFS and SETNAM beforehands.)
// - verify: 0 = Load, 1-255 = Verify
// Returns a status, 0xff: Success other: Kernal Error Code
/// LOAD. Load or verify file. (Must call SETLFS and SETNAM beforehands.)
/// - verify: 0 = Load, 1-255 = Verify
/// Returns a status, 0xff: Success other: Kernal Error Code
char load(char* address, char verify);
// GETIN. Read a byte from the input channel
// return: next byte in buffer or 0 if buffer is empty.
/// GETIN. Read a byte from the input channel
/// return: next byte in buffer or 0 if buffer is empty.
char getin();

View File

@ -1,7 +1,7 @@
// Commander X16 VERA (Versatile Embedded Retro Adapter) Video and Audio Processor
// https://github.com/commanderx16/x16-docs/blob/master/VERA%20Programmer's%20Reference.md
/// Commander X16 VERA (Versatile Embedded Retro Adapter) Video and Audio Processor
/// https://github.com/commanderx16/x16-docs/blob/master/VERA%20Programmer's%20Reference.md
// The colors of the CX16
/// The colors of the CX16
const char BLACK = 0x0;
const char WHITE = 0x1;
const char RED = 0x2;
@ -19,24 +19,24 @@ const char LIGHT_GREEN = 0xd;
const char LIGHT_BLUE = 0xe;
const char LIGHT_GREY = 0xf;
// To access the VRAM (which is 128kB in size) an indirection mechanism is used.
// First the address to be accessed needs to be set (ADDRx_L/ADDRx_M/ADDRx_H) and
// then the data on that VRAM address can be read from or written to via the DATA0/1 register.
// To make accessing the VRAM more efficient an auto-increment mechanism is present.
// These 3 registers are multiplexed using the ADDR_SEL in the CTRL register.
// When ADDR_SEL = 0, ADDRx_L/ADDRx_M/ADDRx_H become ADDR0_L/ADDR0_M/ADDR0_H.
// When ADDR_SEL = 1, ADDRx_L/ADDRx_M/ADDRx_H become ADDR1_L/ADDR1_M/ADDR1_H.
// See https://github.com/commanderx16/x16-emulator/wiki/(VERA-0.8)-Registers-$9F23-and-$9F24-(and-$9F25)
/// To access the VRAM (which is 128kB in size) an indirection mechanism is used.
/// First the address to be accessed needs to be set (ADDRx_L/ADDRx_M/ADDRx_H) and
/// then the data on that VRAM address can be read from or written to via the DATA0/1 register.
/// To make accessing the VRAM more efficient an auto-increment mechanism is present.
/// These 3 registers are multiplexed using the ADDR_SEL in the CTRL register.
/// When ADDR_SEL = 0, ADDRx_L/ADDRx_M/ADDRx_H become ADDR0_L/ADDR0_M/ADDR0_H.
/// When ADDR_SEL = 1, ADDRx_L/ADDRx_M/ADDRx_H become ADDR1_L/ADDR1_M/ADDR1_H.
/// See https://github.com/commanderx16/x16-emulator/wiki/(VERA-0.8)-Registers-$9F23-and-$9F24-(and-$9F25)
// $9F20 VRAM Address (7:0)
/// $9F20 VRAM Address (7:0)
char * const VERA_ADDRX_L = (char*)0x9f20;
// $9F21 VRAM Address (15:8)
/// $9F21 VRAM Address (15:8)
char * const VERA_ADDRX_M = (char*)0x9f21;
// $9F22 VRAM Address (7:0)
// Bit 4-7: Address Increment The following is the amount incremented per value value:increment
// 0:0, 1:1, 2:2, 3:4, 4:8, 5:16, 6:32, 7:64, 8:128, 9:256, 10:512, 11:40, 12:80, 13:160, 14:320, 15:640
// Bit 3: DECR Setting the DECR bit, will decrement instead of increment by the value set by the 'Address Increment' field.
// Bit 0: VRAM Address (16)
/// $9F22 VRAM Address (7:0)
/// Bit 4-7: Address Increment The following is the amount incremented per value value:increment
/// 0:0, 1:1, 2:2, 3:4, 4:8, 5:16, 6:32, 7:64, 8:128, 9:256, 10:512, 11:40, 12:80, 13:160, 14:320, 15:640
/// Bit 3: DECR Setting the DECR bit, will decrement instead of increment by the value set by the 'Address Increment' field.
/// Bit 0: VRAM Address (16)
char * const VERA_ADDRX_H = (char*)0x9f22;
const char VERA_INC_0 = 0x00;
const char VERA_INC_1 = 0x10;
@ -70,50 +70,50 @@ const char VERA_DECR_80 = 0xc8;
const char VERA_DECR_160 = 0xd8;
const char VERA_DECR_320 = 0xe8;
const char VERA_DECR_640 = 0xf8;
// $9F23 DATA0 VRAM Data port 0
/// $9F23 DATA0 VRAM Data port 0
char * const VERA_DATA0 = (char*)0x9f23;
// $9F24 DATA1 VRAM Data port 1
/// $9F24 DATA1 VRAM Data port 1
char * const VERA_DATA1 = (char*)0x9f24;
// $9F25 CTRL Control
// Bit 7: Reset
// Bit 1: DCSEL
// Bit 2: ADDRSEL
/// $9F25 CTRL Control
/// Bit 7: Reset
/// Bit 1: DCSEL
/// Bit 2: ADDRSEL
char * const VERA_CTRL = (char*)0x9f25;
const char VERA_DCSEL = 2;
const char VERA_ADDRSEL = 1;
// $9F26 IEN Interrupt Enable
// Bit 7: IRQ line (8)
// Bit 3: AFLOW
// Bit 2: SPRCOL
// Bit 1: LINE
// Bit 0: VSYNC
/// $9F26 IEN Interrupt Enable
/// Bit 7: IRQ line (8)
/// Bit 3: AFLOW
/// Bit 2: SPRCOL
/// Bit 1: LINE
/// Bit 0: VSYNC
char * const VERA_IEN = (char*)0x9f26;
const char VERA_AFLOW = 8;
const char VERA_SPRCOL = 4;
const char VERA_LINE = 2;
const char VERA_VSYNC = 1;
// $9F27 ISR Interrupt Status
// Interrupts will be generated for the interrupt sources set in the lower 4 bits of IEN. ISR will indicate the interrupts that have occurred.
// Writing a 1 to one of the lower 3 bits in ISR will clear that interrupt status. AFLOW can only be cleared by filling the audio FIFO for at least 1/4.
// Bit 4-7: Sprite Collisions. This field indicates which groups of sprites have collided.
// Bit 3: AFLOW
// Bit 2: SPRCOL
// Bit 1: LINE
// Bit 0: VSYNC
/// $9F27 ISR Interrupt Status
/// Interrupts will be generated for the interrupt sources set in the lower 4 bits of IEN. ISR will indicate the interrupts that have occurred.
/// Writing a 1 to one of the lower 3 bits in ISR will clear that interrupt status. AFLOW can only be cleared by filling the audio FIFO for at least 1/4.
/// Bit 4-7: Sprite Collisions. This field indicates which groups of sprites have collided.
/// Bit 3: AFLOW
/// Bit 2: SPRCOL
/// Bit 1: LINE
/// Bit 0: VSYNC
char * const VERA_ISR = (char*)0x9f27;
// $9F28 IRQLINE_L IRQ line (7:0)
// IRQ_LINE specifies at which line the LINE interrupt will be generated.
// Note that bit 8 of this value is present in the IEN register.
// For interlaced modes the interrupt will be generated each field and the bit 0 of IRQ_LINE is ignored.
/// $9F28 IRQLINE_L IRQ line (7:0)
/// IRQ_LINE specifies at which line the LINE interrupt will be generated.
/// Note that bit 8 of this value is present in the IEN register.
/// For interlaced modes the interrupt will be generated each field and the bit 0 of IRQ_LINE is ignored.
char * const VERA_IRQLINE_L = (char*)0x9f28;
// $9F29 DC_VIDEO (DCSEL=0)
// Bit 7: Current Field Read-only bit which reflects the active interlaced field in composite and RGB modes. (0: even, 1: odd)
// Bit 6: Sprites Enable Enable output from the Sprites renderer
// Bit 5: Layer1 Enable Enable output from the Layer1 renderer
// Bit 4: Layer0 Enable Enable output from the Layer0 renderer
// Bit 2: Chroma Disable Setting 'Chroma Disable' disables output of chroma in NTSC composite mode and will give a better picture on a monochrome display. (Setting this bit will also disable the chroma output on the S-video output.)
// Bit 0-1: Output Mode 0: Video disabled, 1: VGA output, 2: NTSC composite, 3: RGB interlaced, composite sync (via VGA connector)
/// $9F29 DC_VIDEO (DCSEL=0)
/// Bit 7: Current Field Read-only bit which reflects the active interlaced field in composite and RGB modes. (0: even, 1: odd)
/// Bit 6: Sprites Enable Enable output from the Sprites renderer
/// Bit 5: Layer1 Enable Enable output from the Layer1 renderer
/// Bit 4: Layer0 Enable Enable output from the Layer0 renderer
/// Bit 2: Chroma Disable Setting 'Chroma Disable' disables output of chroma in NTSC composite mode and will give a better picture on a monochrome display. (Setting this bit will also disable the chroma output on the S-video output.)
/// Bit 0-1: Output Mode 0: Video disabled, 1: VGA output, 2: NTSC composite, 3: RGB interlaced, composite sync (via VGA connector)
char * const VERA_DC_VIDEO = (char*)0x9f29;
const char VERA_SPRITES_ENABLE = 0x40;
const char VERA_LAYER1_ENABLE = 0x20;
@ -123,24 +123,24 @@ const char VERA_OUTPUT_DISABLE = 0x00;
const char VERA_OUTPUT_VGA = 0x01;
const char VERA_OUTPUT_NTSC = 0x02;
const char VERA_OUTPUT_RGB = 0x03;
// $9F2A DC_HSCALE (DCSEL=0) Active Display H-Scale
/// $9F2A DC_HSCALE (DCSEL=0) Active Display H-Scale
char * const VERA_DC_HSCALE = (char*)0x9f2a;
// $9F2B DC_VSCALE (DCSEL=0) Active Display V-Scale
/// $9F2B DC_VSCALE (DCSEL=0) Active Display V-Scale
char * const VERA_DC_VSCALE = (char*)0x9f2b;
// $9F2C DC_BORDER (DCSEL=0) Border Color
/// $9F2C DC_BORDER (DCSEL=0) Border Color
char * const VERA_DC_BORDER = (char*)0x9f2c;
// $9F29 DC_HSTART (DCSEL=1) Active Display H-Start (9:2)
/// $9F29 DC_HSTART (DCSEL=1) Active Display H-Start (9:2)
char * const VERA_DC_HSTART = (char*)0x9f29;
// $9F2A DC_HSTOP (DCSEL=1) Active Display H-Stop (9:2)
/// $9F2A DC_HSTOP (DCSEL=1) Active Display H-Stop (9:2)
char * const VERA_DC_HSTOP = (char*)0x9f2a;
// $9F2B DC_VSTART (DCSEL=1) Active Display V-Start (8:1)
/// $9F2B DC_VSTART (DCSEL=1) Active Display V-Start (8:1)
char * const VERA_DC_VSTART = (char*)0x9f2b;
// $9F2C DC_VSTOP (DCSEL=1) Active Display V-Stop (8:1)
/// $9F2C DC_VSTOP (DCSEL=1) Active Display V-Stop (8:1)
char * const VERA_DC_VSTOP = (char*)0x9f2c;
// Configuration work tables
/// Configuration work tables
// Bit 4-5. Map Width (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles)
/// Bit 4-5. Map Width (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles)
byte const VERA_LAYER_WIDTH_32 = 0x00;
byte const VERA_LAYER_WIDTH_64 = 0x10;
byte const VERA_LAYER_WIDTH_128 = 0x20;
@ -148,7 +148,7 @@ byte const VERA_LAYER_WIDTH_256 = 0x30;
byte const VERA_LAYER_WIDTH_MASK = 0x30;
word const VERA_LAYER_WIDTH[4] = {32, 64, 128, 256};
// Bit 6-7: Map Height (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles)
/// Bit 6-7: Map Height (0:32 tiles, 1:64 tiles, 2:128 tiles, 3:256 tiles)
byte const VERA_LAYER_HEIGHT_32 = 0x00;
byte const VERA_LAYER_HEIGHT_64 = 0x40;
byte const VERA_LAYER_HEIGHT_128 = 0x80;
@ -156,7 +156,7 @@ byte const VERA_LAYER_HEIGHT_256 = 0xC0;
byte const VERA_LAYER_HEIGHT_MASK = 0xC0;
word const VERA_LAYER_HEIGHT[4] = {32, 64, 128, 256};
// Bit 0-1: Color Depth (0: 1 bpp, 1: 2 bpp, 2: 4 bpp, 3: 8 bpp)
/// Bit 0-1: Color Depth (0: 1 bpp, 1: 2 bpp, 2: 4 bpp, 3: 8 bpp)
byte const VERA_LAYER_COLOR_DEPTH_1BPP = 0x00;
byte const VERA_LAYER_COLOR_DEPTH_2BPP = 0x01;
byte const VERA_LAYER_COLOR_DEPTH_4BPP = 0x02;
@ -164,19 +164,19 @@ byte const VERA_LAYER_COLOR_DEPTH_8BPP = 0x03;
byte const VERA_LAYER_COLOR_DEPTH_MASK = 0x03;
byte const VERA_LAYER_COLOR_DEPTH[4] = {1, 2, 4, 8};
// $9F2D L0_CONFIG Layer 0 Configuration
/// $9F2D L0_CONFIG Layer 0 Configuration
char * const VERA_L0_CONFIG = (char*)0x9f2d;
// Bit 2: Bitmap Mode (0:tile mode, 1: bitmap mode)
/// Bit 2: Bitmap Mode (0:tile mode, 1: bitmap mode)
char const VERA_LAYER_CONFIG_MODE_TILE = 0x00;
char const VERA_LAYER_CONFIG_MODE_BITMAP = 0x04;
// Bit 3: T256C (0: tiles use a 16-color foreground and background color, 1: tiles use a 256-color foreground color) (only relevant in 1bpp modes)
/// Bit 3: T256C (0: tiles use a 16-color foreground and background color, 1: tiles use a 256-color foreground color) (only relevant in 1bpp modes)
char const VERA_LAYER_CONFIG_16C = 0x00;
char const VERA_LAYER_CONFIG_256C = 0x08;
// $9F2E L0_MAPBASE Layer 0 Map Base Address (16:9)
/// $9F2E L0_MAPBASE Layer 0 Map Base Address (16:9)
char * const VERA_L0_MAPBASE = (char*)0x9f2e;
// $9F2F L0_TILEBASE Layer 0 Tile Base
// Bit 2-7: Tile Base Address (16:11)
// Bit 1: Tile Height (0:8 pixels, 1:16 pixels)
/// $9F2F L0_TILEBASE Layer 0 Tile Base
/// Bit 2-7: Tile Base Address (16:11)
/// Bit 1: Tile Height (0:8 pixels, 1:16 pixels)
byte const VERA_TILEBASE_WIDTH_8 = 0x00;
byte const VERA_TILEBASE_WIDTH_16 = 0x01;
byte const VERA_TILEBASE_WIDTH_MASK = 0x01;
@ -184,63 +184,63 @@ byte const VERA_TILEBASE_HEIGHT_8 = 0x00;
byte const VERA_TILEBASE_HEIGHT_16 = 0x02;
byte const VERA_TILEBASE_HEIGHT_MASK = 0x02;
byte const VERA_LAYER_TILEBASE_MASK = 0xfC;
// Bit 0: Tile Width (0:8 pixels, 1:16 pixels)
/// Bit 0: Tile Width (0:8 pixels, 1:16 pixels)
char * const VERA_L0_TILEBASE = (char*)0x9f2f;
// $9F30 L0_HSCROLL_L Layer 0 H-Scroll (7:0)
/// $9F30 L0_HSCROLL_L Layer 0 H-Scroll (7:0)
char * const VERA_L0_HSCROLL_L = (char*)0x9f30;
// $9F31 L0_HSCROLL_H Layer 0 H-Scroll (11:8)
/// $9F31 L0_HSCROLL_H Layer 0 H-Scroll (11:8)
char * const VERA_L0_HSCROLL_H = (char*)0x9f31;
// $9F32 L0_VSCROLL_L Layer 0 V-Scroll (7:0)
/// $9F32 L0_VSCROLL_L Layer 0 V-Scroll (7:0)
char * const VERA_L0_VSCROLL_L = (char*)0x9f32;
// $9F33 L0_VSCROLL_H Layer 0 V-Scroll (11:8)
/// $9F33 L0_VSCROLL_H Layer 0 V-Scroll (11:8)
char * const VERA_L0_VSCROLL_H = (char*)0x9f33;
// $9F34 L1_CONFIG Layer 1 Configuration
/// $9F34 L1_CONFIG Layer 1 Configuration
char * const VERA_L1_CONFIG = (char*)0x9f34;
// $9F35 L1_MAPBASE Layer 1 Map Base Address (16:9)
/// $9F35 L1_MAPBASE Layer 1 Map Base Address (16:9)
char * const VERA_L1_MAPBASE = (char*)0x9f35;
// $9F36 L1_TILEBASE Layer 1 Tile Base
// Bit 2-7: Tile Base Address (16:11)
// Bit 1: Tile Height (0:8 pixels, 1:16 pixels)
// Bit 0: Tile Width (0:8 pixels, 1:16 pixels)
/// $9F36 L1_TILEBASE Layer 1 Tile Base
/// Bit 2-7: Tile Base Address (16:11)
/// Bit 1: Tile Height (0:8 pixels, 1:16 pixels)
/// Bit 0: Tile Width (0:8 pixels, 1:16 pixels)
char * const VERA_L1_TILEBASE = (char*)0x9f36;
// $9F37 L1_HSCROLL_L Layer 1 H-Scroll (7:0)
/// $9F37 L1_HSCROLL_L Layer 1 H-Scroll (7:0)
char * const VERA_L1_HSCROLL_L = (char*)0x9f37;
// $9F38 L1_HSCROLL_H Layer 1 H-Scroll (11:8)
/// $9F38 L1_HSCROLL_H Layer 1 H-Scroll (11:8)
char * const VERA_L1_HSCROLL_H = (char*)0x9f38;
// $9F39 L1_VSCROLL_L Layer 1 V-Scroll (7:0)
/// $9F39 L1_VSCROLL_L Layer 1 V-Scroll (7:0)
char * const VERA_L1_VSCROLL_L = (char*)0x9f39;
// $9F3A L1_VSCROLL_H Layer 1 V-Scroll (11:8)
/// $9F3A L1_VSCROLL_H Layer 1 V-Scroll (11:8)
char * const VERA_L1_VSCROLL_H = (char*)0x9f3a;
// $9F3B AUDIO_CTRL
// Bit 7: FIFO Full / FIFO Reset
// Bit 5: 16-Bit
// Bit 4: Stereo
// Bit 0-3: PCM Volume
/// $9F3B AUDIO_CTRL
/// Bit 7: FIFO Full / FIFO Reset
/// Bit 5: 16-Bit
/// Bit 4: Stereo
/// Bit 0-3: PCM Volume
char * const VERA_AUDIO_CTRL = (char*)0x9f3b;
// $9F3C AUDIO_RATE PCM Sample Rate
/// $9F3C AUDIO_RATE PCM Sample Rate
char * const VERA_AUDIO_RATE = (char*)0x9f3c;
// $9F3D AUDIO_DATA Audio FIFO data (write-only)
/// $9F3D AUDIO_DATA Audio FIFO data (write-only)
char * const VERA_AUDIO_DATA = (char*)0x9f3d;
// $9F3E SPI_DATA SPI Data
/// $9F3E SPI_DATA SPI Data
char * const VERA_SPI_DATA = (char*)0x9f3e;
// $9F3F SPI_CTRL SPI Control
// Bit 7: Busy
// Bit 1: Slow clock
// Bit 0: Select
/// $9F3F SPI_CTRL SPI Control
/// Bit 7: Busy
/// Bit 1: Slow clock
/// Bit 0: Select
char * const VERA_SPI_CTRL = (char*)0x9f3f;
// VERA Palette address in VRAM $1FA00 - $1FBFF
// 256 entries of 2 bytes
// byte 0 bits 4-7: Green
// byte 0 bits 0-3: Blue
// byte 1 bits 0-3: Red
/// VERA Palette address in VRAM $1FA00 - $1FBFF
/// 256 entries of 2 bytes
/// byte 0 bits 4-7: Green
/// byte 0 bits 0-3: Blue
/// byte 1 bits 0-3: Red
const unsigned long VERA_PALETTE = 0x1fa00;
// Sprite Attributes address in VERA VRAM $1FC00 - $1FFFF
/// Sprite Attributes address in VERA VRAM $1FC00 - $1FFFF
const unsigned long VERA_SPRITE_ATTR = 0x1fc00;
// The VERA structure of a sprite (8 bytes)
// 128*8 bytes located at $1FC00-$1FFFF
/// The VERA structure of a sprite (8 bytes)
/// 128*8 bytes located at $1FC00-$1FFFF
struct VERA_SPRITE {
// 0-1 ADDRESS Address and mode
// - bits 0-11: Address (16:5)
@ -263,7 +263,7 @@ struct VERA_SPRITE {
char CTRL2;
};
// 4BPP sprite mode (add to VERA_SPRITE.ADDR to enable)
/// 4BPP sprite mode (add to VERA_SPRITE.ADDR to enable)
const unsigned int VERA_SPRITE_4BPP = 0x0000;
// 8BPP sprite mode (add to VERA_SPRITE.ADDR to enable)
/// 8BPP sprite mode (add to VERA_SPRITE.ADDR to enable)
const unsigned int VERA_SPRITE_8BPP = 0x8000;

View File

@ -1,11 +1,11 @@
// Commander X16 VERA (Versatile Embedded Retro Adapter) Video and Audio Processor
// https://github.com/commanderx16/x16-docs/blob/master/VERA%20Programmer's%20Reference.md
/// Commander X16 VERA (Versatile Embedded Retro Adapter) Video and Audio Processor
/// https://github.com/commanderx16/x16-docs/blob/master/VERA%20Programmer's%20Reference.md
// Author: Sven Van de Velde
/// Author: Sven Van de Velde
#include <cx16-vera.h>
// --- VERA function encapsulation ---
/// --- VERA function encapsulation ---
__ma word vera_mapbase_offset[2] = {0,0};
__ma byte vera_mapbase_bank[2] = {0,0};
@ -37,13 +37,13 @@ byte vera_layer_backcolor[2] = {BLUE, BLUE};
byte hscale[4] = {0,128,64,32};
// --- VERA addressing ---
/// --- VERA addressing ---
inline void vera_vram_bank_offset(byte bank, word offset, byte incr);
inline void vera_vram_address0(dword bankaddr, byte incr);
inline void vera_vram_address1(dword bankaddr, byte incr);
// --- VERA active display management ---
/// --- VERA active display management ---
inline void vera_display_set_scale_none();
inline void vera_display_set_scale_double();
@ -53,35 +53,35 @@ byte vera_display_get_vscale();
word vera_display_get_height();
word vera_display_get_width();
// --- VERA LAYERS ---
/// --- VERA LAYERS ---
// Set the configuration of the layer.
// - layer: Value of 0 or 1.
// - config: Specifies the modes which are specified using T256C / 'Bitmap Mode' / 'Color Depth'.
/// Set the configuration of the layer.
/// - layer: Value of 0 or 1.
/// - config: Specifies the modes which are specified using T256C / 'Bitmap Mode' / 'Color Depth'.
void vera_layer_set_config(byte layer, byte config);
// Get the configuration of the layer.
// - layer: Value of 0 or 1.
// - return: Specifies the modes which are specified using T256C / 'Bitmap Mode' / 'Color Depth'.
/// Get the configuration of the layer.
/// - layer: Value of 0 or 1.
/// - return: Specifies the modes which are specified using T256C / 'Bitmap Mode' / 'Color Depth'.
byte vera_layer_get_config(byte layer);
// Set the configuration of the layer text color mode.
// - layer: Value of 0 or 1.
// - color_mode: Specifies the color mode to be VERA_LAYER_CONFIG_16 or VERA_LAYER_CONFIG_256 for text mode.
/// Set the configuration of the layer text color mode.
/// - layer: Value of 0 or 1.
/// - color_mode: Specifies the color mode to be VERA_LAYER_CONFIG_16 or VERA_LAYER_CONFIG_256 for text mode.
void vera_layer_set_text_color_mode( byte layer, byte color_mode );
// Set the configuration of the layer to bitmap mode.
// - layer: Value of 0 or 1.
/// Set the configuration of the layer to bitmap mode.
/// - layer: Value of 0 or 1.
void vera_layer_set_bitmap_mode( byte layer );
// Set the configuration of the layer to tilemap mode.
// - layer: Value of 0 or 1.
/// Set the configuration of the layer to tilemap mode.
/// - layer: Value of 0 or 1.
void vera_layer_set_tilemap_mode( byte layer );
// Set the map width or height of the layer.
// - layer: Value of 0 or 1.
/// Set the map width or height of the layer.
/// - layer: Value of 0 or 1.
inline void vera_layer_set_width_32(byte layer);
inline void vera_layer_set_width_64(byte layer);
inline void vera_layer_set_width_128(byte layer);
@ -91,238 +91,238 @@ inline void vera_layer_set_height_64(byte layer);
inline void vera_layer_set_height_128(byte layer);
inline void vera_layer_set_height_256(byte layer);
// Get the map width of the layer.
// - layer: Value of 0 or 1.
/// Get the map width of the layer.
/// - layer: Value of 0 or 1.
inline word vera_layer_get_width(byte layer);
// Get the map height of the layer.
// - layer: Value of 0 or 1.
/// Get the map height of the layer.
/// - layer: Value of 0 or 1.
inline word vera_layer_get_height(byte layer);
// Set the color depth of the layer in bit per pixel (BPP) to 1.
// - layer: Value of 0 or 1.
/// Set the color depth of the layer in bit per pixel (BPP) to 1.
/// - layer: Value of 0 or 1.
inline void vera_layer_set_color_depth_1BPP(byte layer);
// Set the color depth of the layer in bit per pixel (BPP) to 1.
// - layer: Value of 0 or 1.
/// Set the color depth of the layer in bit per pixel (BPP) to 1.
/// - layer: Value of 0 or 1.
inline void vera_layer_set_color_depth_2BPP(byte layer);
// Set the color depth of the layer in bit per pixel (BPP) to 1.
// - layer: Value of 0 or 1.
/// Set the color depth of the layer in bit per pixel (BPP) to 1.
/// - layer: Value of 0 or 1.
inline void vera_layer_set_color_depth_4BPP(byte layer);
// Set the color depth of the layer in bit per pixel (BPP) to 1.
// - layer: Value of 0 or 1.
/// Set the color depth of the layer in bit per pixel (BPP) to 1.
/// - layer: Value of 0 or 1.
inline void vera_layer_set_color_depth_8BPP(byte layer);
// Get the color depth of the layer.
// - layer: Value of 0 or 1.
// - return: 0 = 1 color, 1 = 2 colors, 2 = 4 colors or 3 = 8 colors.
/// Get the color depth of the layer.
/// - layer: Value of 0 or 1.
/// - return: 0 = 1 color, 1 = 2 colors, 2 = 4 colors or 3 = 8 colors.
inline byte vera_layer_get_color_depth(byte layer);
// Enable the layer to be displayed on the screen.
// - layer: 0 or 1.
/// Enable the layer to be displayed on the screen.
/// - layer: 0 or 1.
inline void vera_layer_show(byte layer);
// Disable the layer to be displayed on the screen.
// - layer: 0 or 1.
/// Disable the layer to be displayed on the screen.
/// - layer: 0 or 1.
inline void vera_layer_hide(byte layer);
// Is the layer shown on the screen?
// - returns: 1 if layer is displayed on the screen, 0 if not.
/// Is the layer shown on the screen?
/// - returns: 1 if layer is displayed on the screen, 0 if not.
inline byte vera_layer_is_visible(byte layer);
// Set the base of the map layer with which the conio will interact.
// - layer: Value of 0 or 1.
// - mapbase: Specifies the base address of the tile map.
// Note that the register only specifies bits 16:9 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
/// Set the base of the map layer with which the conio will interact.
/// - layer: Value of 0 or 1.
/// - mapbase: Specifies the base address of the tile map.
/// Note that the register only specifies bits 16:9 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
void vera_layer_set_mapbase(byte layer, byte mapbase);
// Set the base of the map layer with which the conio will interact.
// - layer: Value of 0 or 1.
// - mapbase_address: a dword typed address (4 bytes), that specifies the full address of the map base.
// The function does the translation from the dword that contains the 17 bit address,
// to the respective mapbase vera register.
// Note that the register only specifies bits 16:9 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
/// Set the base of the map layer with which the conio will interact.
/// - layer: Value of 0 or 1.
/// - mapbase_address: a dword typed address (4 bytes), that specifies the full address of the map base.
/// The function does the translation from the dword that contains the 17 bit address,
/// to the respective mapbase vera register.
/// Note that the register only specifies bits 16:9 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
void vera_layer_set_mapbase_address(byte layer, dword mapbase_address);
// Get the base of the map layer with which the conio will interact.
// - layer: Value of 0 or 1.
// - return: Returns the base address of the tile map.
// Note that the register is a byte, specifying only bits 16:9 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
/// Get the base of the map layer with which the conio will interact.
/// - layer: Value of 0 or 1.
/// - return: Returns the base address of the tile map.
/// Note that the register is a byte, specifying only bits 16:9 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
byte vera_layer_get_mapbase(byte layer);
// Get the map base address of the tiles for the layer.
// - layer: Value of 0 or 1.
// - return: Specifies the map base address of the layer, which is returned as a dword.
// Note that the register only specifies bits 16:9 of the 17 bit address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes!
/// Get the map base address of the tiles for the layer.
/// - layer: Value of 0 or 1.
/// - return: Specifies the map base address of the layer, which is returned as a dword.
/// Note that the register only specifies bits 16:9 of the 17 bit address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes!
dword vera_layer_get_mapbase_address(byte layer);
// Get the map base bank of the tiles for the layer.
// - layer: Value of 0 or 1.
// - return: Bank in vera vram.
/// Get the map base bank of the tiles for the layer.
/// - layer: Value of 0 or 1.
/// - return: Bank in vera vram.
byte vera_layer_get_mapbase_bank(byte layer);
// Get the map base lower 16-bit address (offset) of the tiles for the layer.
// - layer: Value of 0 or 1.
// - return: Offset in vera vram of the specified bank.
/// Get the map base lower 16-bit address (offset) of the tiles for the layer.
/// - layer: Value of 0 or 1.
/// - return: Offset in vera vram of the specified bank.
word vera_layer_get_mapbase_offset(byte layer);
// Set the base of the tiles for the layer with which the conio will interact.
// - layer: Value of 0 or 1.
// - tilebase: Specifies the base address of the tile map.
// Note that the register only specifies bits 16:11 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
/// Set the base of the tiles for the layer with which the conio will interact.
/// - layer: Value of 0 or 1.
/// - tilebase: Specifies the base address of the tile map.
/// Note that the register only specifies bits 16:11 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
void vera_layer_set_tilebase(byte layer, byte tilebase);
// Set the base address of the tiles for the layer with which the conio will interact.
// - layer: Value of 0 or 1.
// - tilebase_address: a dword typed address (4 bytes), that specifies the base address of the tile map.
// The function does the translation from the dword that contains the 17 bit address,
// to the respective tilebase vera register.
// Note that the resulting vera register holds only specifies bits 16:11 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
/// Set the base address of the tiles for the layer with which the conio will interact.
/// - layer: Value of 0 or 1.
/// - tilebase_address: a dword typed address (4 bytes), that specifies the base address of the tile map.
/// The function does the translation from the dword that contains the 17 bit address,
/// to the respective tilebase vera register.
/// Note that the resulting vera register holds only specifies bits 16:11 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
void vera_layer_set_tilebase_address(byte layer, dword tilebase_address);
// Get the base of the tiles for the layer with which the conio will interact.
// - layer: Value of 0 or 1.
// - return: Specifies the base address of the tile map.
// Note that the register only specifies bits 16:11 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
/// Get the base of the tiles for the layer with which the conio will interact.
/// - layer: Value of 0 or 1.
/// - return: Specifies the base address of the tile map.
/// Note that the register only specifies bits 16:11 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
byte vera_layer_get_tilebase(byte layer);
// Get the tile base address of the tiles for the layer.
// - layer: Value of 0 or 1.
// - return: Specifies the base address of the tile map, which is calculated as an unsigned long int.
// Note that the register only specifies bits 16:11 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
/// Get the tile base address of the tiles for the layer.
/// - layer: Value of 0 or 1.
/// - return: Specifies the base address of the tile map, which is calculated as an unsigned long int.
/// Note that the register only specifies bits 16:11 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
dword vera_layer_get_tilebase_address(byte layer);
// --- VERA layer color management ---
/// --- VERA layer color management ---
// Set the front color for text output. The old front text color setting is returned.
// - layer: Value of 0 or 1.
// - color: a 4 bit value ( decimal between 0 and 15) when the VERA works in 16x16 color text mode.
// An 8 bit value (decimal between 0 and 255) when the VERA works in 256 text mode.
// Note that on the VERA, the transparent color has value 0.
/// Set the front color for text output. The old front text color setting is returned.
/// - layer: Value of 0 or 1.
/// - color: a 4 bit value ( decimal between 0 and 15) when the VERA works in 16x16 color text mode.
/// An 8 bit value (decimal between 0 and 255) when the VERA works in 256 text mode.
/// Note that on the VERA, the transparent color has value 0.
byte vera_layer_set_textcolor(byte layer, byte color);
// Get the front color for text output. The old front text color setting is returned.
// - layer: Value of 0 or 1.
// - return: a 4 bit value ( decimal between 0 and 15).
// This will only work when the VERA is in 16 color mode!
// Note that on the VERA, the transparent color has value 0.
/// Get the front color for text output. The old front text color setting is returned.
/// - layer: Value of 0 or 1.
/// - return: a 4 bit value ( decimal between 0 and 15).
/// This will only work when the VERA is in 16 color mode!
/// Note that on the VERA, the transparent color has value 0.
byte vera_layer_get_textcolor(byte layer);
// Set the back color for text output. The old back text color setting is returned.
// - layer: Value of 0 or 1.
// - color: a 4 bit value ( decimal between 0 and 15).
// This will only work when the VERA is in 16 color mode!
// Note that on the VERA, the transparent color has value 0.
/// Set the back color for text output. The old back text color setting is returned.
/// - layer: Value of 0 or 1.
/// - color: a 4 bit value ( decimal between 0 and 15).
/// This will only work when the VERA is in 16 color mode!
/// Note that on the VERA, the transparent color has value 0.
byte vera_layer_set_backcolor(byte layer, byte color);
// Get the back color for text output. The old back text color setting is returned.
// - layer: Value of 0 or 1.
// - return: a 4 bit value ( decimal between 0 and 15).
// This will only work when the VERA is in 16 color mode!
// Note that on the VERA, the transparent color has value 0.
/// Get the back color for text output. The old back text color setting is returned.
/// - layer: Value of 0 or 1.
/// - return: a 4 bit value ( decimal between 0 and 15).
/// This will only work when the VERA is in 16 color mode!
/// Note that on the VERA, the transparent color has value 0.
byte vera_layer_get_backcolor(byte layer);
// Get the text and back color for text output in 16 color mode.
// - layer: Value of 0 or 1.
// - return: an 8 bit value with bit 7:4 containing the back color and bit 3:0 containing the front color.
// This will only work when the VERA is in 16 color mode!
// Note that on the VERA, the transparent color has value 0.
/// Get the text and back color for text output in 16 color mode.
/// - layer: Value of 0 or 1.
/// - return: an 8 bit value with bit 7:4 containing the back color and bit 3:0 containing the front color.
/// This will only work when the VERA is in 16 color mode!
/// Note that on the VERA, the transparent color has value 0.
byte vera_layer_get_color(byte layer);
// Scroll the horizontal (X) axis of the layer visible area over the layer tile map area.
// - layer: Value of 0 or 1.
// - scroll: A value between 0 and 4096.
/// Scroll the horizontal (X) axis of the layer visible area over the layer tile map area.
/// - layer: Value of 0 or 1.
/// - scroll: A value between 0 and 4096.
inline void vera_layer_set_horizontal_scroll(byte layer, word scroll);
// Scroll the vertical (Y) axis of the layer visible area over the layer tile map area.
// - layer: Value of 0 or 1.
// - scroll: A value between 0 and 4096.
/// Scroll the vertical (Y) axis of the layer visible area over the layer tile map area.
/// - layer: Value of 0 or 1.
/// - scroll: A value between 0 and 4096.
inline void vera_layer_set_vertical_scroll(byte layer, word scroll);
// --- VERA layer technical functions to quickly shift rows.
/// --- VERA layer technical functions to quickly shift rows.
// Get the bit shift value required to skip a whole line fast.
// - layer: Value of 0 or 1.
// - return: Rowshift value to calculate fast from a y value to line offset in tile mode.
/// Get the bit shift value required to skip a whole line fast.
/// - layer: Value of 0 or 1.
/// - return: Rowshift value to calculate fast from a y value to line offset in tile mode.
byte vera_layer_get_rowshift(byte layer);
// Get the value required to skip a whole line fast.
// - layer: Value of 0 or 1.
// - return: Skip value to calculate fast from a y value to line offset in tile mode.
/// Get the value required to skip a whole line fast.
/// - layer: Value of 0 or 1.
/// - return: Skip value to calculate fast from a y value to line offset in tile mode.
word vera_layer_get_rowskip(byte layer);
// Set a vera layer in tile mode and configure the:
// - layer: Value of 0 or 1.
// - mapbase_address: A dword typed address (4 bytes), that specifies the full address of the map base.
// The function does the translation from the dword that contains the 17 bit address,
// to the respective mapbase vera register.
// Note that the register only specifies bits 16:9 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
// - tilebase_address: A dword typed address (4 bytes), that specifies the base address of the tile map.
// The function does the translation from the dword that contains the 17 bit address,
// to the respective tilebase vera register.
// Note that the resulting vera register holds only specifies bits 16:11 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
// - mapwidth: The width of the map in number of tiles.
// - mapheight: The height of the map in number of tiles.
// - tilewidth: The width of a tile, which can be 8 or 16 pixels.
// - tileheight: The height of a tile, which can be 8 or 16 pixels.
// - color_depth: The color depth in bits per pixel (BPP), which can be 1, 2, 4 or 8.
/// Set a vera layer in tile mode and configure the:
/// - layer: Value of 0 or 1.
/// - mapbase_address: A dword typed address (4 bytes), that specifies the full address of the map base.
/// The function does the translation from the dword that contains the 17 bit address,
/// to the respective mapbase vera register.
/// Note that the register only specifies bits 16:9 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
/// - tilebase_address: A dword typed address (4 bytes), that specifies the base address of the tile map.
/// The function does the translation from the dword that contains the 17 bit address,
/// to the respective tilebase vera register.
/// Note that the resulting vera register holds only specifies bits 16:11 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
/// - mapwidth: The width of the map in number of tiles.
/// - mapheight: The height of the map in number of tiles.
/// - tilewidth: The width of a tile, which can be 8 or 16 pixels.
/// - tileheight: The height of a tile, which can be 8 or 16 pixels.
/// - color_depth: The color depth in bits per pixel (BPP), which can be 1, 2, 4 or 8.
void vera_layer_mode_tile(byte layer, dword mapbase_address, dword tilebase_address, word mapwidth, word mapheight, byte tilewidth, byte tileheight, byte color_depth );
// Set a vera layer in text mode and configure the:
// - layer: Value of 0 or 1.
// - mapbase_address: A dword typed address (4 bytes), that specifies the full address of the map base.
// The function does the translation from the dword that contains the 17 bit address,
// to the respective mapbase vera register.
// Note that the register only specifies bits 16:9 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
// - tilebase_address: A dword typed address (4 bytes), that specifies the base address of the tile map.
// The function does the translation from the dword that contains the 17 bit address,
// to the respective tilebase vera register.
// Note that the resulting vera register holds only specifies bits 16:11 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
// - mapwidth: The width of the map in number of tiles.
// - mapheight: The height of the map in number of tiles.
// - tilewidth: The width of a tile, which can be 8 or 16 pixels.
// - tileheight: The height of a tile, which can be 8 or 16 pixels.
// - color_mode: The color mode, which can be 16 or 256.
/// Set a vera layer in text mode and configure the:
/// - layer: Value of 0 or 1.
/// - mapbase_address: A dword typed address (4 bytes), that specifies the full address of the map base.
/// The function does the translation from the dword that contains the 17 bit address,
/// to the respective mapbase vera register.
/// Note that the register only specifies bits 16:9 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
/// - tilebase_address: A dword typed address (4 bytes), that specifies the base address of the tile map.
/// The function does the translation from the dword that contains the 17 bit address,
/// to the respective tilebase vera register.
/// Note that the resulting vera register holds only specifies bits 16:11 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
/// - mapwidth: The width of the map in number of tiles.
/// - mapheight: The height of the map in number of tiles.
/// - tilewidth: The width of a tile, which can be 8 or 16 pixels.
/// - tileheight: The height of a tile, which can be 8 or 16 pixels.
/// - color_mode: The color mode, which can be 16 or 256.
void vera_layer_mode_text(byte layer, dword mapbase_address, dword tilebase_address, word mapwidth, word mapheight, byte tilewidth, byte tileheight, word color_mode );
// Set a vera layer in bitmap mode and configure the:
// - layer: Value of 0 or 1.
// - mapbase_address: A dword typed address (4 bytes), that specifies the full address of the map base.
// The function does the translation from the dword that contains the 17 bit address,
// to the respective mapbase vera register.
// Note that the register only specifies bits 16:9 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
// - tilebase_address: A dword typed address (4 bytes), that specifies the base address of the tile map.
// The function does the translation from the dword that contains the 17 bit address,
// to the respective tilebase vera register.
// Note that the resulting vera register holds only specifies bits 16:11 of the address,
// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
// - mapwidth: The width of the map in number of tiles.
// - mapheight: The height of the map in number of tiles.
// - tilewidth: The width of a tile, which can be 8 or 16 pixels.
// - tileheight: The height of a tile, which can be 8 or 16 pixels.
// - color_mode: The color mode, which can be 16 or 256.
/// Set a vera layer in bitmap mode and configure the:
/// - layer: Value of 0 or 1.
/// - mapbase_address: A dword typed address (4 bytes), that specifies the full address of the map base.
/// The function does the translation from the dword that contains the 17 bit address,
/// to the respective mapbase vera register.
/// Note that the register only specifies bits 16:9 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 512 bytes.
/// - tilebase_address: A dword typed address (4 bytes), that specifies the base address of the tile map.
/// The function does the translation from the dword that contains the 17 bit address,
/// to the respective tilebase vera register.
/// Note that the resulting vera register holds only specifies bits 16:11 of the address,
/// so the resulting address in the VERA VRAM is always aligned to a multiple of 2048 bytes!
/// - mapwidth: The width of the map in number of tiles.
/// - mapheight: The height of the map in number of tiles.
/// - tilewidth: The width of a tile, which can be 8 or 16 pixels.
/// - tileheight: The height of a tile, which can be 8 or 16 pixels.
/// - color_mode: The color mode, which can be 16 or 256.
void vera_layer_mode_bitmap(byte layer, dword bitmap_address, word mapwidth, word color_depth );

View File

@ -1,113 +1,113 @@
// Commander X16
// https://www.commanderx16.com/forum/index.php?/about-faq/
// https://github.com/commanderx16/x16-docs/blob/master/Commander%20X16%20Programmer's%20Reference%20Guide.md
/// Commander X16
/// https://www.commanderx16.com/forum/index.php?/about-faq/
/// https://github.com/commanderx16/x16-docs/blob/master/Commander%20X16%20Programmer's%20Reference%20Guide.md
#ifndef __CX16__
#error "Target platform must be cx16"
#endif
#include <cx16-vera.h>
#include <mos6522.h>
// The VIA#1: ROM/RAM Bank Control
// Port A Bits 0-7 RAM bank
// Port B Bits 0-2 ROM bank
// Port B Bits 3-7 [TBD]
/// The VIA#1: ROM/RAM Bank Control
/// Port A Bits 0-7 RAM bank
/// Port B Bits 0-2 ROM bank
/// Port B Bits 3-7 [TBD]
struct MOS6522_VIA * const VIA1 = (struct MOS6522_VIA *)0x9f60;
// The VIA#2: Keyboard/Joy/Mouse
// Port A Bit 0 KBD PS/2 DAT
// Port A Bit 1 KBD PS/2 CLK
// Port A Bit 2 [TBD]
// Port A Bit 3 JOY1/2 LATCH
// Port A Bit 4 JOY1 DATA
// Port A Bit 5 JOY1/2 CLK
// Port A Bit 6 JOY2 DATA
// Port A Bit 7 [TBD]
// Port B Bit 0 MOUSE PS/2 DAT
// Port B Bit 1 MOUSE PS/2 CLK
// Port B Bits 2-7 [TBD]
// NOTE: The pin assignment of the NES/SNES controller is likely to change.
/// The VIA#2: Keyboard/Joy/Mouse
/// Port A Bit 0 KBD PS/2 DAT
/// Port A Bit 1 KBD PS/2 CLK
/// Port A Bit 2 [TBD]
/// Port A Bit 3 JOY1/2 LATCH
/// Port A Bit 4 JOY1 DATA
/// Port A Bit 5 JOY1/2 CLK
/// Port A Bit 6 JOY2 DATA
/// Port A Bit 7 [TBD]
/// Port B Bit 0 MOUSE PS/2 DAT
/// Port B Bit 1 MOUSE PS/2 CLK
/// Port B Bits 2-7 [TBD]
/// NOTE: The pin assignment of the NES/SNES controller is likely to change.
struct MOS6522_VIA * const VIA2 = (struct MOS6522_VIA *)0x9f70;
// Interrupt Vectors
// https://github.com/commanderx16/x16-emulator/wiki/(ASM-Programming)-Interrupts-and-interrupt-handling
/// Interrupt Vectors
/// https://github.com/commanderx16/x16-emulator/wiki/(ASM-Programming)-Interrupts-and-interrupt-handling
// Pointer to interrupt function
/// Pointer to interrupt function
typedef void (*IRQ_TYPE)(void);
// $FFFE (ROM) Universal interrupt vector - The vector used when the HARDWARE serves IRQ interrupts
/// $FFFE (ROM) Universal interrupt vector - The vector used when the HARDWARE serves IRQ interrupts
IRQ_TYPE* const HARDWARE_IRQ = (IRQ_TYPE*)0xfffe;
// $0314 (RAM) IRQ vector - The vector used when the KERNAL serves IRQ interrupts
/// $0314 (RAM) IRQ vector - The vector used when the KERNAL serves IRQ interrupts
IRQ_TYPE* const KERNEL_IRQ = (IRQ_TYPE*)0x0314;
// $0316 (RAM) BRK vector - The vector used when the KERNAL serves IRQ caused by a BRK
/// $0316 (RAM) BRK vector - The vector used when the KERNAL serves IRQ caused by a BRK
IRQ_TYPE* const KERNEL_BRK = (IRQ_TYPE*)0x0316;
// VRAM Address of the default screen
/// VRAM Address of the default screen
char * const DEFAULT_SCREEN = (char*)0x0000;
// VRAM Bank (0/1) of the default screen
/// VRAM Bank (0/1) of the default screen
char * const DEFAULT_SCREEN_VBANK = (char*)0;
// Put a single byte into VRAM.
// Uses VERA DATA0
// - vbank: Which 64K VRAM bank to put data into (0/1)
// - vaddr: The address in VRAM
// - data: The data to put into VRAM
/// Put a single byte into VRAM.
/// Uses VERA DATA0
/// - vbank: Which 64K VRAM bank to put data into (0/1)
/// - vaddr: The address in VRAM
/// - data: The data to put into VRAM
void vpoke(char vbank, char* vaddr, char data);
// Read a single byte from VRAM.
// Uses VERA DATA0
// - bank: Which 64K VRAM bank to put data into (0/1)
// - addr: The address in VRAM
// - returns: The data to put into VRAM
/// Read a single byte from VRAM.
/// Uses VERA DATA0
/// - bank: Which 64K VRAM bank to put data into (0/1)
/// - addr: The address in VRAM
/// - returns: The data to put into VRAM
char vpeek(char vbank, char* vaddr);
// Copy block of memory (from RAM to VRAM)
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination in VRAM.
// - vbank: Which 64K VRAM bank to put data into (0/1)
// - vdest: The destination address in VRAM
// - src: The source address in RAM
// - num: The number of bytes to copy
/// Copy block of memory (from RAM to VRAM)
/// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination in VRAM.
/// - vbank: Which 64K VRAM bank to put data into (0/1)
/// - vdest: The destination address in VRAM
/// - src: The source address in RAM
/// - num: The number of bytes to copy
void memcpy_to_vram(char vbank, void* vdest, void* src, unsigned int num );
// Copy block of memory (from banked RAM to VRAM)
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination in VRAM.
// - vdest: absolute address in VRAM
// - src: absolute address in the banked RAM of the CX16.
// - num: dword of the number of bytes to copy
// Note: This function can switch RAM bank during copying to copy data from multiple RAM banks.
/// Copy block of memory (from banked RAM to VRAM)
/// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination in VRAM.
/// - vdest: absolute address in VRAM
/// - src: absolute address in the banked RAM of the CX16.
/// - num: dword of the number of bytes to copy
/// Note: This function can switch RAM bank during copying to copy data from multiple RAM banks.
void memcpy_bank_to_vram(unsigned long vdest, unsigned long src, unsigned long num );
// Copy block of memory (from VRAM to VRAM)
// Copies the values from the location pointed by src to the location pointed by dest.
// The method uses the VERA access ports 0 and 1 to copy data from and to in VRAM.
// - src_bank: 64K VRAM bank number to copy from (0/1).
// - src: pointer to the location to copy from. Note that the address is a 16 bit value!
// - src_increment: the increment indicator, VERA needs this because addressing increment is automated by VERA at each access.
// - dest_bank: 64K VRAM bank number to copy to (0/1).
// - dest: pointer to the location to copy to. Note that the address is a 16 bit value!
// - dest_increment: the increment indicator, VERA needs this because addressing increment is automated by VERA at each access.
// - num: The number of bytes to copy
/// Copy block of memory (from VRAM to VRAM)
/// Copies the values from the location pointed by src to the location pointed by dest.
/// The method uses the VERA access ports 0 and 1 to copy data from and to in VRAM.
/// - src_bank: 64K VRAM bank number to copy from (0/1).
/// - src: pointer to the location to copy from. Note that the address is a 16 bit value!
/// - src_increment: the increment indicator, VERA needs this because addressing increment is automated by VERA at each access.
/// - dest_bank: 64K VRAM bank number to copy to (0/1).
/// - dest: pointer to the location to copy to. Note that the address is a 16 bit value!
/// - dest_increment: the increment indicator, VERA needs this because addressing increment is automated by VERA at each access.
/// - num: The number of bytes to copy
void memcpy_in_vram(char dest_bank, void *dest, char dest_increment, char src_bank, void *src, char src_increment, unsigned int num );
// Set block of memory in VRAM to a value .
// Sets num bytes to a value to the memory block pointed to by destination in VRAM.
// - vbank: Which 64K VRAM bank to put data into (0/1)
// - vdest: The destination address in VRAM
// - data: The value to set the vram with.
// - num: The number of bytes to set
/// Set block of memory in VRAM to a value .
/// Sets num bytes to a value to the memory block pointed to by destination in VRAM.
/// - vbank: Which 64K VRAM bank to put data into (0/1)
/// - vdest: The destination address in VRAM
/// - data: The value to set the vram with.
/// - num: The number of bytes to set
void memset_vram(char vbank, void* vdest, char data, unsigned long num );
// Set block of memory in VRAM to a word value .
// Sets num words to a value to the memory block pointed to by destination in VRAM.
// - vbank: Which 64K VRAM bank to put data into (0/1)
// - vdest: The destination address in VRAM
// - data: The value to set the vram with.
// - num: The number of bytes to set
/// Set block of memory in VRAM to a word value .
/// Sets num words to a value to the memory block pointed to by destination in VRAM.
/// - vbank: Which 64K VRAM bank to put data into (0/1)
/// - vdest: The destination address in VRAM
/// - data: The value to set the vram with.
/// - num: The number of bytes to set
void memset_vram_word(char vbank, void* vdest, unsigned int data, unsigned long num );
// Load a file into one of the 256 8KB RAM banks.
// - device: The device to load from
// - filename: The file name
// - address: The absolute address in banked memory to load the file too
// - returns: 0xff: Success, other: Kernal Error Code (https://commodore.ca/manuals/pdfs/commodore_error_messages.pdf)
// Note: This function only works if the entire file fits within the selected bank. The function cannot load to multiple banks.
/// Load a file into one of the 256 8KB RAM banks.
/// - device: The device to load from
/// - filename: The file name
/// - address: The absolute address in banked memory to load the file too
/// - returns: 0xff: Success, other: Kernal Error Code (https://commodore.ca/manuals/pdfs/commodore_error_messages.pdf)
/// Note: This function only works if the entire file fits within the selected bank. The function cannot load to multiple banks.
char load_to_bank( char device, char* filename, unsigned long address);

View File

@ -1,75 +1,75 @@
// Simple binary division implementation
// Follows the C99 standard by truncating toward zero on negative results.
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
/// Simple binary division implementation
/// Follows the C99 standard by truncating toward zero on negative results.
/// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
// Remainder after signed 8 bit division
/// Remainder after signed 8 bit division
extern char rem8u;
// Performs division on two 8 bit unsigned chars
// Returns dividend/divisor.
// The remainder will be set into the global variable rem8u
// Implemented using simple binary division
/// Performs division on two 8 bit unsigned chars
/// Returns dividend/divisor.
/// The remainder will be set into the global variable rem8u
/// Implemented using simple binary division
char div8u(char dividend, char divisor);
// Performs division on two 8 bit unsigned chars and an initial remainder
// Returns dividend/divisor.
// The final remainder will be set into the global variable rem8u
// Implemented using simple binary division
/// Performs division on two 8 bit unsigned chars and an initial remainder
/// Returns dividend/divisor.
/// The final remainder will be set into the global variable rem8u
/// Implemented using simple binary division
char divr8u(char dividend, char divisor, char rem);
// Divide unsigned 16-bit unsigned long dividend with a 8-bit unsigned char divisor
// The 8-bit unsigned char remainder can be found in rem8u after the division
/// Divide unsigned 16-bit unsigned long dividend with a 8-bit unsigned char divisor
/// The 8-bit unsigned char remainder can be found in rem8u after the division
unsigned int div16u8u(unsigned int dividend, unsigned char divisor);
// Remainder after unsigned 16-bit division
/// Remainder after unsigned 16-bit division
extern unsigned int rem16u;
// Performs division on two 16 bit unsigned ints and an initial remainder
// Returns the quotient dividend/divisor.
// The final remainder will be set into the global variable rem16u
// Implemented using simple binary division
/// Performs division on two 16 bit unsigned ints and an initial remainder
/// Returns the quotient dividend/divisor.
/// The final remainder will be set into the global variable rem16u
/// Implemented using simple binary division
unsigned int divr16u(unsigned int dividend, unsigned int divisor, unsigned int rem);
// Performs modulo on two 16 bit unsigned ints and an initial remainder
// Returns the remainder.
// Implemented using simple binary division
/// Performs modulo on two 16 bit unsigned ints and an initial remainder
/// Returns the remainder.
/// Implemented using simple binary division
unsigned int modr16u(unsigned int dividend, unsigned int divisor, unsigned int rem);
// Performs division on two 16 bit unsigned ints
// Returns the quotient dividend/divisor.
// The remainder will be set into the global variable rem16u
// Implemented using simple binary division
/// Performs division on two 16 bit unsigned ints
/// Returns the quotient dividend/divisor.
/// The remainder will be set into the global variable rem16u
/// Implemented using simple binary division
unsigned int div16u(unsigned int dividend, unsigned int divisor);
// Divide unsigned 32-bit unsigned long dividend with a 16-bit unsigned int divisor
// The 16-bit unsigned int remainder can be found in rem16u after the division
/// Divide unsigned 32-bit unsigned long dividend with a 16-bit unsigned int divisor
/// The 16-bit unsigned int remainder can be found in rem16u after the division
unsigned long div32u16u(unsigned long dividend, unsigned int divisor);
// Remainder after signed 8 bit division
/// Remainder after signed 8 bit division
extern signed char rem8s;
// Perform division on two signed 8-bit numbers
// Returns dividend/divisor.
// The remainder will be set into the global variable rem8s.
// Implemented using simple binary division
// Follows the C99 standard by truncating toward zero on negative results.
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
/// Perform division on two signed 8-bit numbers
/// Returns dividend/divisor.
/// The remainder will be set into the global variable rem8s.
/// Implemented using simple binary division
/// Follows the C99 standard by truncating toward zero on negative results.
/// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
signed char div8s(signed char dividend, signed char divisor);
// Remainder after signed 16 bit division
/// Remainder after signed 16 bit division
extern int rem16s;
// Perform division on two signed 16-bit numbers with an initial remainder.
// Returns dividend/divisor. The remainder will be set into the global variable rem16s.
// Implemented using simple binary division
// Follows the C99 standard by truncating toward zero on negative results.
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
/// Perform division on two signed 16-bit numbers with an initial remainder.
/// Returns dividend/divisor. The remainder will be set into the global variable rem16s.
/// Implemented using simple binary division
/// Follows the C99 standard by truncating toward zero on negative results.
/// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
int divr16s(int dividend, int divisor, int rem);
// Perform division on two signed 16-bit numbers
// Returns dividend/divisor.
// The remainder will be set into the global variable rem16s.
// Implemented using simple binary division
// Follows the C99 standard by truncating toward zero on negative results.
// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
/// Perform division on two signed 16-bit numbers
/// Returns dividend/divisor.
/// The remainder will be set into the global variable rem16s.
/// Implemented using simple binary division
/// Follows the C99 standard by truncating toward zero on negative results.
/// See http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.5.5
int div16s(int dividend, int divisor);

View File

@ -1,34 +1,34 @@
// Library Implementation of the Seriously Fast Multiplication
// See http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
// Utilizes the fact that a*b = ((a+b)/2)^2 - ((a-b)/2)^2
/// Library Implementation of the Seriously Fast Multiplication
/// See http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
/// Utilizes the fact that a*b = ((a+b)/2)^2 - ((a-b)/2)^2
// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
/// Initialize the mulf_sqr multiplication tables with f(x)=int(x*x/4)
void mulf_init();
// Prepare for fast multiply with an unsigned char to a unsigned int result
/// Prepare for fast multiply with an unsigned char to a unsigned int result
void mulf8u_prepare(char a);
// Calculate fast multiply with a prepared unsigned char to a unsigned int result
// The prepared number is set by calling mulf8u_prepare(char a)
/// Calculate fast multiply with a prepared unsigned char to a unsigned int result
/// The prepared number is set by calling mulf8u_prepare(char a)
unsigned int mulf8u_prepared(char b);
// Fast multiply two unsigned chars to a unsigned int result
/// Fast multiply two unsigned chars to a unsigned int result
unsigned int mulf8u(char a, char b);
// Prepare for fast multiply with an signed char to a unsigned int result
/// Prepare for fast multiply with an signed char to a unsigned int result
inline void mulf8s_prepare(signed char a);
// Calculate fast multiply with a prepared unsigned char to a unsigned int result
// The prepared number is set by calling mulf8s_prepare(char a)
/// Calculate fast multiply with a prepared unsigned char to a unsigned int result
/// The prepared number is set by calling mulf8s_prepare(char a)
signed int mulf8s_prepared(signed char b);
// Fast multiply two signed chars to a unsigned int result
/// Fast multiply two signed chars to a unsigned int result
signed int mulf8s(signed char a, signed char b);
// Fast multiply two unsigned ints to a double unsigned int result
// Done in assembler to utilize fast addition A+X
/// Fast multiply two unsigned ints to a double unsigned int result
/// Done in assembler to utilize fast addition A+X
unsigned long mulf16u(unsigned int a, unsigned int b);
// Fast multiply two signed ints to a signed double unsigned int result
// Fixes offsets introduced by using unsigned multiplication
/// Fast multiply two signed ints to a signed double unsigned int result
/// Fixes offsets introduced by using unsigned multiplication
signed long mulf16s(signed int a, signed int b);

View File

@ -1,45 +1,45 @@
// Functions for using the F018 DMA for very fast copying or filling of memory
/// Functions for using the F018 DMA for very fast copying or filling of memory
#include <mega65.h>
// Copy a memory block within the first 64K memory space using MEGA65 DMagic DMA
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
// - dest The destination address (within the MB and bank)
// - src The source address (within the MB and bank)
// - num The number of bytes to copy
/// Copy a memory block within the first 64K memory space using MEGA65 DMagic DMA
/// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
/// - dest The destination address (within the MB and bank)
/// - src The source address (within the MB and bank)
/// - num The number of bytes to copy
void memcpy_dma(void* dest, void* src, unsigned int num);
// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
// - dest_bank The 64KB bank for the destination (0-63)
// - dest The destination address (within the MB and bank)
// - src_bank The 64KB bank for the source (0-63)
// - src The source address (within the MB and bank)
// - num The number of bytes to copy
/// Copy a memory block anywhere in first 4MB memory space using MEGA65 DMagic DMA
/// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
/// - dest_bank The 64KB bank for the destination (0-63)
/// - dest The destination address (within the MB and bank)
/// - src_bank The 64KB bank for the source (0-63)
/// - src The source address (within the MB and bank)
/// - num The number of bytes to copy
void memcpy_dma4(char dest_bank, void* dest, char src_bank, void* src, unsigned int num);
// Copy a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
// - dest_mb The MB value for the destination (0-255)
// - dest_bank The 64KB bank for the destination (0-15)
// - dest The destination address (within the MB and bank)
// - src_mb The MB value for the source (0-255)
// - src_bank The 64KB bank for the source (0-15)
// - src The source address (within the MB and bank)
// - num The number of bytes to copy
/// Copy a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
/// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
/// - dest_mb The MB value for the destination (0-255)
/// - dest_bank The 64KB bank for the destination (0-15)
/// - dest The destination address (within the MB and bank)
/// - src_mb The MB value for the source (0-255)
/// - src_bank The 64KB bank for the source (0-15)
/// - src The source address (within the MB and bank)
/// - num The number of bytes to copy
void memcpy_dma256(char dest_mb, char dest_bank, void* dest, char src_mb, char src_bank, void* src, unsigned int num);
// Fill a memory block within the first 64K memory space using MEGA65 DMagic DMA
// Fills the values of num bytes at the destination with a single byte value.
// - dest The destination address (within the MB and bank)
// - fill The char to fill with
// - num The number of bytes to copy
/// Fill a memory block within the first 64K memory space using MEGA65 DMagic DMA
/// Fills the values of num bytes at the destination with a single byte value.
/// - dest The destination address (within the MB and bank)
/// - fill The char to fill with
/// - num The number of bytes to copy
void memset_dma(void* dest, char fill, unsigned int num);
// Set a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
// Sets the values of num bytes to the memory block pointed to by destination.
// - dest_mb The MB value for the destination (0-255)
// - dest_bank The 64KB bank for the destination (0-15)
// - dest The destination address (within the MB and bank)
// - fill The byte to fill into the memory
// - num The number of bytes to copy
/// Set a memory block anywhere in the entire 256MB memory space using MEGA65 DMagic DMA
/// Sets the values of num bytes to the memory block pointed to by destination.
/// - dest_mb The MB value for the destination (0-255)
/// - dest_bank The 64KB bank for the destination (0-15)
/// - dest The destination address (within the MB and bank)
/// - fill The byte to fill into the memory
/// - num The number of bytes to copy
void memset_dma256(char dest_mb, char dest_bank, void* dest, char fill, unsigned int num);

View File

@ -1,13 +1,13 @@
// MEGA65 DMA
// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
// C65 Manual http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt
// DMA lists https://raw.githubusercontent.com/MEGA65/c65-specifications/master/c65manualupdated.txt
// DMA lists https://c65gs.blogspot.com/2019/03/auto-detecting-required-revision-of.html
// DMA list options https://c65gs.blogspot.com/2018/01/improving-dmagic-controller-interface.html
// DMAgic VHDL source https://github.com/MEGA65/mega65-core/blob/master/src/vhdl/gs4510.vhdl#L4364
// Xemu emulator source https://github.com/lgblgblgb/xemu/blob/master/xemu/f018_core.c
/// MEGA65 DMA
/// Appendix J in https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
/// C65 Manual http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt
/// DMA lists https://raw.githubusercontent.com/MEGA65/c65-specifications/master/c65manualupdated.txt
/// DMA lists https://c65gs.blogspot.com/2019/03/auto-detecting-required-revision-of.html
/// DMA list options https://c65gs.blogspot.com/2018/01/improving-dmagic-controller-interface.html
/// DMAgic VHDL source https://github.com/MEGA65/mega65-core/blob/master/src/vhdl/gs4510.vhdl#L4364
/// Xemu emulator source https://github.com/lgblgblgb/xemu/blob/master/xemu/f018_core.c
// Registers of the MEGA65 enchanced F018 DMAgic Controller
/// Registers of the MEGA65 enchanced F018 DMAgic Controller
struct F018_DMAGIC {
// $D700 ADDRLSBTRIG DMAgic DMA list address LSB, and trigger DMA (when written).
// We also clear out the upper address bits in case an enhanced job had set them.
@ -38,7 +38,7 @@ struct F018_DMAGIC {
char MISC;
};
// F018A DMA list entry
/// F018A DMA list entry
struct DMA_LIST_F018A {
// DMA command
// 0-1 command (00: copy, 01: mix (unsupported) 10: swap (unsupported) 11: fill )
@ -71,7 +71,7 @@ struct DMA_LIST_F018A {
unsigned int modulo;
};
// F018B DMA list entry
/// F018B DMA list entry
struct DMA_LIST_F018B {
// DMA command (format F018B)
// bits
@ -108,73 +108,73 @@ struct DMA_LIST_F018B {
unsigned int modulo;
};
// DMA command copy
/// DMA command copy
const char DMA_COMMAND_COPY = 0x00;
// DMA command fill
/// DMA command fill
const char DMA_COMMAND_FILL = 0x03;
// DMA command fill
/// DMA command fill
const char DMA_COMMAND_CHAIN = 0x04;
// DMA command source direction
/// DMA command source direction
const char DMA_COMMAND_SRC_DIR = 0x10;
// DMA command destination direction
/// DMA command destination direction
const char DMA_COMMAND_DEST_DIR = 0x20;
// Extended DMA Option Prefixes
/// Extended DMA Option Prefixes
// $00 = End of options
/// $00 = End of options
const char DMA_OPTION_END = 0x00;
// $06 = Use $86 $xx transparency value (don't write source bytes to destination, if byte value matches $xx)
/// $06 = Use $86 $xx transparency value (don't write source bytes to destination, if byte value matches $xx)
const char DMA_OPTION_TRANSPARENCY_ENABLE = 0x06;
// $07 = Disable $86 $xx transparency value.
/// $07 = Disable $86 $xx transparency value.
const char DMA_OPTION_TRANSPARENCY_DISABLE = 0x07;
// $0A = Use F018A list format
/// $0A = Use F018A list format
const char DMA_OPTION_FORMAT_F018A = 0x0a;
// $0B = Use F018B list format
/// $0B = Use F018B list format
const char DMA_OPTION_FORMAT_F018B = 0x0a;
// $53 Enable Shallan Spiral Mode
/// $53 Enable Shallan Spiral Mode
const char DMA_OPTION_SPIRAL = 0x53;
// $80 $xx = Set MB of source address
/// $80 $xx = Set MB of source address
const char DMA_OPTION_SRC_MB = 0x80;
// $81 $xx = Set MB of destination address
/// $81 $xx = Set MB of destination address
const char DMA_OPTION_DEST_MB = 0x81;
// $82 $xx = Set source skip rate (/256ths of bytes)
/// $82 $xx = Set source skip rate (/256ths of bytes)
const char DMA_OPTION_SRC_SKIPRATE_256TH = 0x82;
// $83 $xx = Set source skip rate (whole bytes)
/// $83 $xx = Set source skip rate (whole bytes)
const char DMA_OPTION_SRC_SKIPRATE = 0x83;
// $84 $xx = Set destination skip rate (/256ths of bytes)
/// $84 $xx = Set destination skip rate (/256ths of bytes)
const char DMA_OPTION_DEST_SKIPRATE_256TH = 0x84;
// $85 $xx = Set destination skip rate (whole bytes)
/// $85 $xx = Set destination skip rate (whole bytes)
const char DMA_OPTION_DEST_SKIPRATE = 0x85;
// $86 $xx = Don't write to destination if byte value = $xx, and option $06 enabled
/// $86 $xx = Don't write to destination if byte value = $xx, and option $06 enabled
const char DMA_OPTION_TRANSPARENCY_VALUE = 0x86;
// $87 Set X column bytes (LSB) for line drawing
// The number of bytes needed to move to the next X column (8 pixels to the right)
/// $87 Set X column bytes (LSB) for line drawing
/// The number of bytes needed to move to the next X column (8 pixels to the right)
const char DMA_OPTION_LINE_XSTEP_LO = 0x87;
// $88 Set X column bytes (MSB) for line drawing
// The number of bytes needed to move to the next X column (8 pixels to the right)
/// $88 Set X column bytes (MSB) for line drawing
/// The number of bytes needed to move to the next X column (8 pixels to the right)
const char DMA_OPTION_LINE_XSTEP_HI = 0x88;
// $89 Set Y row bytes (LSB) for line drawing
// The number of bytes needed to move to the next Y row (1 pixel below)
/// $89 Set Y row bytes (LSB) for line drawing
/// The number of bytes needed to move to the next Y row (1 pixel below)
const char DMA_OPTION_LINE_YSTEP_LO = 0x89;
// $8A Set Y row bytes (MSB) for line drawing
// The number of bytes needed to move to the next Y row (1 pixel below)
/// $8A Set Y row bytes (MSB) for line drawing
/// The number of bytes needed to move to the next Y row (1 pixel below)
const char DMA_OPTION_LINE_YSTEP_HI = 0x8a;
// $8B Slope (LSB) for line drawing
/// $8B Slope (LSB) for line drawing
const char DMA_OPTION_LINE_SLOPE_LO = 0x8b;
// $8C Slope (MSB) for line drawing
/// $8C Slope (MSB) for line drawing
const char DMA_OPTION_LINE_SLOPE_HI = 0x8c;
// $8D Slope accumulator initial fraction (LSB) for line drawing
/// $8D Slope accumulator initial fraction (LSB) for line drawing
const char DMA_OPTION_LINE_SLOPE_INIT_LO = 0x8d;
// $8E Slope accumulator initial fraction (MSB) for line drawing
/// $8E Slope accumulator initial fraction (MSB) for line drawing
const char DMA_OPTION_LINE_SLOPE_INIT_HI = 0x8e;
// $8F Line Drawing Mode enable and options (set in argument byte):
// Bit 7 = enable line mode,
// Bit 6 = select X or Y direction,
// Bit 5 = slope is negative.
/// $8F Line Drawing Mode enable and options (set in argument byte):
/// Bit 7 = enable line mode,
/// Bit 6 = select X or Y direction,
/// Bit 5 = slope is negative.
const char DMA_OPTION_LINE_MODE = 0x8f;
// Line Drawing Mode Bit 7 = enable line mode,
/// Line Drawing Mode Bit 7 = enable line mode,
const char DMA_OPTION_LINE_MODE_ENABLE = 0x80;
// Line Drawing Mode Bit 6 = select X or Y direction,
/// Line Drawing Mode Bit 6 = select X or Y direction,
const char DMA_OPTION_LINE_MODE_DIRECTION_Y = 0x40;
// Line Drawing Mode Bit 5 = slope is negative.
/// Line Drawing Mode Bit 5 = slope is negative.
const char DMA_OPTION_LINE_MODE_SLOPE_NEGATIVE = 0x20;

View File

@ -1,22 +1,22 @@
// MEGA65 CPU MATHS ACCELERATION REGISTERS
// Every MEGA65 contains a combined 32-bit hardware multiplier and divider. This device
// takes two 32-bit inputs, MULTINA and MULTINB, and simultaneously calculates:
// • the 64-bit product of MULTINA and MULTINB
// • the 32-bit whole part of MULTINA / MULTINB
// • the 32-bit fractional part of MULTINA / MULTINB
// It is always updating the outputs based on the inputs, so there is no need to take special
// action when changing the inputs. The multiplier takes 1 cycle to calculate, and the updated result will thus be available immediately.
// The hardware divider, however, can take up to 16 cycles depending on the particular inputs. Thus programmers should insert a short
// delay after changing the inputs before reading the output. As this delay is so short, it can be implemented by simply reading the first
// byte of the result four times consecutively, as the 4th read will occur after the result has settled.
/// MEGA65 CPU MATHS ACCELERATION REGISTERS
/// Every MEGA65 contains a combined 32-bit hardware multiplier and divider. This device
/// takes two 32-bit inputs, MULTINA and MULTINB, and simultaneously calculates:
/// • the 64-bit product of MULTINA and MULTINB
/// • the 32-bit whole part of MULTINA / MULTINB
/// • the 32-bit fractional part of MULTINA / MULTINB
/// It is always updating the outputs based on the inputs, so there is no need to take special
/// action when changing the inputs. The multiplier takes 1 cycle to calculate, and the updated result will thus be available immediately.
/// The hardware divider, however, can take up to 16 cycles depending on the particular inputs. Thus programmers should insert a short
/// delay after changing the inputs before reading the output. As this delay is so short, it can be implemented by simply reading the first
/// byte of the result four times consecutively, as the 4th read will occur after the result has settled.
// $D70F MATH BUSY
// Bit 7: DIVBUSY
// Bit 6: MULBUSY
/// $D70F MATH BUSY
/// Bit 7: DIVBUSY
/// Bit 6: MULBUSY
char * const MATH_BUSY = (char *)0xd70f;
// $D768-$D76F DIVOUT 64-bit output of MULTINA ÷ MULTINB
// $D768-$D76B DIVOUT FRAC 32-bit output of MULTINA ÷ MULTINB
/// $D768-$D76F DIVOUT 64-bit output of MULTINA ÷ MULTINB
/// $D768-$D76B DIVOUT FRAC 32-bit output of MULTINA ÷ MULTINB
signed char volatile * const MATH_DIVOUT_FRAC_CHAR0 = (signed char*)0xd768;
signed char volatile * const MATH_DIVOUT_FRAC_CHAR1 = (signed char*)0xd769;
signed char volatile * const MATH_DIVOUT_FRAC_CHAR2 = (signed char*)0xd76a;
@ -24,13 +24,13 @@ signed char volatile * const MATH_DIVOUT_FRAC_CHAR3 = (signed char*)0xd76b;
signed int volatile * const MATH_DIVOUT_FRAC_INT0 = (signed int*)0xd768;
signed int volatile * const MATH_DIVOUT_FRAC_INT1 = (signed int*)0xd76a;
signed long volatile * const MATH_DIVOUT_FRAC_LONG0 = (signed long*)0xd768;
// $D768-$D76F DIVOUT 64-bit output of MULTINA ÷ MULTINB
/// $D768-$D76F DIVOUT 64-bit output of MULTINA ÷ MULTINB
signed char volatile * const MATH_DIVOUT_WHOLE_CHAR0 = (signed char*)0xd76c;
signed int volatile * const MATH_DIVOUT_WHOLE_INT0 = (signed int*)0xd76c;
signed int volatile * const MATH_DIVOUT_WHOLE_INT1 = (signed int*)0xd76e;
signed long volatile * const MATH_DIVOUT_WHOLE_LONG = (signed long*)0xd76c;
// $D770-$D773 MULTINA Multiplier input A / Divider numerator (32 bit)
/// $D770-$D773 MULTINA Multiplier input A / Divider numerator (32 bit)
signed char * const MATH_MULTINA_CHAR0 = (signed char*)0xd770;
signed char * const MATH_MULTINA_CHAR1 = (signed char*)0xd771;
signed char * const MATH_MULTINA_CHAR2 = (signed char*)0xd772;
@ -39,7 +39,7 @@ signed int * const MATH_MULTINA_INT0 = (signed int*)0xd770;
signed int * const MATH_MULTINA_INT1 = (signed int*)0xd772;
signed long * const MATH_MULTINA_LONG = (signed long*)0xd770;
// $D774-$D777 MULTINB Multiplier input B / Divider denominator (32 bit)
/// $D774-$D777 MULTINB Multiplier input B / Divider denominator (32 bit)
signed char * const MATH_MULTINB_CHAR0 = (signed char*)0xd774;
signed char * const MATH_MULTINB_CHAR1 = (signed char*)0xd775;
signed char * const MATH_MULTINB_CHAR2 = (signed char*)0xd776;
@ -48,7 +48,7 @@ signed int * const MATH_MULTINB_INT0 = (signed int*)0xd774;
signed int * const MATH_MULTINB_INT1 = (signed int*)0xd776;
signed long * const MATH_MULTINB_LONG = (signed long*)0xd774;
// $D778-$D77F MULTOUT 64-bit output of MULTINA × MULTINB
/// $D778-$D77F MULTOUT 64-bit output of MULTINA × MULTINB
signed char volatile * const MATH_MULTOUT_CHAR0 = (signed char*)0xd778;
signed int volatile * const MATH_MULTOUT_INT0 = (signed int*)0xd778;
signed long volatile * const MATH_MULTOUT_LONG0 = (signed long*)0xd778;

View File

@ -1,84 +1,84 @@
// MEGA65 Memory Mapper allows the 6502 CPU to access up to 256MB of memory by remapping where the eight 8K blocks point in real memory.
// The memory mapping is configured through the new MAP instruction of the MOS 4510.
// https://mega65.org/
// https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
// https://github.com/MEGA65/mega65-core/blob/master/src/vhdl/gs4510.vhdl
// http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt
// http://anyplatform.net/media/guides/cpus/65xx%20Processor%20Data.txt
/// MEGA65 Memory Mapper allows the 6502 CPU to access up to 256MB of memory by remapping where the eight 8K blocks point in real memory.
/// The memory mapping is configured through the new MAP instruction of the MOS 4510.
/// https://mega65.org/
/// https://mega.scryptos.com/sharefolder-link/MEGA/MEGA65+filehost/Docs/MEGA65-Book_draft.pdf
/// https://github.com/MEGA65/mega65-core/blob/master/src/vhdl/gs4510.vhdl
/// http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt
/// http://anyplatform.net/media/guides/cpus/65xx%20Processor%20Data.txt
// Bit representing 8K block #0 of the 64K addressable memory ($0000-$1fff)
/// Bit representing 8K block #0 of the 64K addressable memory ($0000-$1fff)
const unsigned char MEMORYBLOCK_0000 = 0b00000001;
// Bit representing 8K block #1 of the 64K addressable memory ($2000-$3fff)
/// Bit representing 8K block #1 of the 64K addressable memory ($2000-$3fff)
const unsigned char MEMORYBLOCK_2000 = 0b00000010;
// Bit representing 8K block #2 of the 64K addressable memory ($4000-$5fff)
/// Bit representing 8K block #2 of the 64K addressable memory ($4000-$5fff)
const unsigned char MEMORYBLOCK_4000 = 0b00000100;
// Bit representing 8K block #3 of the 64K addressable memory ($6000-$7fff)
/// Bit representing 8K block #3 of the 64K addressable memory ($6000-$7fff)
const unsigned char MEMORYBLOCK_6000 = 0b00001000;
// Bit representing 8K block #4 of the 64K addressable memory ($8000-$9fff)
/// Bit representing 8K block #4 of the 64K addressable memory ($8000-$9fff)
const unsigned char MEMORYBLOCK_8000 = 0b00010000;
// Bit representing 8K block #5 of the 64K addressable memory ($a000-$bfff)
/// Bit representing 8K block #5 of the 64K addressable memory ($a000-$bfff)
const unsigned char MEMORYBLOCK_A000 = 0b00100000;
// Bit representing 8K block #6 of the 64K addressable memory ($c000-$dfff)
/// Bit representing 8K block #6 of the 64K addressable memory ($c000-$dfff)
const unsigned char MEMORYBLOCK_C000 = 0b01000000;
// Bit representing 8K block #7 of the 64K addressable memory ($e000-$ffff)
/// Bit representing 8K block #7 of the 64K addressable memory ($e000-$ffff)
const unsigned char MEMORYBLOCK_E000 = 0b10000000;
// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
/// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
/// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
/// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
/// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
/// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
/// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
/// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
/// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
/// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
/// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
/// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
/// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
/// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
/// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
/// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
/// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
/// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
/// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
/// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
/// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 12bits of the passed value is used.
/// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
/// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
/// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
/// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
void memoryRemap(unsigned char remapBlocks, unsigned int lowerPageOffset, unsigned int upperPageOffset);
// Remap a single 8K memory block in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
// All the other 8K memory blocks will not be mapped and will point to their own address in the lowest 64K of the MEGA65 memory.
// blockPage: Page address of the 8K memory block to remap (ie. the block that is remapped is $100 * the passed page address.)
// memoryPage: Page address of the memory that the block should point to in the 1MB memory space of the MEGA65.
// Ie. the memory that will be pointed to is $100 * the passed page address. Only the lower 12bits of the passed value is used.
/// Remap a single 8K memory block in the 64K address space of the 6502 to point somewhere else in the first 1MB memory space of the MEGA65.
/// All the other 8K memory blocks will not be mapped and will point to their own address in the lowest 64K of the MEGA65 memory.
/// blockPage: Page address of the 8K memory block to remap (ie. the block that is remapped is $100 * the passed page address.)
/// memoryPage: Page address of the memory that the block should point to in the 1MB memory space of the MEGA65.
/// Ie. the memory that will be pointed to is $100 * the passed page address. Only the lower 12bits of the passed value is used.
void memoryRemapBlock(unsigned char blockPage, unsigned int memoryPage);
// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the entire 256MB memory space of the MEGA65.
// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
// See Appendix G in file:///Users/jespergravgaard/Downloads/MEGA65-Book_draft%20(5).pdf for a description of the CPU memory remapper of the MEGA65.
// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 20bits of the passed value is used.
// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 20bits of the passed value is used.
// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
/// Remap some of the eight 8K memory blocks in the 64K address space of the 6502 to point somewhere else in the entire 256MB memory space of the MEGA65.
/// After the remapping the CPU will access the mapped memory whenever it uses instructions that access a remapped block.
/// See section 2.3.4 in http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt for a description of the CPU memory remapper of the C65.
/// See Appendix G in file:///Users/jespergravgaard/Downloads/MEGA65-Book_draft%20(5).pdf for a description of the CPU memory remapper of the MEGA65.
/// remapBlocks: Indicates which 8K blocks of the 6502 address space to remap. Each bit represents one 8K block
/// - bit 0 Memory block $0000-$1fff. Use constant MEMORYBLOCK_0000.
/// - bit 1 Memory block $2000-$3fff. Use constant MEMORYBLOCK_2000.
/// - bit 2 Memory block $4000-$5fff. Use constant MEMORYBLOCK_4000.
/// - bit 3 Memory block $6000-$7fff. Use constant MEMORYBLOCK_6000.
/// - bit 4 Memory block $8000-$9fff. Use constant MEMORYBLOCK_8000.
/// - bit 5 Memory block $a000-$bfff. Use constant MEMORYBLOCK_A000.
/// - bit 6 Memory block $c000-$dfff. Use constant MEMORYBLOCK_C000.
/// - bit 7 Memory block $e000-$ffff. Use constant MEMORYBLOCK_E000.
/// lowerPageOffset: Offset that will be added to any remapped blocks in the lower 32K of memory (block 0-3).
/// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 20bits of the passed value is used.
/// - If block 0 ($0000-$1fff) is remapped it will point to lowerPageOffset*$100.
/// - If block 1 ($2000-$3fff) is remapped it will point to lowerPageOffset*$100 + $2000.
/// - If block 2 ($4000-$5fff) is remapped it will point to lowerPageOffset*$100 + $4000.
/// - If block 3 ($6000-$7fff) is remapped it will point to lowerPageOffset*$100 + $6000.
/// upperPageOffset: Offset that will be added to any remapped blocks in the upper 32K of memory (block 4-7).
/// The offset is a page offset (meaning it is multiplied by 0x100). Only the lower 20bits of the passed value is used.
/// - If block 4 ($8000-$9fff) is remapped it will point to upperPageOffset*$100 + $8000
/// - If block 5 ($a000-$bfff) is remapped it will point to upperPageOffset*$100 + $a000.
/// - If block 6 ($c000-$dfff) is remapped it will point to upperPageOffset*$100 + $c000.
/// - If block 7 ($e000-$ffff) is remapped it will point to upperPageOffset*$100 + $e000.
void memoryRemap256M(unsigned char remapBlocks, unsigned long lowerPageOffset, unsigned long upperPageOffset);

View File

@ -1,6 +1,6 @@
// MEGA65 Video Interface Chip (VIC IV)
// https://mega65.org/
// https://github.com/MEGA65/mega65-core/blob/master/src/vhdl/viciv.vhdl
/// MEGA65 Video Interface Chip (VIC IV)
/// https://mega65.org/
/// https://github.com/MEGA65/mega65-core/blob/master/src/vhdl/viciv.vhdl
struct MEGA65_VICIV {
char SPRITE0_X;
char SPRITE0_Y;
@ -306,72 +306,72 @@ struct MEGA65_VICIV {
char DEBUGXY;
};
// $D02f KEY register is used for choosing between the different I/O personalities.
// This disables/enables different registers in $D000-$DFFF
// $00: C64 personality
/// $D02f KEY register is used for choosing between the different I/O personalities.
/// This disables/enables different registers in $D000-$DFFF
/// $00: C64 personality
const char VICIV_KEY_C64 = 0x00;
// $A5, $96: C65 personality
/// $A5, $96: C65 personality
const char VICIV_KEY_C65_A = 0xa5;
const char VICIV_KEY_C65_B = 0x96;
// $45, $54: MEGA65 ETHERNET personality
/// $45, $54: MEGA65 ETHERNET personality
const char VICIV_KEY_ETHERNET_A = 0x45;
const char VICIV_KEY_ETHERNET_B = 0x54;
// $47, $53: MEGA65 personality
/// $47, $53: MEGA65 personality
const char VICIV_KEY_M65_A = 0x47;
const char VICIV_KEY_M65_B = 0x53;
// $D030 VIC-III Control Register A (ROM banks)
// Bit 20-bit Address 16-bit Address Read-Write
// 0 CRAM2K $1F800 $1FFFF, $D800 $DFFF Y
// $FF80000 $FF807FF
/// $D030 VIC-III Control Register A (ROM banks)
/// Bit 20-bit Address 16-bit Address Read-Write
/// 0 CRAM2K $1F800 $1FFFF, $D800 $DFFF Y
/// $FF80000 $FF807FF
const char VICIV_CRAM2K = 0x01;
// 3 ROM8 $38000 $39FFF $8000 $9FFF N
/// 3 ROM8 $38000 $39FFF $8000 $9FFF N
const char VICIV_ROM8 = 0x08;
// 4 ROMA $3A000 $3BFFF $A000 $BFFF N
/// 4 ROMA $3A000 $3BFFF $A000 $BFFF N
const char VICIV_ROMA = 0x10;
// 5 ROMC $2C000 $2CFFF $C000 $CFFF N
/// 5 ROMC $2C000 $2CFFF $C000 $CFFF N
const char VICIV_ROMC = 0x20;
// 6 CROM9 $29000 $29FFF $D000 $DFFF N
/// 6 CROM9 $29000 $29FFF $D000 $DFFF N
const char VICIV_CROM9 = 0x40;
// 7 ROME $3E000 $3FFFF $E000 $FFFF N
/// 7 ROME $3E000 $3FFFF $E000 $FFFF N
const char VICIV_ROME = 0x80;
// $D031 VIC-III Control Register B
// 0 INT Enable VIC-III interlaced mode
/// $D031 VIC-III Control Register B
/// 0 INT Enable VIC-III interlaced mode
const char VICIV_INT = 0x01;
// 1 MONO Enable VIC-III MONO video output (not implemented)
/// 1 MONO Enable VIC-III MONO video output (not implemented)
const char VICIV_MONO = 0x02;
// 2 H1280 Enable 1280 horizontal pixels (not implemented)
/// 2 H1280 Enable 1280 horizontal pixels (not implemented)
const char VICIV_H1280 = 0x04;
// 3 V400 Enable 400 vertical pixels
/// 3 V400 Enable 400 vertical pixels
const char VICIV_V400 = 0x08;
// 4 BPM Bit-Plane Mode
/// 4 BPM Bit-Plane Mode
const char VICIV_BPM = 0x10;
// 5 ATTR Enable extended attributes and 8 bit colour entries
/// 5 ATTR Enable extended attributes and 8 bit colour entries
const char VICIV_ATTR = 0x20;
// 6 FAST Enable C65 FAST mode (3 .5MHz)
/// 6 FAST Enable C65 FAST mode (3 .5MHz)
const char VICIV_FAST = 0x40;
// 7 H640 Enable C64 640 horizontal pixels / 80 column mode
/// 7 H640 Enable C64 640 horizontal pixels / 80 column mode
const char VICIV_H640 = 0x80;
// $D054 VIC-IV Control register C
// 0 CHR16 enable 16-bit character numbers (two screen bytes per character)
/// $D054 VIC-IV Control register C
/// 0 CHR16 enable 16-bit character numbers (two screen bytes per character)
const char VICIV_CHR16 = 0x01;
// 1 FCLRLO enable full-colour mode for character numbers <=\$FF
/// 1 FCLRLO enable full-colour mode for character numbers <=\$FF
const char VICIV_FCLRLO = 0x02;
// 2 FCLRHI enable full-colour mode for character numbers >\$FF
/// 2 FCLRHI enable full-colour mode for character numbers >\$FF
const char VICIV_FCLRHI = 0x04;
// 3 SMTH video output horizontal smoothing enable
/// 3 SMTH video output horizontal smoothing enable
const char VICIV_CSMTH = 0x08;
// 4 VIC-IV:SPR640 Sprite H640 enable;
/// 4 VIC-IV:SPR640 Sprite H640 enable;
const char VICIV_SPR640 = 0x10;
// 5 VIC-IV:PALEMU video output pal simulation
/// 5 VIC-IV:PALEMU video output pal simulation
const char VICIV_PALEMU = 0x20;
// 6 VIC-IV:VFAST C65GS FAST mode (48MHz)
/// 6 VIC-IV:VFAST C65GS FAST mode (48MHz)
const char VICIV_VFAST = 0x40;
// 7 VIC-IV:ALPHEN Alpha compositor enable
/// 7 VIC-IV:ALPHEN Alpha compositor enable
const char VICIV_ALPHEN = 0x80;
// $D06E.0-6 SPRPTRADR sprite pointer address (bits 22 - 16)
// 7 SPRPTR16 16-bit sprite pointer mode (allows sprites to be located on any 64 byte boundary in chip RAM)
/// $D06E.0-6 SPRPTRADR sprite pointer address (bits 22 - 16)
/// 7 SPRPTR16 16-bit sprite pointer mode (allows sprites to be located on any 64 byte boundary in chip RAM)
const char VICIV_SPRPTR16 = 0x80;

View File

@ -1,4 +1,4 @@
// MEGA65 Registers and Constants
/// MEGA65 Registers and Constants
#ifndef __MEGA65__
#error "Target platform must be MEGA65"
#endif
@ -11,80 +11,80 @@
#include <mega65-f018.h>
#include <mega65-math.h>
// I/O Personality selection
/// I/O Personality selection
volatile char * const IO_KEY = (char*)0xd02f;
// C65 Banking Register
/// C65 Banking Register
volatile char * const IO_BANK = (char*)0xd030;
// Map 2nd KB of colour RAM $DC00-$DFFF (hiding CIA's)
/// Map 2nd KB of colour RAM $DC00-$DFFF (hiding CIA's)
const char CRAM2K = 0b00000001;
// Processor port data direction register
/// Processor port data direction register
char* const PROCPORT_DDR = (char*)0x00;
// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
/// Mask for PROCESSOR_PORT_DDR which allows only memory configuration to be written
const char PROCPORT_DDR_MEMORY_MASK = 0b00000111;
// Processor Port Register controlling RAM/ROM configuration and the datasette
/// Processor Port Register controlling RAM/ROM configuration and the datasette
char* const PROCPORT = (char*)0x01;
// RAM in all three areas 0xA000, 0xD000, 0xE000
/// RAM in all three areas 0xA000, 0xD000, 0xE000
const char PROCPORT_RAM_ALL = 0b00000000;
// RAM in 0xA000, 0xE000 I/O in 0xD000
/// RAM in 0xA000, 0xE000 I/O in 0xD000
const char PROCPORT_RAM_IO = 0b00000101;
// RAM in 0xA000, 0xE000 CHAR ROM in 0xD000
/// RAM in 0xA000, 0xE000 CHAR ROM in 0xD000
const char PROCPORT_RAM_CHARROM = 0b00000001;
// RAM in 0xA000, I/O in 0xD000, KERNEL in 0xE000
/// RAM in 0xA000, I/O in 0xD000, KERNEL in 0xE000
const char PROCPORT_KERNEL_IO = 0b00000110;
// BASIC in 0xA000, I/O in 0xD000, KERNEL in 0xE000
/// BASIC in 0xA000, I/O in 0xD000, KERNEL in 0xE000
const char PROCPORT_BASIC_KERNEL_IO = 0b00000111;
// The VIC-II MOS 6567/6569
/// The VIC-II MOS 6567/6569
struct MOS6569_VICII* const VICII = (struct MOS6569_VICII*)0xd000;
// The VIC III MOS 4567/4569
/// The VIC III MOS 4567/4569
struct MOS4569_VICIII* const VICIII = (struct MOS4569_VICIII*)0xd000;
// The VIC IV
/// The VIC IV
struct MEGA65_VICIV* const VICIV = (struct MEGA65_VICIV*)0xd000;
// The address of the CHARGEN character set
/// The address of the CHARGEN character set
char * const CHARGEN = (char*)0xd000;
// Palette RED
/// Palette RED
char * const PALETTE_RED = (char*)0xd100;
// Palette GREEN
/// Palette GREEN
char * const PALETTE_GREEN = (char*)0xd200;
// Palette BLUE
/// Palette BLUE
char * const PALETTE_BLUE = (char*)0xd300;
// The SID MOS 6581/8580
/// The SID MOS 6581/8580
struct MOS6581_SID * const SID = (struct MOS6581_SID *)0xd400;
// DMAgic F018 Controller
/// DMAgic F018 Controller
struct F018_DMAGIC * const DMA = (struct F018_DMAGIC *)0xd700;
// Color Ram
/// Color Ram
char * const COLORRAM = (char*)0xd800;
// Default address of screen character matrix
/// Default address of screen character matrix
#ifdef __MEGA65_C64__
char * const DEFAULT_SCREEN = (char*)0x0400;
#else
char * const DEFAULT_SCREEN = (char*)0x0800;
#endif
// The CIA#1: keyboard matrix, joystick #1/#2
/// The CIA#1: keyboard matrix, joystick #1/#2
struct MOS6526_CIA * const CIA1 = (struct MOS6526_CIA *)0xdc00;
// The CIA#2: Serial bus, RS-232, VIC memory bank
/// The CIA#2: Serial bus, RS-232, VIC memory bank
struct MOS6526_CIA * const CIA2 = (struct MOS6526_CIA *)0xdd00;
// CIA#1 Interrupt for reading in ASM
/// CIA#1 Interrupt for reading in ASM
char * const CIA1_INTERRUPT = (char*)0xdc0d;
// CIA#2 timer A&B as one single 32-bit value
/// CIA#2 timer A&B as one single 32-bit value
unsigned long* const CIA2_TIMER_AB = (unsigned long*)0xdd04;
// CIA#2 Interrupt for reading in ASM
/// CIA#2 Interrupt for reading in ASM
char * const CIA2_INTERRUPT = (char*)0xdd0d;
// Pointer to interrupt function
/// Pointer to interrupt function
typedef void (*IRQ_TYPE)(void);
// The vector used when the KERNAL serves IRQ interrupts
/// The vector used when the KERNAL serves IRQ interrupts
IRQ_TYPE * const KERNEL_IRQ = (IRQ_TYPE*)0x0314;
// The vector used when the KERNAL serves NMI interrupts
/// The vector used when the KERNAL serves NMI interrupts
IRQ_TYPE * const KERNEL_NMI = (IRQ_TYPE*)0x0318;
// The vector used when the HARDWARE serves IRQ interrupts
/// The vector used when the HARDWARE serves IRQ interrupts
IRQ_TYPE * const HARDWARE_IRQ = (IRQ_TYPE*)0xfffe;
// The colors of the C64
/// The colors of the C64
const char BLACK = 0x0;
const char WHITE = 0x1;
const char RED = 0x2;
@ -102,18 +102,18 @@ const char LIGHT_GREEN = 0xd;
const char LIGHT_BLUE = 0xe;
const char LIGHT_GREY = 0xf;
// Get the value to store into D018 to display a specific screen and charset/bitmap
// Optimized for ASM from (char)((((unsigned int)screen&0x3fff)/0x40)|(((unsigned int)charset&0x3fff)/0x400));
/// Get the value to store into D018 to display a specific screen and charset/bitmap
/// Optimized for ASM from (char)((((unsigned int)screen&0x3fff)/0x40)|(((unsigned int)charset&0x3fff)/0x400));
char toD018(char* screen, char* gfx);
// Get the value to store into DD00 (CIA 2 port A) to choose a specific VIC bank
// Optimized for ASM from %00000011 ^ (char)((unsigned int)gfx/0x4000)
/// Get the value to store into DD00 (CIA 2 port A) to choose a specific VIC bank
/// Optimized for ASM from %00000011 ^ (char)((unsigned int)gfx/0x4000)
char toDd00(char* gfx);
// Get the sprite pointer for a sprite.
// The sprite pointer is the index of the sprite within the graphics bank and equal to the sprite (char)(sprite_addr/64)
// The sprite pointers are stored SCREEN+0x3f8+sprite_id to set the pointer of each sprite
/// Get the sprite pointer for a sprite.
/// The sprite pointer is the index of the sprite within the graphics bank and equal to the sprite (char)(sprite_addr/64)
/// The sprite pointers are stored SCREEN+0x3f8+sprite_id to set the pointer of each sprite
char toSpritePtr(char* sprite);
// Select a specific VIC graphics bank by setting the CIA 2 port A (0xdd00) as needed
/// Select a specific VIC graphics bank by setting the CIA 2 port A (0xdd00) as needed
void vicSelectGfxBank(char* gfx);

View File

@ -1,4 +1,8 @@
// MOS 4567 / 4569 Video Interface Chip (VIC III)
/// @file
/// @brief MOS 4567 / 4569 Video Interface Chip (VIC III)
/// MOS 4567 / 4569 Video Interface Chip (VIC III)
struct MOS4569_VICIII {
char SPRITE0_X;
char SPRITE0_Y;

View File

@ -1,7 +1,7 @@
// MOS 6522 Versatile Interface Adapter (VIA)
// Used in VIC 20 and 1541
// https://en.wikipedia.org/wiki/MOS_Technology_6522
// http://archive.6502.org/datasheets/mos_6522_preliminary_nov_1977.pdf
/// MOS 6522 Versatile Interface Adapter (VIA)
/// Used in VIC 20 and 1541
/// https://en.wikipedia.org/wiki/MOS_Technology_6522
/// http://archive.6502.org/datasheets/mos_6522_preliminary_nov_1977.pdf
struct MOS6522_VIA {
// Port B

View File

@ -1,7 +1,7 @@
// MOS 6523 TRI-PORT INTERFACE (TPI)
// It has three dedicated 8-bit I/O ports which provide 24 individually programmable I/O lines
// Used in the Commodore 1551 disk drive
// http://archive.6502.org/datasheets/mos_6523_tpi_preliminary_nov_1980.pdf
/// MOS 6523 TRI-PORT INTERFACE (TPI)
/// It has three dedicated 8-bit I/O ports which provide 24 individually programmable I/O lines
/// Used in the Commodore 1551 disk drive
/// http://archive.6502.org/datasheets/mos_6523_tpi_preliminary_nov_1980.pdf
struct MOS6523_TIA {
// Port A

View File

@ -1,5 +1,11 @@
// The MOS 6526 Complex Interface Adapter (CIA)
// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
/// @file
/// @brief The MOS 6526 Complex Interface Adapter (CIA)
///
/// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
/// @brief The MOS 6526 Complex Interface Adapter (CIA)
///
/// http://archive.6502.org/datasheets/mos_6526_cia_recreated.pdf
struct MOS6526_CIA {
// Port A
char PORT_A;
@ -31,38 +37,38 @@ struct MOS6526_CIA {
char TIMER_B_CONTROL;
};
// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
/// Value that disables all CIA interrupts when stored to the CIA Interrupt registers
const char CIA_INTERRUPT_CLEAR = $7f;
// Timer Control - Start/stop timer (0:stop, 1: start)
/// Timer Control - Start/stop timer (0:stop, 1: start)
const char CIA_TIMER_CONTROL_STOP = 0b00000000;
// Timer Control - Start/stop timer (0:stop, 1: start)
/// Timer Control - Start/stop timer (0:stop, 1: start)
const char CIA_TIMER_CONTROL_START = 0b00000001;
// Timer Control - Time CONTINUOUS/ONE-SHOT (0:CONTINUOUS, 1: ONE-SHOT)
/// Timer Control - Time CONTINUOUS/ONE-SHOT (0:CONTINUOUS, 1: ONE-SHOT)
const char CIA_TIMER_CONTROL_CONTINUOUS = 0b00000000;
// Timer Control - Time CONTINUOUS/ONE-SHOT (0:CONTINUOUS, 1: ONE-SHOT)
/// Timer Control - Time CONTINUOUS/ONE-SHOT (0:CONTINUOUS, 1: ONE-SHOT)
const char CIA_TIMER_CONTROL_ONESHOT = 0b00001000;
// Timer A Control - Timer counts (0:system cycles, 1: CNT pulses)
/// Timer A Control - Timer counts (0:system cycles, 1: CNT pulses)
const char CIA_TIMER_CONTROL_A_COUNT_CYCLES = 0b00000000;
// Timer A Control - Timer counts (0:system cycles, 1: CNT pulses)
/// Timer A Control - Timer counts (0:system cycles, 1: CNT pulses)
const char CIA_TIMER_CONTROL_A_COUNT_CNT = 0b00100000;
// Timer A Control - Serial Port Mode (0: Serial Port Input, 1: Serial Port Output)
/// Timer A Control - Serial Port Mode (0: Serial Port Input, 1: Serial Port Output)
const char CIA_TIMER_CONTROL_A_SERIAL_IN = 0b00000000;
// Timer A Control - Serial Port Mode (0: Serial Port Input, 1: Serial Port Output)
/// Timer A Control - Serial Port Mode (0: Serial Port Input, 1: Serial Port Output)
const char CIA_TIMER_CONTROL_A_SERIAL_OUT = 0b01000000;
// Timer A Control - time-of-day clock Mode (0: 60Hz, 1: 50Hz)
/// Timer A Control - time-of-day clock Mode (0: 60Hz, 1: 50Hz)
const char CIA_TIMER_CONTROL_A_TOD_60HZ = 0b00000000;
// Timer A Control - time-of-day clock Mode (0: 60Hz, 1: 50Hz)
/// Timer A Control - time-of-day clock Mode (0: 60Hz, 1: 50Hz)
const char CIA_TIMER_CONTROL_A_TOD_50HZ = 0b10000000;
// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high)
/// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high)
const char CIA_TIMER_CONTROL_B_COUNT_CYCLES = 0b00000000;
// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high)
/// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high)
const char CIA_TIMER_CONTROL_B_COUNT_CNT = 0b00100000;
// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high)
/// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high)
const char CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = 0b01000000;
// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high)
/// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high)
const char CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A_CNT = 0b01100000;
// Timer B Control - time-of-day write mode (0: TOD clock, 1: TOD alarm)
/// Timer B Control - time-of-day write mode (0: TOD clock, 1: TOD alarm)
const char CIA_TIMER_CONTROL_B_TOD_CLOCK_SET = 0b00000000;
// Timer B Control - time-of-day write mode (0: TOD clock, 1: TOD alarm)
/// Timer B Control - time-of-day write mode (0: TOD clock, 1: TOD alarm)
const char CIA_TIMER_CONTROL_B_TOD_ALARM_SET = 0b10000000;

View File

@ -1,6 +1,6 @@
// MOS 6529 Single Port Interface (SPI aka PIO)
// I/O controller providing a single 8-bit digital bidirectional parallel I/O port.
// http://archive.6502.org/datasheets/mos_6529_spi.pdf
/// MOS 6529 Single Port Interface (SPI aka PIO)
/// I/O controller providing a single 8-bit digital bidirectional parallel I/O port.
/// http://archive.6502.org/datasheets/mos_6529_spi.pdf
struct MOS6529_PIO {
char PORT;

View File

@ -1,7 +1,7 @@
// MOS 6532 RAM-I/O-Timer (RIOT)
// http://www.ionpool.net/arcade/gottlieb/technical/datasheets/R6532_datasheet.pdf
// http://www.qotile.net/minidig/docs/stella.pdf
// https://en.wikipedia.org/wiki/MOS_Technology_6532
/// MOS 6532 RAM-I/O-Timer (RIOT)
/// http://www.ionpool.net/arcade/gottlieb/technical/datasheets/R6532_datasheet.pdf
/// http://www.qotile.net/minidig/docs/stella.pdf
/// https://en.wikipedia.org/wiki/MOS_Technology_6532
struct MOS6532_RIOT {
// $280 Port A data register for joysticks: Bits 4-7 for player 1. Bits 0-3 for player 2.

View File

@ -1,7 +1,7 @@
// MOS 6551 6551 ASYNCHRONOUS COMMUNICATION INTERFACE ADAPTER
// used for RS232
// http://archive.6502.org/datasheets/mos_6551_acia.pdf
// https://en.wikipedia.org/wiki/MOS_Technology_6551
/// MOS 6551 6551 ASYNCHRONOUS COMMUNICATION INTERFACE ADAPTER
/// used for RS232
/// http://archive.6502.org/datasheets/mos_6551_acia.pdf
/// https://en.wikipedia.org/wiki/MOS_Technology_6551
struct MOS6551_ACIA {
// DATA port

View File

@ -1,6 +1,6 @@
// MOS 6560/6561 VIDEO INTERFACE CHIP
// Used in VIC 20
// http://archive.6502.org/datasheets/mos_6560_6561_vic.pdf
/// MOS 6560/6561 VIDEO INTERFACE CHIP
/// Used in VIC 20
/// http://archive.6502.org/datasheets/mos_6560_6561_vic.pdf
struct MOS6561_VIC {
// Screen Origin X-coordinate

View File

@ -1,7 +1,7 @@
// MOS 6567 / 6569 Video Interface Chip (VIC II)
// http://archive.6502.org/datasheets/mos_6567_vic_ii_preliminary.pdf
// https://dustlayer.com/vic-ii/2013/4/22/when-visibility-matters
// http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt
/// MOS 6567 / 6569 Video Interface Chip (VIC II)
/// http://archive.6502.org/datasheets/mos_6567_vic_ii_preliminary.pdf
/// https://dustlayer.com/vic-ii/2013/4/22/when-visibility-matters
/// http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt
struct MOS6569_VICII {
// $D000 X-Coordinate Sprite#0
char SPRITE0_X;
@ -143,13 +143,13 @@ struct MOS6569_VICII {
char SPRITE7_COLOR;
};
// Positions of the border (in sprite positions)
/// Positions of the border (in sprite positions)
const char BORDER_XPOS_LEFT=24;
const unsigned int BORDER_XPOS_RIGHT=344;
const char BORDER_YPOS_TOP=50;
const char BORDER_YPOS_BOTTOM=250;
// The offset of the sprite pointers from the screen start address
/// The offset of the sprite pointers from the screen start address
const unsigned int OFFSET_SPRITE_PTRS = 0x3f8;
char * const SPRITES_XPOS = (char*)$d000;
@ -188,12 +188,12 @@ const char VICII_CSEL = %00001000;
char* const VICII_MEMORY = (char*)$d018;
char* const D018 = (char*)$d018;
// VIC II IRQ Status Register
/// VIC II IRQ Status Register
char* const IRQ_STATUS = (char*)$d019;
// VIC II IRQ Enable Register
/// VIC II IRQ Enable Register
char* const IRQ_ENABLE = (char*)$d01a;
// Bits for the VICII IRQ Status/Enable Registers
/// Bits for the VICII IRQ Status/Enable Registers
const char IRQ_RASTER = %00000001;
const char IRQ_COLLISION_BG = %00000010;
const char IRQ_COLLISION_SPRITE = %00000100;

View File

@ -1,5 +1,5 @@
// The MOS 6581/8580 SID (Sound Interface Device)
// http://archive.6502.org/datasheets/mos_6581_sid.pdf
/// The MOS 6581/8580 SID (Sound Interface Device)
/// http://archive.6502.org/datasheets/mos_6581_sid.pdf
struct MOS6581_SID {
// Channel 1 Frequency
unsigned int CH1_FREQ;
@ -49,45 +49,45 @@ struct MOS6581_SID {
char CH3_ENV;
};
// Channel 1 Frequency Low byte
/// Channel 1 Frequency Low byte
char * const SID_CH1_FREQ_LO = (char*)0xd400;
// Channel 1 Frequency High byte
/// Channel 1 Frequency High byte
char * const SID_CH1_FREQ_HI = (char*)0xd401;
// Channel 1 Pulse Width (0-4095) Low byte
/// Channel 1 Pulse Width (0-4095) Low byte
char * const SID_CH1_PULSE_WIDTH_LO = (char*)0xd402;
// Channel 1 Pulse Width (0-4095) High byte
/// Channel 1 Pulse Width (0-4095) High byte
char * const SID_CH1_PULSE_WIDTH_HI = (char*)0xd403;
// Channel 2 Frequency Low byte
/// Channel 2 Frequency Low byte
char * const SID_CH2_FREQ_LO = (char*)0xd407;
// Channel 2 Frequency High byte
/// Channel 2 Frequency High byte
char * const SID_CH2_FREQ_HI = (char*)0xd408;
// Channel 2 Pulse Width (0-4095) Low byte
/// Channel 2 Pulse Width (0-4095) Low byte
char * const SID_CH2_PULSE_WIDTH_LO = (char*)0xd409;
// Channel 2 Pulse Width (0-4095) High byte
/// Channel 2 Pulse Width (0-4095) High byte
char * const SID_CH2_PULSE_WIDTH_HI = (char*)0xd40a;
// Channel 3 Frequency Low byte
/// Channel 3 Frequency Low byte
char * const SID_CH3_FREQ_LO = (char*)0xd40e;
// Channel 3 Frequency High byte
/// Channel 3 Frequency High byte
char * const SID_CH3_FREQ_HI = (char*)0xd40f;
// Channel 3 Pulse Width (0-4095) Low byte
/// Channel 3 Pulse Width (0-4095) Low byte
char * const SID_CH3_PULSE_WIDTH_LO = (char*)0xd410;
// Channel 3 Pulse Width (0-4095) High byte
/// Channel 3 Pulse Width (0-4095) High byte
char * const SID_CH3_PULSE_WIDTH_HI = (char*)0xd411;
// SID Channel Control Register Noise Waveform
/// SID Channel Control Register Noise Waveform
const char SID_CONTROL_NOISE = 0x80;
// SID Channel Control Register Pulse Waveform / Square Wave
/// SID Channel Control Register Pulse Waveform / Square Wave
const char SID_CONTROL_PULSE = 0x40;
// SID Channel Control Register Sawtooth Waveform
/// SID Channel Control Register Sawtooth Waveform
const char SID_CONTROL_SAWTOOTH = 0x20;
// SID Channel Control Register Triangle Waveform
/// SID Channel Control Register Triangle Waveform
const char SID_CONTROL_TRIANGLE = 0x10;
// SID Channel Control Register Test bit
/// SID Channel Control Register Test bit
const char SID_CONTROL_TEST = 0x08;
// SID Channel Control Register Ring Modulation
/// SID Channel Control Register Ring Modulation
const char SID_CONTROL_RING = 0x04;
// SID Channel Control Register Synchronization
/// SID Channel Control Register Synchronization
const char SID_CONTROL_SYNC = 0x02;
// SID Channel Control Register Gate
/// SID Channel Control Register Gate
const char SID_CONTROL_GATE = 0x01;

View File

@ -1,6 +1,6 @@
// The MOS 7360/8360 TED chip used for graphics and sound in Plus/4 and Commodore 16
// https://www.karlstechnology.com/commodore/TED7360-datasheet.pdf
// http://mclauchlan.site.net.au/scott/C=Hacking/C-Hacking12/gfx.html
/// The MOS 7360/8360 TED chip used for graphics and sound in Plus/4 and Commodore 16
/// https://www.karlstechnology.com/commodore/TED7360-datasheet.pdf
/// http://mclauchlan.site.net.au/scott/C=Hacking/C-Hacking12/gfx.html
struct MOS7360_TED {
// Counter #01. It always starts to decrement from the last written value into it.

View File

@ -1,8 +1,8 @@
// MOS 7501/8501 MICROPROCESSOR
// https://en.wikipedia.org/wiki/MOS_Technology_6510
/// MOS 7501/8501 MICROPROCESSOR
/// https://en.wikipedia.org/wiki/MOS_Technology_6510
// The processor port of the MOS 7501 CPU
// http://hackjunk.com/2017/06/23/commodore-16-plus-4-8501-to-6510-cpu-conversion/
/// The processor port of the MOS 7501 CPU
/// http://hackjunk.com/2017/06/23/commodore-16-plus-4-8501-to-6510-cpu-conversion/
struct MOS7501_PORT {
// The data direction of the port
char DDR;

View File

@ -1,19 +1,19 @@
// Simple binary multiplication implementation
/// Simple binary multiplication implementation
// Perform binary multiplication of two unsigned 8-bit chars into a 16-bit unsigned int
/// Perform binary multiplication of two unsigned 8-bit chars into a 16-bit unsigned int
unsigned int mul8u(char a, char b);
// Multiply of two signed chars to a signed int
// Fixes offsets introduced by using unsigned multiplication
/// Multiply of two signed chars to a signed int
/// Fixes offsets introduced by using unsigned multiplication
int mul8s(signed char a, signed char b);
// Multiply a signed char and an unsigned char (into a signed int)
// Fixes offsets introduced by using unsigned multiplication
/// Multiply a signed char and an unsigned char (into a signed int)
/// Fixes offsets introduced by using unsigned multiplication
int mul8su(signed char a, char b);
// Perform binary multiplication of two unsigned 16-bit unsigned ints into a 32-bit unsigned double unsigned int
/// Perform binary multiplication of two unsigned 16-bit unsigned ints into a 32-bit unsigned double unsigned int
unsigned long mul16u(unsigned int a, unsigned int b);
// Multiply of two signed ints to a signed double unsigned int
// Fixes offsets introduced by using unsigned multiplication
/// Multiply of two signed ints to a signed double unsigned int
/// Fixes offsets introduced by using unsigned multiplication
signed long mul16s(int a, int b);

View File

@ -1,23 +1,23 @@
// Nintendo Entertainment System (NES
// https://en.wikipedia.org/wiki/Nintendo_Entertainment_System_(Model_NES-101)
// https://github.com/gregkrsak/first_nes
/// Nintendo Entertainment System (NES
/// https://en.wikipedia.org/wiki/Nintendo_Entertainment_System_(Model_NES-101)
/// https://github.com/gregkrsak/first_nes
#ifndef __NES__
#error "Target platform must be NES"
#endif
#include <ricoh_2c02.h>
#include <ricoh_2a03.h>
// NES Picture Processing Unit (PPU)
/// NES Picture Processing Unit (PPU)
struct RICOH_2C02 * PPU = (struct RICOH_2C02 *)0x2000;
// NES CPU and audion processing unit (APU)
/// NES CPU and audion processing unit (APU)
struct RICOH_2A03 * APU = (struct RICOH_2A03 *)0x4000;
// Pointer to the start of RAM memory
/// Pointer to the start of RAM memory
char * const MEMORY = (char *)0;
// Sprite Object Attribute Memory Structure
// The memory layout of a sprite in the PPU's OAM memory
/// Sprite Object Attribute Memory Structure
/// The memory layout of a sprite in the PPU's OAM memory
struct SpriteData {
char y;
char tile;
@ -25,98 +25,98 @@ struct SpriteData {
char x;
};
// DMA transfer a complete sprite memory buffer to the PPU
// - The Sprite OAM buffer to transfer (must be aligned to $100 in memory)
/// DMA transfer a complete sprite memory buffer to the PPU
/// - The Sprite OAM buffer to transfer (must be aligned to $100 in memory)
void ppuSpriteBufferDmaTransfer(struct SpriteData* spriteBuffer);
// Disable audio output
/// Disable audio output
void disableAudioOutput();
// Disable video output. This will cause a black screen and disable vblank.
/// Disable video output. This will cause a black screen and disable vblank.
void disableVideoOutput();
// Enable video output. This will enable vblank.
/// Enable video output. This will enable vblank.
void enableVideoOutput();
// Wait for vblank to start
/// Wait for vblank to start
void waitForVBlank();
// Clear the vblank flag
/// Clear the vblank flag
void clearVBlankFlag();
// Initialize the NES after a RESET.
// Clears the memory and sets up the stack
// Note: Calling this will destroy the stack, so it only works if called directly inside the reset routine.
/// Initialize the NES after a RESET.
/// Clears the memory and sets up the stack
/// Note: Calling this will destroy the stack, so it only works if called directly inside the reset routine.
void initNES();
// Read Standard Controller #1
// Returns a byte representing the pushed buttons
// - bit 0: right
// - bit 1: left
// - bit 2: down
// - bit 3: up
// - bit 4: start
// - bit 5: select
// - bit 6: B
// - bit 7: A
/// Read Standard Controller #1
/// Returns a byte representing the pushed buttons
/// - bit 0: right
/// - bit 1: left
/// - bit 2: down
/// - bit 3: up
/// - bit 4: start
/// - bit 5: select
/// - bit 6: B
/// - bit 7: A
char readJoy1();
// Standard Controller Right Button
/// Standard Controller Right Button
const char JOY_RIGHT = 0b00000001;
// Standard Controller Left Button
/// Standard Controller Left Button
const char JOY_LEFT = 0b00000010;
// Standard Controller Down Button
/// Standard Controller Down Button
const char JOY_DOWN = 0b00000100;
// Standard Controller Up Button
/// Standard Controller Up Button
const char JOY_UP = 0b00001000;
// Standard Controller Start Button
/// Standard Controller Start Button
const char JOY_START = 0b00010000;
// Standard Controller Select Button
/// Standard Controller Select Button
const char JOY_SELECT = 0b00100000;
// Standard Controller B Button
/// Standard Controller B Button
const char JOY_B = 0b01000000;
// Standard Controller A Button
/// Standard Controller A Button
const char JOY_A = 0b10000000;
// Prepare for transferring data from the CPU to the PPU
// - ppuData : Pointer in the PPU memory
/// Prepare for transferring data from the CPU to the PPU
/// - ppuData : Pointer in the PPU memory
void ppuDataPrepare(void* const ppuData);
// Put one byte into PPU memory
// The byte is put into the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR
/// Put one byte into PPU memory
/// The byte is put into the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR
void ppuDataPut(char val);
// Read one byte from PPU memory
// The byte is read from the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR
/// Read one byte from PPU memory
/// The byte is read from the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR
char ppuDataRead();
// Fill a number of bytes in the PPU memory
// - ppuData : Pointer in the PPU memory
// - size : The number of bytes to transfer
/// Fill a number of bytes in the PPU memory
/// - ppuData : Pointer in the PPU memory
/// - size : The number of bytes to transfer
void ppuDataFill(void* const ppuData, char val, unsigned int size);
// Transfer a number of bytes from the CPU memory to the PPU memory
// - ppuData : Pointer in the PPU memory
// - cpuData : Pointer to the CPU memory (RAM of ROM)
// - size : The number of bytes to transfer
/// Transfer a number of bytes from the CPU memory to the PPU memory
/// - ppuData : Pointer in the PPU memory
/// - cpuData : Pointer to the CPU memory (RAM of ROM)
/// - size : The number of bytes to transfer
void ppuDataTransfer(void* const ppuData, void* const cpuData, unsigned int size);
// Transfer a number of bytes from the PPU memory to the CPU memory
// - cpuData : Pointer to the CPU memory (RAM of ROM)
// - ppuData : Pointer in the PPU memory
// - size : The number of bytes to transfer
/// Transfer a number of bytes from the PPU memory to the CPU memory
/// - cpuData : Pointer to the CPU memory (RAM of ROM)
/// - ppuData : Pointer in the PPU memory
/// - size : The number of bytes to transfer
void ppuDataFetch(void* const cpuData, void* const ppuData, unsigned int size);
// Transfer a 2x2 tile into the PPU memory
// - ppuData : Pointer in the PPU memory
// - tile : The tile to transfer
/// Transfer a 2x2 tile into the PPU memory
/// - ppuData : Pointer in the PPU memory
/// - tile : The tile to transfer
void ppuDataPutTile(void* const ppuData, char* tile);
// Set one byte in PPU memory
// - ppuData : Pointer in the PPU memory
// - val : The value to set
/// Set one byte in PPU memory
/// - ppuData : Pointer in the PPU memory
/// - val : The value to set
void ppuDataSet(void* const ppuData, char val);
// Get one byte from PPU memory
// - ppuData : Pointer in the PPU memory
/// Get one byte from PPU memory
/// - ppuData : Pointer in the PPU memory
char ppuDataGet(void* const ppuData);

View File

@ -1,16 +1,16 @@
// PEEK and POKE macros for those who want to write BASIC code in C
// Based on https://github.com/cc65/cc65/blob/master/include/peekpoke.h
/// PEEK and POKE macros for those who want to write BASIC code in C
/// Based on https://github.com/cc65/cc65/blob/master/include/peekpoke.h
// Read the absolute memory given by addr and return the value read.
/// Read the absolute memory given by addr and return the value read.
#define PEEK(addr) (*(unsigned char*) (addr))
// Read the absolute memory given by addr and return the value read.
// The byte read from the higher address is the high byte of the return value.
/// Read the absolute memory given by addr and return the value read.
/// The byte read from the higher address is the high byte of the return value.
#define PEEKW(addr) (*(unsigned int*) (addr))
// Writes the value val to the absolute memory address given by addr.
/// Writes the value val to the absolute memory address given by addr.
#define POKE(addr,val) (*(unsigned char*) (addr) = (val))
// Writes the value val to the absolute memory address given by addr.
// The low byte of val is written to the addr, the high byte is written to addr+1.
/// Writes the value val to the absolute memory address given by addr.
/// The low byte of val is written to the addr, the high byte is written to addr+1.
#define POKEW(addr,val) (*(unsigned int*) (addr) = (val))

View File

@ -1,8 +1,8 @@
// Plus/4 / Commodore 16 registers and memory layout
// http://zimmers.net/anonftp/pub/cbm/schematics/computers/plus4/264_Hardware_Spec.pdf
// http://www.zimmers.net/anonftp/pub/cbm/schematics/computers/plus4/Plus_4_Technical_Docs.pdf
// http://personalpages.tds.net/~rcarlsen/cbm/c16/C16_Service_Manual_314001-03_(1984_Oct).pdf
// https://www.floodgap.com/retrobits/ckb/secret/264memory.txt
/// Plus/4 / Commodore 16 registers and memory layout
/// http://zimmers.net/anonftp/pub/cbm/schematics/computers/plus4/264_Hardware_Spec.pdf
/// http://www.zimmers.net/anonftp/pub/cbm/schematics/computers/plus4/Plus_4_Technical_Docs.pdf
/// http://personalpages.tds.net/~rcarlsen/cbm/c16/C16_Service_Manual_314001-03_(1984_Oct).pdf
/// https://www.floodgap.com/retrobits/ckb/secret/264memory.txt
#include <mos7360.h>
#include <mos6551.h>
#include <mos6529.h>
@ -11,30 +11,30 @@
#ifndef __PLUS4__
#error "Target platform must be PLU4"
#endif
// The processor port
// Used for serial I/O and controlling the cassette
/// The processor port
/// Used for serial I/O and controlling the cassette
struct MOS7501_PORT * const PROCESSOR_PORT = (struct MOS7501_PORT *)0x00;
// Default address of screen luminance/color matrix
/// Default address of screen luminance/color matrix
char * const DEFAULT_COLORRAM = (char*)0x0800;
// Default address of screen character matrix
/// Default address of screen character matrix
char * const DEFAULT_SCREEN = (char*)0x0c00;
// The ACIA used for RS232 (only on the Plus/4)
/// The ACIA used for RS232 (only on the Plus/4)
struct MOS6551_ACIA * const ACIA = (struct MOS6551_ACIA *)0xfd00;
// User Port PIO (P0-P7)
// Bit 2 (P2) is used to detect if play on cassette is pressed (CST sense)
/// User Port PIO (P0-P7)
/// Bit 2 (P2) is used to detect if play on cassette is pressed (CST sense)
struct MOS6529_PIO * const USER_PORT = (struct MOS6529_PIO *)0xfd10;
// Keyboard Port PIO (P0-P7)
// The input latch is part of the TED.
/// Keyboard Port PIO (P0-P7)
/// The input latch is part of the TED.
struct MOS6529_PIO * const KEYBOARD_PORT = (struct MOS6529_PIO *)0xfd30;
// ROM configuration for the machine, which normally has the BASIC and kernal ROMs enabled.
// The ROM configuration is adjusted by writing to the registers (the value is irrelevant).
// The upper portion of the kernal ROM at $FC00-$FCFF is always enabled no matter what the memory configuration, as are the I/O registers.
/// ROM configuration for the machine, which normally has the BASIC and kernal ROMs enabled.
/// The ROM configuration is adjusted by writing to the registers (the value is irrelevant).
/// The upper portion of the kernal ROM at $FC00-$FCFF is always enabled no matter what the memory configuration, as are the I/O registers.
struct PLUS4_ROM_BANKING {
// $FDD0 enables or disables BASIC,
char BASIC;
@ -54,7 +54,7 @@ struct PLUS4_ROM_BANKING {
struct PLUS4_ROM_BANKING * const ROM_BANKING = (struct PLUS4_ROM_BANKING *)0xfdd0;
// The TED chip controlling video and sound on the Plus/4 and Commodore 16
/// The TED chip controlling video and sound on the Plus/4 and Commodore 16
struct MOS7360_TED * const TED = (struct MOS7360_TED *)0xff00;

View File

@ -1,16 +1,16 @@
// Functions for printing formatted strings
/// Functions for printing formatted strings
#include <stdlib.h>
#include <conio.h>
// Print a formatted string.
// https://en.wikipedia.org/wiki/Printf_format_string
// This implementation supports decimal, octal and hexadecimal radix. It supports min length, left/right justify, zero-padding and always-sign.
/// Print a formatted string.
/// https://en.wikipedia.org/wiki/Printf_format_string
/// This implementation supports decimal, octal and hexadecimal radix. It supports min length, left/right justify, zero-padding and always-sign.
void printf(char* format, ...);
// Print a padding char a number of times
/// Print a padding char a number of times
void printf_padding(char pad, char length);
// Format specifying how to format a printed number
/// Format specifying how to format a printed number
struct printf_format_number {
// The minimal number of chars to output (used for padding with spaces or 0)
char min_length;
@ -26,7 +26,7 @@ struct printf_format_number {
enum RADIX radix;
};
// Buffer used for stringified number being printed
/// Buffer used for stringified number being printed
struct printf_buffer_number {
// Sign used for printing numbers (0 if no sign, '-' if a minus-sign, '+' if a plus-sign)
char sign;
@ -34,29 +34,29 @@ struct printf_buffer_number {
char digits[11];
};
// Print a signed long using a specific format
/// Print a signed long using a specific format
void printf_slong(signed long value, struct printf_format_number format);
// Print an unsigned int using a specific format
/// Print an unsigned int using a specific format
void printf_ulong(unsigned long uvalue, struct printf_format_number format);
// Print a signed integer using a specific format
/// Print a signed integer using a specific format
void printf_sint(signed int value, struct printf_format_number format);
// Print an unsigned int using a specific format
/// Print an unsigned int using a specific format
void printf_uint(unsigned int uvalue, struct printf_format_number format);
// Print a signed char using a specific format
/// Print a signed char using a specific format
void printf_schar(signed char value, struct printf_format_number format);
// Print an unsigned char using a specific format
/// Print an unsigned char using a specific format
void printf_uchar(unsigned char uvalue, struct printf_format_number format);
// Print the contents of the number buffer using a specific format.
// This handles minimum length, zero-filling, and left/right justification from the format
/// Print the contents of the number buffer using a specific format.
/// This handles minimum length, zero-filling, and left/right justification from the format
void printf_number_buffer(struct printf_buffer_number buffer, struct printf_format_number format);
// Format specifying how to format a printed string
/// Format specifying how to format a printed string
struct printf_format_string {
// The minimal number of chars to output (used for padding with spaces or 0).
char min_length;
@ -64,6 +64,6 @@ struct printf_format_string {
char justify_left;
};
// Print a string value using a specific format
// Handles justification and min length
/// Print a string value using a specific format
/// Handles justification and min length
void printf_string(char* str, struct printf_format_string format);

View File

@ -1,13 +1,13 @@
// Ricoh 2A03 Nintendo Entertainment System CPU and audio processing unit (APU)
// Ricoh 2A03 or RP2A03 (NTSC version) / Ricoh 2A07 or RP2A07 (PAL version)
// https://en.wikipedia.org/wiki/Ricoh_2A03
// https://www.nesdev.com/2A03%20technical%20reference.txt
// https://wiki.nesdev.com/w/index.php/2A03
// https://wiki.nesdev.com/w/index.php/APU
// Based on: https://github.com/gregkrsak/first_nes written by Greg M. Krsak, 2018.
/// Ricoh 2A03 Nintendo Entertainment System CPU and audio processing unit (APU)
/// Ricoh 2A03 or RP2A03 (NTSC version) / Ricoh 2A07 or RP2A07 (PAL version)
/// https://en.wikipedia.org/wiki/Ricoh_2A03
/// https://www.nesdev.com/2A03%20technical%20reference.txt
/// https://wiki.nesdev.com/w/index.php/2A03
/// https://wiki.nesdev.com/w/index.php/APU
/// Based on: https://github.com/gregkrsak/first_nes written by Greg M. Krsak, 2018.
// The APU (Audio Processing Unit) is the sound hardware the NES console which generates sound.
/// The APU (Audio Processing Unit) is the sound hardware the NES console which generates sound.
struct RICOH_2A03 {
// APU Square wave channels 1 and 2
// Reference: https://wiki.nesdev.com/w/index.php/APU_Pulse
@ -105,17 +105,17 @@ struct RICOH_2A03 {
char JOY2;
};
// APU Frame Counter
// generates low-frequency clocks for the channels and an optional 60 Hz interrupt.
// https://wiki.nesdev.com/w/index.php/APU_Frame_Counter
// ------+-----+---------------------------------------------------------------
// $4017 | W | FR_COUNTER Frame Counter Set mode and interrupt
// ------+-----+---------------------------------------------------------------
// | 7 | Sequencer mode: 0 selects 4-step sequence, 1 selects 5-step sequence
// | 6 | Interrupt inhibit flag. If set, the frame interrupt flag is cleared, otherwise it is unaffected.
// ------+-----+---------------------------------------------------------------
// Side effects After 3 or 4 CPU clock cycles*, the timer is reset.
// If the mode flag is set, then both "quarter frame" and "half frame" signals are also generated.
/// APU Frame Counter
/// generates low-frequency clocks for the channels and an optional 60 Hz interrupt.
/// https://wiki.nesdev.com/w/index.php/APU_Frame_Counter
/// ------+-----+---------------------------------------------------------------
/// $4017 | W | FR_COUNTER Frame Counter Set mode and interrupt
/// ------+-----+---------------------------------------------------------------
/// | 7 | Sequencer mode: 0 selects 4-step sequence, 1 selects 5-step sequence
/// | 6 | Interrupt inhibit flag. If set, the frame interrupt flag is cleared, otherwise it is unaffected.
/// ------+-----+---------------------------------------------------------------
/// Side effects After 3 or 4 CPU clock cycles*, the timer is reset.
/// If the mode flag is set, then both "quarter frame" and "half frame" signals are also generated.
char * const FR_COUNTER = (char*)0x4017;

View File

@ -1,35 +1,35 @@
// Ricoh 2C02 - NES Picture Processing Unit (PPU)
// Ricoh RP2C02 (NTSC version) / RP2C07 (PAL version),
// https://en.wikipedia.org/wiki/Picture_Processing_Unit
// https://wiki.nesdev.com/w/index.php/PPU_registers
// http://nesdev.com/2C02%20technical%20reference.TXT
// Based on: https://github.com/gregkrsak/first_nes written by Greg M. Krsak, 2018.
/// Ricoh 2C02 - NES Picture Processing Unit (PPU)
/// Ricoh RP2C02 (NTSC version) / RP2C07 (PAL version),
/// https://en.wikipedia.org/wiki/Picture_Processing_Unit
/// https://wiki.nesdev.com/w/index.php/PPU_registers
/// http://nesdev.com/2C02%20technical%20reference.TXT
/// Based on: https://github.com/gregkrsak/first_nes written by Greg M. Krsak, 2018.
// PPU Memory Map
// $0000-$0fff $1000 Pattern table 0
/// PPU Memory Map
/// $0000-$0fff $1000 Pattern table 0
char * const PPU_PATTERN_TABLE_0 = (char*)0x0000;
// $1000-$1fff $1000 Pattern table 1
/// $1000-$1fff $1000 Pattern table 1
char * const PPU_PATTERN_TABLE_1 = (char*)0x1000;
// $2000-$23bf $03c0 Name table 0
/// $2000-$23bf $03c0 Name table 0
char * const PPU_NAME_TABLE_0 = (char*)0x2000;
// $23c0-$23ff $0040 Attribute table 0
/// $23c0-$23ff $0040 Attribute table 0
char * const PPU_ATTRIBUTE_TABLE_0 = (char*)0x23c0;
// $2400-$27bf $03c0 Name table 1
/// $2400-$27bf $03c0 Name table 1
char * const PPU_NAME_TABLE_1 = (char*)0x2400;
// $27c0-$27ff $0040 Attribute table 1
/// $27c0-$27ff $0040 Attribute table 1
char * const PPU_ATTRIBUTE_TABLE_1 = (char*)0x27c0;
// $2800-$2bbf $03c0 Name table 2
/// $2800-$2bbf $03c0 Name table 2
char * const PPU_NAME_TABLE_2 = (char*)0x2800;
// $2bc0-$2bff $0040 Attribute table 2
/// $2bc0-$2bff $0040 Attribute table 2
char * const PPU_ATTRIBUTE_TABLE_2 = (char*)0x2bc0;
// $2c00-$2fbf $03c0 Name table 3
/// $2c00-$2fbf $03c0 Name table 3
char * const PPU_NAME_TABLE_3 = (char*)0x2c00;
// $2fc0-$2fff $0040 Attribute table 3
/// $2fc0-$2fff $0040 Attribute table 3
char * const PPU_ATTRIBUTE_TABLE_3 = (char*)0x2fc0;
// $3000-$3eff $0f00 Mirrors of $2000-$2eff
// $3f00-$3f1f $0020 Palette RAM indexes
/// $3000-$3eff $0f00 Mirrors of $2000-$2eff
/// $3f00-$3f1f $0020 Palette RAM indexes
char * const PPU_PALETTE = (char*)0x3f00;
// $3f20-$3fff $00e0 Mirrors of $3f00-$3f1f
/// $3f20-$3fff $00e0 Mirrors of $3f00-$3f1f
struct RICOH_2C02 {
// ------+-----+---------------------------------------------------------------
@ -135,8 +135,8 @@ struct RICOH_2C02 {
char PPUDATA; // Reference: https://wiki.nesdev.com/w/index.php/PPU_registers#PPUDATA
};
// PPU Status Register for reading in ASM
/// PPU Status Register for reading in ASM
volatile char * const PPU_PPUSTATUS = (char*)0x2002;
// PPU Data Register for reading in ASM
/// PPU Data Register for reading in ASM
volatile char * const PPU_PPUDATA = (char*)0x2007;

View File

@ -1,52 +1,52 @@
// Sine Generator functions using only multiplication, addition and bit shifting
// Uses a single division for converting the wavelength to a reciprocal.
// Generates sine using the series sin(x) = x - x^/3! + x^-5! - x^7/7! ...
// Uses the approximation sin(x) = x - x^/6 + x^/128
// Optimization possibility: Use symmetries when generating sine tables. wavelength%2==0 -> mirror symmetry over PI, wavelength%4==0 -> mirror symmetry over PI/2.
/// Sine Generator functions using only multiplication, addition and bit shifting
/// Uses a single division for converting the wavelength to a reciprocal.
/// Generates sine using the series sin(x) = x - x^/3! + x^-5! - x^7/7! ...
/// Uses the approximation sin(x) = x - x^/6 + x^/128
/// Optimization possibility: Use symmetries when generating sine tables. wavelength%2==0 -> mirror symmetry over PI, wavelength%4==0 -> mirror symmetry over PI/2.
// PI*2 in u[4.28] format
/// PI*2 in u[4.28] format
extern const unsigned long PI2_u4f28;
// PI in u[4.28] format
/// PI in u[4.28] format
extern const unsigned long PI_u4f28;
// PI/2 in u[4.28] format
/// PI/2 in u[4.28] format
extern const unsigned long PI_HALF_u4f28;
// PI*2 in u[4.12] format
/// PI*2 in u[4.12] format
extern const unsigned int PI2_u4f12;
// PI in u[4.12] format
/// PI in u[4.12] format
extern const unsigned int PI_u4f12;
// PI/2 in u[4.12] format
/// PI/2 in u[4.12] format
extern const unsigned int PI_HALF_u4f12;
// Generate signed (large) unsigned int sine table - on the full -$7fff - $7fff range
// sintab - the table to generate into
// wavelength - the number of sine points in a total sine wavelength (the size of the table)
/// Generate signed (large) unsigned int sine table - on the full -$7fff - $7fff range
/// sintab - the table to generate into
/// wavelength - the number of sine points in a total sine wavelength (the size of the table)
void sin16s_gen(int* sintab, unsigned int wavelength);
// Generate signed int sine table - with values in the range min-max.
// sintab - the table to generate into
// wavelength - the number of sine points in a total sine wavelength (the size of the table)
/// Generate signed int sine table - with values in the range min-max.
/// sintab - the table to generate into
/// wavelength - the number of sine points in a total sine wavelength (the size of the table)
void sin16s_gen2(int* sintab, unsigned int wavelength, int min, int max);
// Generate signed char sine table - on the full -$7f - $7f range
// sintab - the table to generate into
// wavelength - the number of sine points in a total sine wavelength (the size of the table)
/// Generate signed char sine table - on the full -$7f - $7f range
/// sintab - the table to generate into
/// wavelength - the number of sine points in a total sine wavelength (the size of the table)
void sin8s_gen(signed char* sintab, unsigned int wavelength);
// Calculate signed int sine sin(x)
// x: unsigned long input u[4.28] in the interval $00000000 - PI2_u4f28
// result: signed int sin(x) s[0.15] - using the full range -$7fff - $7fff
/// Calculate signed int sine sin(x)
/// x: unsigned long input u[4.28] in the interval $00000000 - PI2_u4f28
/// result: signed int sin(x) s[0.15] - using the full range -$7fff - $7fff
int sin16s(unsigned long x);
// Calculate signed char sine sin(x)
// x: unsigned int input u[4.12] in the interval $0000 - PI2_u4f12
// result: signed char sin(x) s[0.7] - using the full range -$7f - $7f
/// Calculate signed char sine sin(x)
/// x: unsigned int input u[4.12] in the interval $0000 - PI2_u4f12
/// result: signed char sin(x) s[0.7] - using the full range -$7f - $7f
signed char sin8s(unsigned int x);
// Calculate val*val for two unsigned int values - the result is 16 selected bits of the 32-bit result.
// The select parameter indicates how many of the highest bits of the 32-bit result to skip
/// Calculate val*val for two unsigned int values - the result is 16 selected bits of the 32-bit result.
/// The select parameter indicates how many of the highest bits of the 32-bit result to skip
unsigned int mulu16_sel(unsigned int v1, unsigned int v2, char select);
// Calculate val*val for two unsigned char values - the result is 8 selected bits of the 16-bit result.
// The select parameter indicates how many of the highest bits of the 16-bit result to skip
/// Calculate val*val for two unsigned char values - the result is 8 selected bits of the 16-bit result.
/// The select parameter indicates how many of the highest bits of the 16-bit result to skip
char mulu8_sel(char v1, char v2, char select);

View File

@ -1,14 +1,14 @@
// Table-based implementation of integer square sqr() and square root sqrt()
/// Table-based implementation of integer square sqr() and square root sqrt()
// Initialize squares table
// Uses iterative formula (x+1)^2 = x^2 + 2*x + 1
/// Initialize squares table
/// Uses iterative formula (x+1)^2 = x^2 + 2*x + 1
void init_squares();
// Find the square of a char value
// Uses a table of squares that must be initialized by calling init_squares()
/// Find the square of a char value
/// Uses a table of squares that must be initialized by calling init_squares()
unsigned int sqr(char val);
// Find the (integer) square root of a unsigned int value
// If the square is not an integer then it returns the largest integer N where N*N <= val
// Uses a table of squares that must be initialized by calling init_squares()
/// Find the (integer) square root of a unsigned int value
/// If the square is not an integer then it returns the largest integer N where N*N <= val
/// Uses a table of squares that must be initialized by calling init_squares()
char sqrt(unsigned int val);

View File

@ -1,54 +1,54 @@
// C standard library stdint.h
// Defines a set of integral type aliases with specific width requirements, along with macros specifying their limits and macro functions to create values of these types.
/// C standard library stdint.h
/// Defines a set of integral type aliases with specific width requirements, along with macros specifying their limits and macro functions to create values of these types.
// Unsigned integer type with a width of exactly 8 bits
/// Unsigned integer type with a width of exactly 8 bits
typedef unsigned char uint8_t;
// Signed integer type with a width of exactly 8 bits
/// Signed integer type with a width of exactly 8 bits
typedef signed char int8_t;
// Unsigned integer type with a width of exactly 16 bits
/// Unsigned integer type with a width of exactly 16 bits
typedef unsigned int uint16_t;
// Sisigned integer type with a width of exactly 16 bits
/// Sisigned integer type with a width of exactly 16 bits
typedef signed int int16_t;
// Unsigned integer type with a width of exactly 32 bits
/// Unsigned integer type with a width of exactly 32 bits
typedef unsigned long uint32_t;
// Siigned integer type with a width of exactly 32 bits
/// Siigned integer type with a width of exactly 32 bits
typedef signed long int32_t;
// Unsigned integer type with the maximum width supported.
/// Unsigned integer type with the maximum width supported.
typedef unsigned long uintmax_t;
// Signed integer type with the maximum width supported.
/// Signed integer type with the maximum width supported.
typedef signed long intmax_t;
//TODO: Convert all limits to macros
// Minimum value of exactly 8-bit wide unsigned type
/// Minimum value of exactly 8-bit wide unsigned type
const uint8_t UINT8_MIN = 0;
// Maximum value of exactly 8-bit wide unsigned type
/// Maximum value of exactly 8-bit wide unsigned type
const uint8_t UINT8_MAX = 255;
// Minimum value of exactly 8-bit wide signed type
/// Minimum value of exactly 8-bit wide signed type
const int8_t INT8_MIN = -128;
// Maximum value of exactly 8-bit wide signed type
/// Maximum value of exactly 8-bit wide signed type
const int8_t INT8_MAX = 127;
// Minimum value of exactly 16-bit wide unsigned type
/// Minimum value of exactly 16-bit wide unsigned type
const uint16_t UINT16_MIN = 0;
// Maximum value of exactly 16-bit wide unsigned type
/// Maximum value of exactly 16-bit wide unsigned type
const uint16_t UINT16_MAX = 65535;
// Minimum value of exactly 16-bit wide signed type
/// Minimum value of exactly 16-bit wide signed type
const int16_t INT16_MIN = -32768;
// Maximum value of exactly 16-bit wide signed type
/// Maximum value of exactly 16-bit wide signed type
const int16_t INT16_MAX = 32767;
// Minimum value of exactly 16-bit wide unsigned type
/// Minimum value of exactly 16-bit wide unsigned type
const uint32_t UINT32_MIN = 0;
// Maximum value of exactly 32-bit wide unsigned type
/// Maximum value of exactly 32-bit wide unsigned type
const uint32_t UINT32_MAX = 4194304;
// Minimum value of exactly 32-bit wide signed type
/// Minimum value of exactly 32-bit wide signed type
const int32_t INT32_MIN = -2097152;
// Maximum value of exactly 32-bit wide signed type
/// Maximum value of exactly 32-bit wide signed type
const int32_t INT32_MAX = 2097151;
// Minimum value of exactly 16-bit wide unsigned type
/// Minimum value of exactly 16-bit wide unsigned type
const uint32_t UINTMAX_MIN = UINT32_MIN;
// Maximum value of exactly 32-bit wide unsigned type
/// Maximum value of exactly 32-bit wide unsigned type
const uint32_t UINTMAX_MAX = UINT32_MAX;
// Minimum value of exactly 32-bit wide signed type
/// Minimum value of exactly 32-bit wide signed type
const int32_t INTMAX_MIN = INT32_MIN;
// Maximum value of exactly 32-bit wide signed type
/// Maximum value of exactly 32-bit wide signed type
const int32_t INTMAX_MAX = INT32_MAX;

View File

@ -1,3 +1,3 @@
// Functions for performing input and output.
/// Functions for performing input and output.
#include <printf.h>

View File

@ -1,58 +1,58 @@
// C standard library stdlib.h
// Implementation of functions found int C stdlib.h / stdlib.c
/// C standard library stdlib.h
/// Implementation of functions found int C stdlib.h / stdlib.c
#include <string.h>
// Allocates a block of size chars of memory, returning a pointer to the beginning of the block.
// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
/// Allocates a block of size chars of memory, returning a pointer to the beginning of the block.
/// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.
void* malloc(unsigned int size);
// A block of memory previously allocated by a call to malloc is deallocated, making it available again for further allocations.
// If ptr is a null pointer, the function does nothing.
/// A block of memory previously allocated by a call to malloc is deallocated, making it available again for further allocations.
/// If ptr is a null pointer, the function does nothing.
void free(void* ptr);
// Allocates memory and returns a pointer to it. Sets allocated memory to zero.
// - nitems This is the number of elements to be allocated.
// - size This is the size of elements.
/// Allocates memory and returns a pointer to it. Sets allocated memory to zero.
/// - nitems This is the number of elements to be allocated.
/// - size This is the size of elements.
void *calloc(size_t nitems, size_t size);
// Searches an array of nitems unsigned ints, the initial member of which is pointed to by base, for a member that matches the value key.
// - key - The value to look for
// - items - Pointer to the start of the array to search in
// - num - The number of items in the array
// Returns pointer to an entry in the array that matches the search key
/// Searches an array of nitems unsigned ints, the initial member of which is pointed to by base, for a member that matches the value key.
/// - key - The value to look for
/// - items - Pointer to the start of the array to search in
/// - num - The number of items in the array
/// Returns pointer to an entry in the array that matches the search key
unsigned int* bsearch16u(unsigned int key, unsigned int* items, char num);
// The different supported radix
/// The different supported radix
enum RADIX { BINARY=2, OCTAL=8, DECIMAL=10, HEXADECIMAL=16 };
// Converts unsigned number value to a string representing it in RADIX format.
// If the leading digits are zero they are not included in the string.
// - value : The number to be converted to RADIX
// - buffer : receives the string representing the number and zero-termination.
// - radix : The radix to convert the number to (from the enum RADIX)
/// Converts unsigned number value to a string representing it in RADIX format.
/// If the leading digits are zero they are not included in the string.
/// - value : The number to be converted to RADIX
/// - buffer : receives the string representing the number and zero-termination.
/// - radix : The radix to convert the number to (from the enum RADIX)
void utoa(unsigned int value, char* buffer, enum RADIX radix);
// Converts unsigned number value to a string representing it in RADIX format.
// If the leading digits are zero they are not included in the string.
// - value : The number to be converted to RADIX
// - buffer : receives the string representing the number and zero-termination.
// - radix : The radix to convert the number to (from the enum RADIX)
/// Converts unsigned number value to a string representing it in RADIX format.
/// If the leading digits are zero they are not included in the string.
/// - value : The number to be converted to RADIX
/// - buffer : receives the string representing the number and zero-termination.
/// - radix : The radix to convert the number to (from the enum RADIX)
void ultoa(unsigned long value, char* buffer, enum RADIX radix);
// Converts the string argument str to an integer.
/// Converts the string argument str to an integer.
int atoi(const char *str);
// Returns the absolute value of int x.
/// Returns the absolute value of int x.
int abs(int x);
// Returns the absolute value of long int x.
/// Returns the absolute value of long int x.
long labs(long x);
// The maximal random value
/// The maximal random value
#define RAND_MAX 65335
// Returns a pseudo-random number in the range of 0 to RAND_MAX (65535)
/// Returns a pseudo-random number in the range of 0 to RAND_MAX (65535)
unsigned int rand();
// Seeds the random number generator used by the function rand.
/// Seeds the random number generator used by the function rand.
void srand(unsigned int seed);

View File

@ -1,28 +1,28 @@
// C standard library string.h
// Functions to manipulate C strings and arrays.
/// C standard library string.h
/// Functions to manipulate C strings and arrays.
typedef unsigned int size_t ;
// Copy block of memory (forwards)
// Copies the values of num chars from the location pointed to by source directly to the memory block pointed to by destination.
/// Copy block of memory (forwards)
/// Copies the values of num chars from the location pointed to by source directly to the memory block pointed to by destination.
void* memcpy( void* destination, void* source, size_t num );
// Move block of memory
// Copies the values of num chars from the location pointed by source to the memory block pointed by destination. Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap.
/// Move block of memory
/// Copies the values of num chars from the location pointed by source to the memory block pointed by destination. Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap.
void* memmove( void* destination, void* source, size_t num );
// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str.
/// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str.
void *memset(void *str, char c, size_t num);
// Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
/// Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
char* strcpy( char* destination, char* source );
// Computes the length of the string str up to but not including the terminating null character.
/// Computes the length of the string str up to but not including the terminating null character.
size_t strlen(char *str);
// Searches for the first occurrence of the character c (an unsigned char) in the first n bytes of the string pointed to, by the argument str.
// - str: The memory to search
// - c: A character to search for
// - n: The number of bytes to look through
// Return: A pointer to the matching byte or NULL if the character does not occur in the given memory area.
/// Searches for the first occurrence of the character c (an unsigned char) in the first n bytes of the string pointed to, by the argument str.
/// - str: The memory to search
/// - c: A character to search for
/// - n: The number of bytes to look through
/// Return: A pointer to the matching byte or NULL if the character does not occur in the given memory area.
void *memchr(const void *str, char c, size_t n);

View File

@ -1,6 +1,6 @@
// Commodore VIC 20 registers and memory layout
// http://sleepingelephant.com/denial/wiki/index.php?title=Memory_Map
// http://www.zimmers.net/anonftp/pub/cbm/vic20/manuals/VIC-20_Programmers_Reference_Guide_1st_Edition_6th_Printing.pdf
/// Commodore VIC 20 registers and memory layout
/// http://sleepingelephant.com/denial/wiki/index.php?title=Memory_Map
/// http://www.zimmers.net/anonftp/pub/cbm/vic20/manuals/VIC-20_Programmers_Reference_Guide_1st_Edition_6th_Printing.pdf
#include <mos6561.h>
#include <mos6522.h>
@ -8,25 +8,25 @@
#error "Target platform must be VIC20"
#endif
// Default address of screen color matrix
/// Default address of screen color matrix
char * const DEFAULT_COLORRAM = (char*)0x9600;
// Address of screen color matrix if bit 7 of $9002 is 1
/// Address of screen color matrix if bit 7 of $9002 is 1
char * const ALTERNATIVE_COLORRAM = (char*)0x9400;
// Default address of screen character matrix
/// Default address of screen character matrix
char * const DEFAULT_SCREEN = (char*)0x1e00;
// The address of the CHARGEN character set
/// The address of the CHARGEN character set
char * const CHARGEN = (char*)0x8000;
// The MOS 6560/6561 VIC Video Interface Chip
/// The MOS 6560/6561 VIC Video Interface Chip
struct MOS6561_VIC * const VIC = (struct MOS6561_VIC *)0x9000;
// The VIA#1: User port, RS-232, Joystick, Lightpen, Cassette
/// The VIA#1: User port, RS-232, Joystick, Lightpen, Cassette
struct MOS6522_VIA * const VIA1 = (struct MOS6522_VIA *)0x9110;
// The VIA#2: Keyboard, Joystick, Cassette
/// The VIA#2: Keyboard, Joystick, Cassette
struct MOS6522_VIA * const VIA2 = (struct MOS6522_VIA *)0x9120;
// The colors of the VIC 20
/// The colors of the VIC 20
const char BLACK = 0x0;
const char WHITE = 0x1;
const char RED = 0x2;