llvm-mos-sdk
dma.hpp
Go to the documentation of this file.
1 // Copyright 2023 LLVM-MOS Project
2 // Licensed under the Apache License, Version 2.0 with LLVM Exceptions.
3 // See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license
4 // information.
5 //
6 // C++ support for MEGA65 DMA operations.
7 //
8 //
9 #ifndef _MEGA65_DMA_HPP
10 #define _MEGA65_DMA_HPP
11 
12 #include <array>
13 #include <cstdint>
14 #include <mega65.h>
15 #include <type_traits>
16 
17 namespace mega65::dma {
18 
27 template <size_t N, typename T = DMAList_F018B> struct DMAJob {
28  static_assert(N > 0);
32  const uint8_t end_option = 0;
34 };
35 
38 
49 CommonDMAJob make_dma_fill(const uint32_t dst, const uint8_t value,
50  const uint16_t count, const uint8_t skip = 1) {
51  CommonDMAJob dma;
52  dma.options[0] = ENABLE_F018B_OPT;
53  dma.options[1] = SRC_ADDR_BITS_OPT;
54  dma.options[2] = 0;
55  dma.options[3] = DST_ADDR_BITS_OPT;
56  dma.options[4] = (uint8_t)(dst >> 20);
57  dma.options[5] = DST_SKIP_RATE_OPT;
58  dma.options[6] = skip;
59  dma.dmalist.command = DMA_FILL_CMD;
60  dma.dmalist.count = count;
61  dma.dmalist.source_addr = value;
62  dma.dmalist.source_bank = 0;
63  dma.dmalist.dest_addr = dst & 0xffff;
64  dma.dmalist.dest_bank = (dst >> 16) & 0x0f;
65  dma.dmalist.command_msb = 0;
66  dma.dmalist.modulo = 0;
67  return dma;
68 }
69 
80  const uint16_t count) {
81  auto dma = make_dma_fill(dst, 0, count);
82  dma.options[2] = (uint8_t)(src >> 20);
83  dma.dmalist.command = DMA_COPY_CMD;
84  dma.dmalist.source_addr = src & 0xffff;
85  dma.dmalist.source_bank = (src >> 16) & 0x0f;
86  return dma;
87 }
88 
92 template <size_t N, typename T>
93 inline void trigger_dma(const DMAJob<N, T> &dma_job) {
95  DMA.addr_bank = 0;
96  DMA.addr_msb = ((uint16_t)&dma_job) >> 8;
97  DMA.trigger_enhanced = ((uint16_t)&dma_job) & 0xff;
98  // Avoid the above from being optimized out. Ideally
99  // we would want to somehow access `dma_job`, but an
100  // empty statement seems to be sufficient.
101  asm volatile("");
102 }
103 
104 } // namespace mega65::dma
105 #endif // _MEGA65_DMA_HPP
DST_SKIP_RATE_OPT
@ DST_SKIP_RATE_OPT
Destination skip rate (whole bytes) [value follows].
Definition: _dmagic.h:66
type_traits
std::uint16_t
::uint16_t uint16_t
Definition: cstdint:22
mega65::dma
Definition: dma.hpp:17
DMA
#define DMA
DMAgic DMA controller.
Definition: mega65.h:167
mega65::dma::DMAJob
Definition: dma.hpp:27
std::uint8_t
::uint8_t uint8_t
Definition: cstdint:21
mega65.h
DMA_FILL_CMD
@ DMA_FILL_CMD
DMA fill command.
Definition: _dmagic.h:23
count
const void uint16_t count
Definition: memory.h:58
src
const void * src
Definition: memory.h:57
mega65::dma::CommonDMAJob
DMAJob< 7, DMAList_F018B > CommonDMAJob
Common structure for DMA fill and copy jobs.
Definition: dma.hpp:37
array
mega65::dma::make_dma_fill
CommonDMAJob make_dma_fill(const uint32_t dst, const uint8_t value, const uint16_t count, const uint8_t skip=1)
Definition: dma.hpp:49
cstdint
mega65::dma::trigger_dma
void trigger_dma(const DMAJob< N, T > &dma_job)
Definition: dma.hpp:93
DMA_COPY_CMD
@ DMA_COPY_CMD
DMA copy command.
Definition: _dmagic.h:20
ENABLE_F018B_OPT
@ ENABLE_F018B_OPT
Use 12 byte F011B DMA list format [no value].
Definition: _dmagic.h:60
DST_ADDR_BITS_OPT
@ DST_ADDR_BITS_OPT
Destination address bits 20 – 27 [value follows].
Definition: _dmagic.h:64
mega65::dma::DMAJob::end_option
const uint8_t end_option
Definition: dma.hpp:32
std::array< uint8_t, N >
mega65::dma::DMAJob::dmalist
T dmalist
Definition: dma.hpp:33
std::is_same
Definition: type_traits:125
SRC_ADDR_BITS_OPT
@ SRC_ADDR_BITS_OPT
Source address bits 20 – 27 [value follows].
Definition: _dmagic.h:62
mega65::dma::DMAJob::options
std::array< uint8_t, N > options
Definition: dma.hpp:28
std::uint32_t
::uint32_t uint32_t
Definition: cstdint:23
mega65::dma::make_dma_copy
CommonDMAJob make_dma_copy(const uint32_t src, const uint32_t dst, const uint16_t count)
Definition: dma.hpp:79