loader: remove shouting from ORB's variable name
[hvf.git] / build / ccw_gen.c
blob313167d4932f55dc746298c19e5495eb02216c81
1 /*
2 * Copyright (c) 2011-2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/stat.h>
28 static char *deck_head =
29 "#\n"
30 "# NOTE: This file was automatically generated by " __FILE__ "\n"
31 "#\n"
32 "# During the system IPL, 24 bytes are read from the device.\n"
33 "#\n"
34 "# NOTE: zArch IPLs in ESA/390 mode.\n"
35 "#\n"
36 "\n"
37 ".text\n"
38 " .align 4\n"
39 ".globl START\n"
40 " .type START, @function\n"
41 "START:\n";
43 static char *card_head =
44 "\n"
45 "#######################################################################\n"
46 "# CARD %-3d #\n"
47 "#######################################################################\n";
49 static char *psw_head =
50 "#\n"
51 "# Bytes 0-7 contain PSW to be loaded after IO operation completes\n"
52 "#\n";
54 static char *psw =
55 " .byte 0x%c%c\n"
56 " # bits value name desc\n"
57 " # 0 0 <zero>\n"
58 " # 1 0 PER Mask (R) disabled\n"
59 " # 2-4 0 <zero>\n"
60 " # 5 0 DAT Mode (T) disabled\n"
61 " # 6 0 I/O Mask (IO) disabled\n"
62 " # 7 0 External Mask (EX) disabled\n"
63 "\n"
64 " .byte 0x%c%c\n"
65 " # bits value name desc\n"
66 " # 8-11 0 Key\n"
67 " # 12 1 <one>\n"
68 " # 13 0 Machine-Check Mask (M) disabled\n"
69 " # 14 0 Wait State (W) executing\n"
70 " # 15 0 Problem State (P) supervisor state\n"
71 "\n"
72 " .byte 0x%c%c\n"
73 " # bits value name desc\n"
74 " # 16-17 0 Address-Space Control (AS) disabled\n"
75 " # 18-19 0 Condition Code (CC)\n"
76 " # 20-23 0 Program Mask exceptions disabled\n"
77 "\n"
78 " .byte 0x%c%c\n"
79 " # bits value name desc\n"
80 " # 24-30 0 <zero>\n"
81 " # 31 0 Extended Addressing (EA) ! 64 mode\n"
82 "\n"
83 " .byte 0x%c%c # bits 32-39\n"
84 " .byte 0x%c%c # bits 40-47\n"
85 " .byte 0x%c%c # bits 48-55\n"
86 " .byte 0x%c%c # bits 56-63\n"
87 " # bits value name desc\n"
88 " # 32 1 Basic Addressing (BA) BA = 31, !BA = 24\n"
89 " # 33-63 addr Instruction Address Address to exec\n";
91 static char *psw_tail =
92 "\n"
93 "#\n"
94 "# The remaining 16 bytes should contain CCW to read data from device\n"
95 "#\n"
96 "\n"
97 "# CCW format-0:\n"
98 "# bits name\n"
99 "# 0-7 Cmd Code\n"
100 "# 8-31 Data Address\n"
101 "# 32 Chain-Data (CD)\n"
102 "# 33 Chain-Command (CC)\n"
103 "# 34 Sup.-Len.-Inditcation (SLI)\n"
104 "# 35 Skip (SKP)\n"
105 "# 36 Prog.-Contr.-Inter. (PCI)\n"
106 "# 37 Indir.-Data-Addr. (IDA)\n"
107 "# 38 Suspend (S)\n"
108 "# 39 Modified I.D.A. (MIDA)\n"
109 "# 40-47 <ignored>\n"
110 "# 48-63 number of bytes to read\n"
111 "\n"
112 "# CP-CCW 1\n"
113 " # READ 80 bytes of CCWs to 0x%06X\n"
114 " .byte 0x02, 0x%02X, 0x%02X, 0x%02X\n"
115 " .byte 0x%02X, 0x00, 0x00, 0x50\n"
116 "\n"
117 "# CP-CCW 2\n"
118 " # TIC to 0x%06X\n"
119 " .byte 0x08, 0x%02X, 0x%02X, 0x%02X\n"
120 " .byte 0x00, 0x00, 0x00, 0x00\n";
122 static char *pad =
123 "\n"
124 "#\n"
125 "# Pad to 80 bytes\n"
126 "#\n"
127 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
128 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
129 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
130 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
131 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
132 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n"
133 " .byte 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40\n";
135 static char *cp_ccw =
136 "\n"
137 "# CP-CCW %d\n"
138 " .byte 0x02, 0x%02X, 0x%02X, 0x%02X\n"
139 " .byte 0x40, 0x00, 0x00, 0x50\n";
141 #define CHAIN 0x40
143 static char *data_ccw =
144 "\n"
145 "# LOADER-CCW %d\n"
146 " .byte 0x02, 0x%02X, 0x%02X, 0x%02X\n"
147 " .byte 0x%02X, 0x00, 0x00, 0x50\n";
149 static char *nop_ccw =
150 "\n"
151 "# NOP-CCW %d\n"
152 " .byte 0x03, 0x00, 0x00, 0x08\n"
153 " .byte 0x60, 0x00, 0x00, 0x01\n";
155 #define ADDR(x) (((x)[0]<<16) | \
156 ((x)[1]<<8) | \
157 ((x)[2]))
159 #define ADDRS(x) (x)[0], (x)[1], (x)[2]
161 static void die(char *pgm, char *s)
163 fprintf(stderr, "Error: %s\n", s);
164 fprintf(stderr, "Usage: %s <psw word 1> <psw word 2> <loaded file> "
165 "<address> <channel pgm addr>\n", pgm);
166 exit(1);
169 static unsigned int get_file_size(const char *fname)
171 struct stat buf;
172 int ret;
174 ret = stat(fname, &buf);
176 return ret ? 0 : buf.st_size;
179 static unsigned int unhex(char *pgm, char c)
181 if ((c >= '0') && (c <= '9'))
182 return c - '0';
183 if ((c >= 'A') && (c <= 'F'))
184 return c - 'A' + 10;
185 if ((c >= 'a') && (c <= 'f'))
186 return c - 'a' + 10;
187 die(pgm, "Argument not hexadecimal");
188 return 0;
191 static void __add(unsigned int *addr, int a)
193 int i;
195 addr[2] += a;
196 for(i=2; i>=0; i--) {
197 if (addr[i] > 255) {
198 addr[i-1] += addr[i] / 256;
199 addr[i] %= 256;
204 int main(int argc, char **argv)
206 int i = 1, j;
207 unsigned int card;
208 unsigned int ccw_addr[3];
209 unsigned int addr[3];
210 unsigned int size;
211 unsigned int data_cards;
213 if (argc != 6)
214 die(argv[0], "Invalid number of args");
216 if ((strlen(argv[1]) != 8) ||
217 (strlen(argv[2]) != 8))
218 die(argv[0], "Invalid PSW argument length");
220 size = get_file_size(argv[3]);
221 if (!size)
222 die(argv[0], "cannot get file size");
224 if ((strlen(argv[4]) != 6) ||
225 (strlen(argv[5]) != 6))
226 die(argv[0], "Invalid addr argument length");
228 addr[0] = (unhex(argv[0], argv[4][0]) << 4) |
229 unhex(argv[0], argv[4][1]);
230 addr[1] = (unhex(argv[0], argv[4][2]) << 4) |
231 unhex(argv[0], argv[4][3]);
232 addr[2] = (unhex(argv[0], argv[4][4]) << 4) |
233 unhex(argv[0], argv[4][5]);
235 ccw_addr[0] = (unhex(argv[0], argv[5][0]) << 4) |
236 unhex(argv[0], argv[5][1]);
237 ccw_addr[1] = (unhex(argv[0], argv[5][2]) << 4) |
238 unhex(argv[0], argv[5][3]);
239 ccw_addr[2] = (unhex(argv[0], argv[5][4]) << 4) |
240 unhex(argv[0], argv[5][5]);
242 /* round up */
243 if (size % 80)
244 size = size - (size % 80) + 80;
246 data_cards = size / 80;
248 printf(deck_head);
250 printf(card_head, i);
251 printf(psw_head);
252 printf(psw,
253 argv[1][0], argv[1][1], argv[1][2], argv[1][3],
254 argv[1][4], argv[1][5], argv[1][6], argv[1][7],
255 argv[2][0], argv[2][1], argv[2][2], argv[2][3],
256 argv[2][4], argv[2][5], argv[2][6], argv[2][7]);
258 if (data_cards == 1)
259 die(argv[0], "Cannot handle the case where size <= 80");
261 card = 2;
262 i = 0;
263 j = 1;
265 printf(psw_tail, ADDR(ccw_addr), ADDRS(ccw_addr), CHAIN,
266 ADDR(ccw_addr), ADDRS(ccw_addr));
267 printf(pad);
268 __add(ccw_addr, 80);
270 for(i=0; i<=((data_cards+9)/10) + (((data_cards+9)/10)+9)/10 - 2; i++) {
271 printf(cp_ccw, i+3, ADDRS(ccw_addr));
272 __add(ccw_addr, 80);
275 while (i % 10) {
276 printf(nop_ccw, i);
277 i++;
280 for(i=1; i<=data_cards; i++) {
281 printf(data_ccw, i, ADDRS(addr),
282 (i == data_cards) ? 0 : CHAIN);
284 __add(addr, 80);
287 return 0;
289 printf(card_head, card++);
290 return 0;