2019-07-03 19:15:53 +00:00
|
|
|
// Setup and run a simple CIA-timer
|
2020-12-21 07:57:41 +00:00
|
|
|
// Commodore 64 PRG executable file
|
|
|
|
.file [name="cia-timer-simple.prg", type="prg", segments="Program"]
|
|
|
|
.segmentdef Program [segments="Basic, Code, Data"]
|
|
|
|
.segmentdef Basic [start=$0801]
|
|
|
|
.segmentdef Code [start=$80d]
|
|
|
|
.segmentdef Data [startAfter="Code"]
|
|
|
|
.segment Basic
|
2019-07-03 19:15:53 +00:00
|
|
|
:BasicUpstart(main)
|
2021-06-19 19:26:05 +00:00
|
|
|
/// Timer Control - Start/stop timer (0:stop, 1: start)
|
2019-07-03 19:15:53 +00:00
|
|
|
.const CIA_TIMER_CONTROL_START = 1
|
2021-06-19 19:26:05 +00:00
|
|
|
/// Timer B Control - Timer counts (00:system cycles, 01: CNT pulses, 10: timer A underflow, 11: time A underflow while CNT is high)
|
2019-07-03 19:15:53 +00:00
|
|
|
.const CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A = $40
|
2020-04-30 20:15:59 +00:00
|
|
|
.const OFFSET_STRUCT_MOS6526_CIA_TIMER_A_CONTROL = $e
|
|
|
|
.const OFFSET_STRUCT_MOS6526_CIA_TIMER_B_CONTROL = $f
|
2021-06-19 19:26:05 +00:00
|
|
|
/// The CIA#2: Serial bus, RS-232, VIC memory bank
|
2020-04-27 22:30:35 +00:00
|
|
|
.label CIA2 = $dd00
|
2021-06-19 19:26:05 +00:00
|
|
|
/// CIA#2 timer A&B as one single 32-bit value
|
2020-04-27 22:30:35 +00:00
|
|
|
.label CIA2_TIMER_AB = $dd04
|
2019-07-03 19:15:53 +00:00
|
|
|
.label SCREEN = $400
|
2020-12-21 07:57:41 +00:00
|
|
|
.segment Code
|
2019-07-03 19:15:53 +00:00
|
|
|
main: {
|
2020-02-23 08:44:36 +00:00
|
|
|
// clock_start()
|
2020-03-07 21:38:40 +00:00
|
|
|
// Reset & start the CIA#2 timer A+B
|
2019-07-03 20:22:25 +00:00
|
|
|
jsr clock_start
|
2019-09-29 21:13:37 +00:00
|
|
|
__b1:
|
2020-02-23 08:44:36 +00:00
|
|
|
// clock()
|
2019-07-03 20:22:25 +00:00
|
|
|
jsr clock
|
2020-04-13 18:00:13 +00:00
|
|
|
// print_ulong_at(clock(), SCREEN)
|
|
|
|
jsr print_ulong_at
|
2019-09-29 21:13:37 +00:00
|
|
|
jmp __b1
|
2019-07-03 19:15:53 +00:00
|
|
|
}
|
2020-06-27 21:26:57 +00:00
|
|
|
// Reset & start the processor clock time. The value can be read using clock().
|
|
|
|
// This uses CIA #2 Timer A+B on the C64
|
|
|
|
clock_start: {
|
|
|
|
// CIA2->TIMER_A_CONTROL = CIA_TIMER_CONTROL_STOP | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES
|
|
|
|
// Setup CIA#2 timer A to count (down) CPU cycles
|
|
|
|
lda #0
|
|
|
|
sta CIA2+OFFSET_STRUCT_MOS6526_CIA_TIMER_A_CONTROL
|
|
|
|
// CIA2->TIMER_B_CONTROL = CIA_TIMER_CONTROL_STOP | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A
|
|
|
|
lda #CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A
|
|
|
|
sta CIA2+OFFSET_STRUCT_MOS6526_CIA_TIMER_B_CONTROL
|
|
|
|
// *CIA2_TIMER_AB = 0xffffffff
|
|
|
|
lda #<$ffffffff
|
|
|
|
sta CIA2_TIMER_AB
|
|
|
|
lda #>$ffffffff
|
|
|
|
sta CIA2_TIMER_AB+1
|
|
|
|
lda #<$ffffffff>>$10
|
|
|
|
sta CIA2_TIMER_AB+2
|
|
|
|
lda #>$ffffffff>>$10
|
|
|
|
sta CIA2_TIMER_AB+3
|
|
|
|
// CIA2->TIMER_B_CONTROL = CIA_TIMER_CONTROL_START | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A
|
|
|
|
lda #CIA_TIMER_CONTROL_START|CIA_TIMER_CONTROL_B_COUNT_UNDERFLOW_A
|
|
|
|
sta CIA2+OFFSET_STRUCT_MOS6526_CIA_TIMER_B_CONTROL
|
|
|
|
// CIA2->TIMER_A_CONTROL = CIA_TIMER_CONTROL_START | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES
|
|
|
|
lda #CIA_TIMER_CONTROL_START
|
|
|
|
sta CIA2+OFFSET_STRUCT_MOS6526_CIA_TIMER_A_CONTROL
|
|
|
|
// }
|
|
|
|
rts
|
|
|
|
}
|
|
|
|
// 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: {
|
|
|
|
.label return = 9
|
2021-07-21 23:16:59 +00:00
|
|
|
// CIA2->TIMER_A_CONTROL = CIA_TIMER_CONTROL_STOP | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES
|
|
|
|
// Stop the timer
|
|
|
|
lda #0
|
|
|
|
sta CIA2+OFFSET_STRUCT_MOS6526_CIA_TIMER_A_CONTROL
|
2021-07-27 17:11:14 +00:00
|
|
|
// clock_t ticks = 0xffffffff - *CIA2_TIMER_AB
|
2020-06-27 21:26:57 +00:00
|
|
|
lda #<$ffffffff
|
|
|
|
sec
|
|
|
|
sbc CIA2_TIMER_AB
|
|
|
|
sta.z return
|
|
|
|
lda #>$ffffffff
|
|
|
|
sbc CIA2_TIMER_AB+1
|
|
|
|
sta.z return+1
|
|
|
|
lda #<$ffffffff>>$10
|
|
|
|
sbc CIA2_TIMER_AB+2
|
|
|
|
sta.z return+2
|
|
|
|
lda #>$ffffffff>>$10
|
|
|
|
sbc CIA2_TIMER_AB+3
|
|
|
|
sta.z return+3
|
2021-07-21 23:16:59 +00:00
|
|
|
// CIA2->TIMER_A_CONTROL = CIA_TIMER_CONTROL_START | CIA_TIMER_CONTROL_CONTINUOUS | CIA_TIMER_CONTROL_A_COUNT_CYCLES
|
|
|
|
// Start the timer
|
|
|
|
lda #CIA_TIMER_CONTROL_START
|
|
|
|
sta CIA2+OFFSET_STRUCT_MOS6526_CIA_TIMER_A_CONTROL
|
2020-06-27 21:26:57 +00:00
|
|
|
// }
|
|
|
|
rts
|
|
|
|
}
|
2020-04-13 18:00:13 +00:00
|
|
|
// Print a unsigned long as HEX at a specific position
|
2021-08-10 15:48:55 +00:00
|
|
|
// void print_ulong_at(__zp(9) unsigned long dw, char *at)
|
2020-04-13 18:00:13 +00:00
|
|
|
print_ulong_at: {
|
2019-07-03 19:15:53 +00:00
|
|
|
.label dw = 9
|
2021-06-12 18:57:35 +00:00
|
|
|
// print_uint_at(WORD1(dw), at)
|
2019-08-07 19:00:19 +00:00
|
|
|
lda.z dw+2
|
2020-04-13 18:00:13 +00:00
|
|
|
sta.z print_uint_at.w
|
2019-08-07 19:00:19 +00:00
|
|
|
lda.z dw+3
|
2020-04-13 18:00:13 +00:00
|
|
|
sta.z print_uint_at.w+1
|
2019-07-03 19:15:53 +00:00
|
|
|
lda #<SCREEN
|
2020-04-13 18:00:13 +00:00
|
|
|
sta.z print_uint_at.at
|
2019-07-03 19:15:53 +00:00
|
|
|
lda #>SCREEN
|
2020-04-13 18:00:13 +00:00
|
|
|
sta.z print_uint_at.at+1
|
|
|
|
jsr print_uint_at
|
2021-06-12 18:57:35 +00:00
|
|
|
// print_uint_at(WORD0(dw), at+4)
|
2019-08-07 19:00:19 +00:00
|
|
|
lda.z dw
|
2020-04-13 18:00:13 +00:00
|
|
|
sta.z print_uint_at.w
|
2019-08-07 19:00:19 +00:00
|
|
|
lda.z dw+1
|
2020-04-13 18:00:13 +00:00
|
|
|
sta.z print_uint_at.w+1
|
2019-07-03 19:15:53 +00:00
|
|
|
lda #<SCREEN+4
|
2020-04-13 18:00:13 +00:00
|
|
|
sta.z print_uint_at.at
|
2019-07-03 19:15:53 +00:00
|
|
|
lda #>SCREEN+4
|
2020-04-13 18:00:13 +00:00
|
|
|
sta.z print_uint_at.at+1
|
|
|
|
jsr print_uint_at
|
2020-02-23 08:44:36 +00:00
|
|
|
// }
|
2019-07-03 19:15:53 +00:00
|
|
|
rts
|
|
|
|
}
|
2020-04-13 18:00:13 +00:00
|
|
|
// Print a unsigned int as HEX at a specific position
|
2021-09-23 06:24:56 +00:00
|
|
|
// void print_uint_at(__zp(7) unsigned int w, __zp(4) char *at)
|
2020-04-13 18:00:13 +00:00
|
|
|
print_uint_at: {
|
2021-09-23 06:24:56 +00:00
|
|
|
.label w = 7
|
2019-07-03 19:15:53 +00:00
|
|
|
.label at = 4
|
2021-06-12 18:57:35 +00:00
|
|
|
// print_uchar_at(BYTE1(w), at)
|
2019-08-07 19:00:19 +00:00
|
|
|
lda.z w+1
|
2020-04-13 18:06:30 +00:00
|
|
|
sta.z print_uchar_at.b
|
|
|
|
jsr print_uchar_at
|
2021-06-12 18:57:35 +00:00
|
|
|
// print_uchar_at(BYTE0(w), at+2)
|
2019-08-07 19:00:19 +00:00
|
|
|
lda.z w
|
2020-04-13 18:06:30 +00:00
|
|
|
sta.z print_uchar_at.b
|
2020-01-19 22:37:15 +00:00
|
|
|
lda #2
|
2019-07-03 19:15:53 +00:00
|
|
|
clc
|
2020-04-13 18:06:30 +00:00
|
|
|
adc.z print_uchar_at.at
|
|
|
|
sta.z print_uchar_at.at
|
2019-07-03 19:15:53 +00:00
|
|
|
bcc !+
|
2020-04-13 18:06:30 +00:00
|
|
|
inc.z print_uchar_at.at+1
|
2019-07-03 19:15:53 +00:00
|
|
|
!:
|
2020-04-13 18:06:30 +00:00
|
|
|
jsr print_uchar_at
|
2020-02-23 08:44:36 +00:00
|
|
|
// }
|
2019-07-03 19:15:53 +00:00
|
|
|
rts
|
|
|
|
}
|
2020-04-13 18:00:13 +00:00
|
|
|
// Print a char as HEX at a specific position
|
2021-08-10 15:48:55 +00:00
|
|
|
// void print_uchar_at(__zp(6) char b, __zp(4) char *at)
|
2020-04-13 18:06:30 +00:00
|
|
|
print_uchar_at: {
|
2019-07-03 19:15:53 +00:00
|
|
|
.label b = 6
|
|
|
|
.label at = 4
|
2020-02-23 08:44:36 +00:00
|
|
|
// b>>4
|
2019-08-07 19:00:19 +00:00
|
|
|
lda.z b
|
2019-07-03 19:15:53 +00:00
|
|
|
lsr
|
|
|
|
lsr
|
|
|
|
lsr
|
|
|
|
lsr
|
2020-02-23 08:44:36 +00:00
|
|
|
// print_char_at(print_hextab[b>>4], at)
|
2019-07-03 19:15:53 +00:00
|
|
|
tay
|
|
|
|
ldx print_hextab,y
|
2019-08-07 19:00:19 +00:00
|
|
|
lda.z at
|
|
|
|
sta.z print_char_at.at
|
|
|
|
lda.z at+1
|
|
|
|
sta.z print_char_at.at+1
|
2020-03-07 21:38:40 +00:00
|
|
|
// Table of hexadecimal digits
|
2019-07-03 19:15:53 +00:00
|
|
|
jsr print_char_at
|
2024-01-02 18:45:16 +00:00
|
|
|
// b&0xf
|
2019-07-03 19:15:53 +00:00
|
|
|
lda #$f
|
2019-08-07 19:00:19 +00:00
|
|
|
and.z b
|
2019-07-03 19:15:53 +00:00
|
|
|
tay
|
2024-01-02 18:45:16 +00:00
|
|
|
// print_char_at(print_hextab[b&0xf], at+1)
|
2019-07-03 19:15:53 +00:00
|
|
|
clc
|
2020-10-12 18:28:00 +00:00
|
|
|
lda.z at
|
2019-07-03 19:15:53 +00:00
|
|
|
adc #1
|
2019-08-07 19:00:19 +00:00
|
|
|
sta.z print_char_at.at
|
|
|
|
lda.z at+1
|
2019-07-03 19:15:53 +00:00
|
|
|
adc #0
|
2019-08-07 19:00:19 +00:00
|
|
|
sta.z print_char_at.at+1
|
2019-07-03 19:15:53 +00:00
|
|
|
ldx print_hextab,y
|
|
|
|
jsr print_char_at
|
2020-02-23 08:44:36 +00:00
|
|
|
// }
|
2019-07-03 19:15:53 +00:00
|
|
|
rts
|
|
|
|
}
|
|
|
|
// Print a single char
|
2021-09-23 06:24:56 +00:00
|
|
|
// void print_char_at(__register(X) char ch, __zp(2) char *at)
|
2019-07-03 19:15:53 +00:00
|
|
|
print_char_at: {
|
2021-09-23 06:24:56 +00:00
|
|
|
.label at = 2
|
2020-02-23 08:44:36 +00:00
|
|
|
// *(at) = ch
|
2019-07-03 19:15:53 +00:00
|
|
|
txa
|
|
|
|
ldy #0
|
|
|
|
sta (at),y
|
2020-02-23 08:44:36 +00:00
|
|
|
// }
|
2019-07-03 19:15:53 +00:00
|
|
|
rts
|
|
|
|
}
|
2020-12-21 07:57:41 +00:00
|
|
|
.segment Data
|
2019-07-03 19:15:53 +00:00
|
|
|
print_hextab: .text "0123456789abcdef"
|