summaryrefslogtreecommitdiffstats
path: root/src/tools/gputils/gputils_generator.cpp
blob: 3bcebac6019f9f2e89c20787c35a8c22be900b1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/***************************************************************************
 *   Copyright (C) 2007 Nicolas Hadacek <hadacek@kde.org>                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/
#include "gputils_generator.h"

#include "devices/pic/pic/pic_memory.h"
#include "devices/pic/base/pic_register.h"
#include "devices/list/device_list.h"

//----------------------------------------------------------------------------
QValueList<const Device::Data *> GPUtils::getSupportedDevices(const QString &s)
{
  QStringList devices = QStringList::split(' ', s.simplifyWhiteSpace().upper());
  QValueList<const Device::Data *> list;
  for (uint i=0; i<devices.count(); i++) {
    QString name = devices[i];
    if ( devices[i].startsWith("P1") ) name = name.mid(1);
    const Device::Data *data = Device::lister().data(name);
    if (data) list.append(data);
  }
  return list;
}

//----------------------------------------------------------------------------
SourceLine::List GPUtils::SourceGenerator::configLines(PURL::ToolType, const Device::Memory &memory, bool &ok) const
{
  return GPUtils::generateConfigLines(static_cast<const Pic::Memory &>(memory), ok);
}

SourceLine::List GPUtils::SourceGenerator::includeLines(PURL::ToolType, const Device::Data &data) const
{
  return GPUtils::includeLines(data);
}

SourceLine::List GPUtils::SourceGenerator::sourceFileContent(PURL::ToolType, const Device::Data &data, bool &ok) const
{
  ok = true;
  SourceLine::List lines;
  lines.appendSeparator();
  const Pic::Data &pdata = static_cast<const Pic::Data &>(data);
  const Pic::RegistersData &rdata = static_cast<const Pic::RegistersData &>(*data.registersData());
  switch (pdata.architecture().type()) {
  case Pic::Architecture::P10X:
    lines.appendTitle(i18n("relocatable code"));
    lines.appendNotIndentedCode("PROG CODE");
    lines.appendNotIndentedCode("start");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert code") + " >>");
    lines.appendIndentedCode("goto    $", i18n("loop forever"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("END");
    break;
  case Pic::Architecture::P16X: {
    lines.appendTitle(i18n("Variables declaration"));
    bool needPCLATH = ( pdata.nbWords(Pic::MemoryRangeType::Code)>0x400 );
    uint first;
    bool allShared;
    bool hasShared = rdata.hasSharedGprs(first, allShared);
    if ( hasShared && !allShared ) lines.appendNotIndentedCode("INT_VAR UDATA_SHR");
    else {
      first = rdata.firstGprIndex();
      lines.appendNotIndentedCode("INT_VAR UDATA " + toHexLabel(first, rdata.nbCharsAddress()));
    }
    lines.appendNotIndentedCode("w_saved      RES 1", i18n("variable used for context saving"));
    lines.appendNotIndentedCode("status_saved RES 1", i18n("variable used for context saving"));
    first += 2;
    if (needPCLATH) {
      lines.appendNotIndentedCode("pclath_saved RES 1", i18n("variable used for context saving"));
      first++;
    }
    lines.appendEmpty();
    lines.appendNotIndentedCode("var1         RES 1", i18n("example variable"));
    if ( !hasShared ) {
      for (uint i=1; i<rdata.nbBanks; i++) {
        uint address = first + i*rdata.nbBytesPerBank();
        lines.appendNotIndentedCode(QString("INT_VAR%1 UDATA ").arg(i) + toHexLabel(address, rdata.nbCharsAddress()), i18n("variables used for context saving"));
        lines.appendNotIndentedCode(QString("w_saved%1     RES 1").arg(i), i18n("variable used for context saving"));
      }
    }
    lines.appendEmpty();
    lines.appendSeparator();
    lines.appendTitle(i18n("reset vector"));
    lines.appendNotIndentedCode("STARTUP CODE 0x000");
    lines.appendIndentedCode("nop", i18n("needed for ICD2 debugging"));
    lines.appendIndentedCode("movlw   high start", i18n("load upper byte of 'start' label"));
    lines.appendIndentedCode("movwf   PCLATH", i18n("initialize PCLATH"));
    lines.appendIndentedCode("goto    start", i18n("go to start of main code"));
    lines.appendEmpty();
    lines.appendTitle(i18n("interrupt vector"));
    lines.appendNotIndentedCode("INT_VECTOR CODE 0x004");
    lines.appendIndentedCode("goto    interrupt", i18n("go to start of interrupt code"));
    lines.appendEmpty();
    lines.appendTitle(i18n("relocatable code"));
    lines.appendNotIndentedCode("PROG CODE");
    lines.appendNotIndentedCode("interrupt");
    lines.appendIndentedCode("movwf   w_saved", i18n("save context"));
    lines.appendIndentedCode("swapf   STATUS,w");
    if ( !hasShared ) lines.appendIndentedCode("clrf    STATUS");
    lines.appendIndentedCode("movwf   status_saved");
    if (needPCLATH) {
      lines.appendIndentedCode("movf    PCLATH,w", i18n("only required if using more than first page"));
      lines.appendIndentedCode("movwf   pclath_saved");
      lines.appendIndentedCode("clrf    PCLATH");
    }
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert interrupt code") + " >>");
    if (needPCLATH) {
      lines.appendIndentedCode("movf    pclath_saved,w", i18n("restore context"));
      lines.appendIndentedCode("movwf   PCLATH");
      lines.appendIndentedCode("swapf   status_saved,w");
    } else lines.appendIndentedCode("swapf   status_saved,w", i18n("restore context"));
    lines.appendIndentedCode("movwf   STATUS");
    lines.appendIndentedCode("swapf   w_saved,f");
    lines.appendIndentedCode("swapf   w_saved,w");
    lines.appendIndentedCode("retfie");
    lines.appendEmpty();
    lines.appendNotIndentedCode("start");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert main code") + " >>");
    lines.appendIndentedCode("goto    $", i18n("loop forever"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("END");
    break;
  }
  case Pic::Architecture::P17C:
    lines.appendTitle(i18n("Variables declaration"));
    lines.appendNotIndentedCode("INT_VAR UDATA " + toHexLabel(rdata.accessBankSplit, rdata.nbCharsAddress()));
    lines.appendNotIndentedCode("wred_saved   RES 1", i18n("variable used for context saving (for low-priority interrupts only)"));
    lines.appendNotIndentedCode("alusta_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)"));
    lines.appendNotIndentedCode("bsr_saved    RES 1", i18n("variable used for context saving (for low-priority interrupts only)"));
    lines.appendNotIndentedCode("pclath_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("var1 RES 1", i18n("example variable"));
    lines.appendEmpty();
    lines.appendSeparator();
    lines.appendTitle(i18n("Macros"));
    lines.appendNotIndentedCode("PUSH MACRO", i18n("for saving context"));
    lines.appendIndentedCode("movpf   WREG,wred_saved");
    lines.appendIndentedCode("movpf   ALUSTA,alusta_saved");
    lines.appendIndentedCode("movpf   BSR,bsr_saved");
    lines.appendIndentedCode("movpf   PCLATH,pclath_saved");
    lines.appendIndentedCode("ENDM");
    lines.appendEmpty();
    lines.appendNotIndentedCode("POP MACRO", i18n("for restoringing context"));
    lines.appendIndentedCode("movfp   pclath_saved,PCLATH");
    lines.appendIndentedCode("movfp   bsr_saved,BSR");
    lines.appendIndentedCode("movfp   alusta_saved,ALUSTA");
    lines.appendIndentedCode("movfp   wred_saved,WREG");
    lines.appendIndentedCode("ENDM");
    lines.appendSeparator();
    lines.appendTitle(i18n("reset vector"));
    lines.appendNotIndentedCode("STARTUP CODE 0x0000");
    lines.appendIndentedCode("nop", i18n("needed for ICD2 debugging"));
    lines.appendIndentedCode("nop", i18n("needed for ICD2 debugging"));
    lines.appendIndentedCode("goto    start", i18n("go to start of main code"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("INT_PIN_VECTOR CODE 0x0008");
    lines.appendIndentedCode("PUSH");
    lines.appendIndentedCode("goto    int_pin_isr", i18n("go to start of int pin interrupt code"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("TIMER0_VECTOR CODE 0x0010");
    lines.appendIndentedCode("PUSH");
    lines.appendIndentedCode("goto    timer0_isr", i18n("go to start of timer0 interrupt code"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("T0CKI_VECTOR CODE 0x00018");
    lines.appendIndentedCode("PUSH");
    lines.appendIndentedCode("goto    t0cki_isr", i18n("go to start of t0cki interrupt code"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("PERIPHERAL_VECTOR CODE 0x0020");
    lines.appendIndentedCode("PUSH");
    lines.appendIndentedCode("goto    peripheral_isr", i18n("go to start of peripheral interrupt code"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("start:");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert main code") + " >>");
    lines.appendIndentedCode("goto    $", i18n("loop forever"));
    lines.appendEmpty();
    lines.appendTitle(i18n("INT pin interrupt service routine"));
    lines.appendNotIndentedCode("int_pin_isr:");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert INT pin interrupt code") + " >>");
    lines.appendIndentedCode("POP");
    lines.appendIndentedCode("retfie");
    lines.appendEmpty();
    lines.appendTitle(i18n("TIMER0 interrupt service routine"));
    lines.appendNotIndentedCode("timer0_isr:");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert TIMER0 interrupt code") + " >>");
    lines.appendIndentedCode("POP");
    lines.appendIndentedCode("retfie");
    lines.appendEmpty();
    lines.appendTitle(i18n("T0CKI interrupt service routine"));
    lines.appendNotIndentedCode("t0cki_isr:");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert T0CKI interrupt code") + " >>");
    lines.appendIndentedCode("POP");
    lines.appendIndentedCode("retfie");
    lines.appendEmpty();
    lines.appendTitle(i18n("peripheral interrupt service routine"));
    lines.appendNotIndentedCode("peripheral_isr:");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert peripheral interrupt code") + " >>");
    lines.appendIndentedCode("POP");
    lines.appendIndentedCode("retfie");
    lines.appendEmpty();
    lines.appendNotIndentedCode("END");
    break;
  case Pic::Architecture::P18C:
  case Pic::Architecture::P18F:
  case Pic::Architecture::P18J: // ??
    lines.appendTitle(i18n("Variables declaration"));
    lines.appendNotIndentedCode("INT_VAR UDATA " + toHexLabel(rdata.accessBankSplit, rdata.nbCharsAddress()));
    lines.appendNotIndentedCode("w_saved      RES 1", i18n("variable used for context saving (for low-priority interrupts only)"));
    lines.appendNotIndentedCode("status_saved RES 1", i18n("variable used for context saving (for low-priority interrupts only)"));
    lines.appendNotIndentedCode("bsr_saved    RES 1", i18n("variable used for context saving (for low-priority interrupts only)"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("var1 RES 1", i18n("example variable"));
    lines.appendEmpty();
    lines.appendSeparator();
    lines.appendTitle(i18n("reset vector"));
    lines.appendNotIndentedCode("STARTUP CODE 0x0000");
    lines.appendIndentedCode("nop", i18n("needed for ICD2 debugging"));
    lines.appendIndentedCode("nop", i18n("needed for ICD2 debugging"));
    lines.appendIndentedCode("goto    start", i18n("go to start of main code"));
    lines.appendEmpty();
    lines.appendTitle(i18n("high priority interrupt vector"));
    lines.appendNotIndentedCode("HIGH_INT_VECTOR CODE 0x0008");
    lines.appendIndentedCode("bra    high_interrupt", i18n("go to start of high priority interrupt code"));
    lines.appendEmpty();
    lines.appendTitle(i18n("low priority interrupt vector"));
    lines.appendNotIndentedCode("LOW_INT_VECTOR CODE 0x0018");
    lines.appendIndentedCode("movff   STATUS,status_saved", i18n("save context"));
    lines.appendIndentedCode("movff   WREG,w_saved");
    lines.appendIndentedCode("movff   BSR,bsr_saved");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert low priority interrupt code") + " >>");
    lines.appendIndentedCode("movff   bsr_saved,BSR", i18n("restore context"));
    lines.appendIndentedCode("movff   w_saved,WREG");
    lines.appendIndentedCode("movff   status_saved,STATUS");
    lines.appendIndentedCode("retfie");
    lines.appendEmpty();
    lines.appendTitle(i18n("high priority interrupt service routine"));
    lines.appendNotIndentedCode("high_interrupt:");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert high priority interrupt code") + " >>");
    lines.appendIndentedCode("retfie  FAST");
    lines.appendEmpty();
    lines.appendNotIndentedCode("start:");
    lines.appendIndentedCode(QString::null, "<< " + i18n("insert main code") + " >>");
    lines.appendIndentedCode("goto    $", i18n("loop forever"));
    lines.appendEmpty();
    lines.appendNotIndentedCode("END");
    break;
  case Pic::Architecture::P24F:
  case Pic::Architecture::P24H:
  case Pic::Architecture::P30F:
  case Pic::Architecture::P33F: ok = false; break;
  case Pic::Architecture::Nb_Types: Q_ASSERT(false); break;
  }
  return lines;
}