|
|
1.1 root 1: /* NeXT DMA Emulation
2: * Contains informations from QEMU-NeXT
3: * NeXT DMA consists of 12 channel processors with 128 bytes internal buffer for each channel
4: * 12 channels: SCSI, Sound in, Sound out, Optical disk, Printer, SCC, DSP,
5: * Ethernet transmit, Ethernet receive, Video, Memory to register, Register to memory
6: */
7:
8: #include "ioMem.h"
9: #include "ioMemTables.h"
10: #include "m68000.h"
11: #include "esp.h"
12: #include "sysReg.h"
13: #include "dma.h"
14: #include "configuration.h"
15: #include "ethernet.h"
16:
17:
18: #define LOG_DMA_LEVEL LOG_WARN
19:
20: #define IO_SEG_MASK 0x1FFFF
21:
22: /* read CSR bits */
23: #define DMA_ENABLE 0x01000000 /* enable dma transfer */
24: #define DMA_SUPDATE 0x02000000 /* single update */
25: #define DMA_COMPLETE 0x08000000 /* current dma has completed */
26: #define DMA_BUSEXC 0x10000000 /* bus exception occurred */
27: /* write CSR bits */
28: #define DMA_SETENABLE 0x00010000 /* set enable */
29: #define DMA_SETSUPDATE 0x00020000 /* set single update */
30: #define DMA_M2DEV 0x00000000 /* dma from mem to dev */
31: #define DMA_DEV2M 0x00040000 /* dma from dev to mem */
32: #define DMA_CLRCOMPLETE 0x00080000 /* clear complete conditional */
33: #define DMA_RESET 0x00100000 /* clr cmplt, sup, enable */
34: #define DMA_INITBUF 0x00200000 /* initialize DMA buffers */
35:
36:
37: /* Read and write CSR bits for 68030 based NeXT Computer.
38: * We convert these to 68040 values before using in functions.
39: * read CSR bits *
40: #define DMA_ENABLE 0x01
41: #define DMA_SUPDATE 0x02
42: #define DMA_COMPLETE 0x08
43: #define DMA_BUSEXC 0x10
44: * write CSR bits *
45: #define DMA_SETENABLE 0x01
46: #define DMA_SETSUPDATE 0x02
47: #define DMA_M2DEV 0x00
48: #define DMA_DEV2M 0x04
49: #define DMA_CLRCOMPLETE 0x08
50: #define DMA_RESET 0x10
51: #define DMA_INITBUF 0x20
52: */
53:
54:
55:
56: /* DMA registers */
57:
58: typedef struct {
59: Uint32 csr;
60: Uint32 saved_next;
61: Uint32 saved_limit;
62: Uint32 saved_start;
63: Uint32 saved_stop;
64: Uint32 next;
65: Uint32 limit;
66: Uint32 start;
67: Uint32 stop;
68: Uint32 init;
69: Uint32 size;
70: } DMA_CONTROL;
71:
72: DMA_CONTROL dma[16];
73:
74:
75:
76: int get_channel(Uint32 address) {
77: int channel = address&IO_SEG_MASK;
78: switch (channel) {
79: case 0x010: printf("channel SCSI:\n"); return CHANNEL_SCSI; break;
80: case 0x040: printf("channel Sound Out:\n"); return CHANNEL_SOUNDOUT; break;
81: case 0x050: printf("channel MO Disk:\n"); return CHANNEL_DISK; break;
82: case 0x080: printf("channel Sound in:\n"); return CHANNEL_SOUNDIN; break;
83: case 0x090: printf("channel Printer:\n"); return CHANNEL_PRINTER; break;
84: case 0x0c0: printf("channel SCC:\n"); return CHANNEL_SCC; break;
85: case 0x0d0: printf("channel DSP:\n"); return CHANNEL_DSP; break;
86: case 0x110: printf("channel Ethernet Tx:\n"); return CHANNEL_EN_TX; break;
87: case 0x150: printf("channel Ethernet Rx:\n"); return CHANNEL_EN_RX; break;
88: case 0x180: printf("channel Video:\n"); return CHANNEL_VIDEO; break;
89: case 0x1d0: printf("channel M2R:\n"); return CHANNEL_M2R; break;
90: case 0x1c0: printf("channel R2M:\n"); return CHANNEL_R2M; break;
91:
92: default:
93: Log_Printf(LOG_DMA_LEVEL, "Unknown DMA channel!\n");
94: return -1;
95: break;
96: }
97: }
98:
99: int get_interrupt_type(int channel) {
100: switch (channel) {
101: case CHANNEL_SCSI: return INT_SCSI_DMA; break;
102: case CHANNEL_SOUNDOUT: return INT_SND_OUT_DMA; break;
103: case CHANNEL_DISK: return INT_DISK_DMA; break;
104: case CHANNEL_SOUNDIN: return INT_SND_IN_DMA; break;
105: case CHANNEL_PRINTER: return INT_PRINTER_DMA; break;
106: case CHANNEL_SCC: return INT_SCC_DMA; break;
107: case CHANNEL_DSP: return INT_DSP_DMA; break;
108: case CHANNEL_EN_TX: return INT_EN_TX_DMA; break;
109: case CHANNEL_EN_RX: return INT_EN_RX_DMA; break;
110: case CHANNEL_VIDEO: return 0; break; // no interrupt? CHECK THIS
111: case CHANNEL_M2R: return INT_M2R_DMA; break;
112: case CHANNEL_R2M: return INT_R2M_DMA; break;
113:
114: default:
115: Log_Printf(LOG_DMA_LEVEL, "Unknown DMA interrupt!\n");
116: return 0;
117: break;
118: }
119: }
120:
121: void DMA_CSR_Read(void) { // 0x02000010, length of register is byte on 68030 based NeXT Computer
122: int channel = get_channel(IoAccessCurrentAddress);
123: if(ConfigureParams.System.nMachineType == NEXT_CUBE030) { // for 68030 based NeXT Computer
124: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = dma[channel].csr >> 24;
125: Log_Printf(LOG_DMA_LEVEL,"DMA CSR read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].csr >> 24, m68k_getpc());
126: } else {
127: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].csr);
128: Log_Printf(LOG_DMA_LEVEL,"DMA CSR read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].csr, m68k_getpc());
129: }
130: }
131:
132: void DMA_CSR_Write(void) {
133: int channel = get_channel(IoAccessCurrentAddress);
134: int interrupt = get_interrupt_type(channel);
135: Uint32 writecsr;
136: if(ConfigureParams.System.nMachineType == NEXT_CUBE030) { // for 68030 based NeXT Computer
137: writecsr = IoMem[IoAccessCurrentAddress & IO_SEG_MASK] << 16;
138: Log_Printf(LOG_DMA_LEVEL,"DMA CSR write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, writecsr >> 16, m68k_getpc());
139: } else {
140: writecsr = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
141: Log_Printf(LOG_DMA_LEVEL,"DMA CSR write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, writecsr, m68k_getpc());
142: }
143:
144: if(writecsr & DMA_DEV2M) {
145: if(ConfigureParams.System.nMachineType == NEXT_CUBE030) {
146: dma[channel].csr |= (0x04 << 24); // use 8 bit DMA_DEV2M value for 68030 based NeXT Computer
147: } else {
148: dma[channel].csr |= DMA_DEV2M;
149: }
150: Log_Printf(LOG_DMA_LEVEL,"DMA from dev to mem");
151: } else {
152: Log_Printf(LOG_DMA_LEVEL,"DMA from mem to dev");
153: }
154: if(writecsr & DMA_SETENABLE) {
155: dma[channel].csr |= DMA_ENABLE;
156: Log_Printf(LOG_DMA_LEVEL,"DMA enable transfer");
157: if ((channel == CHANNEL_EN_TX) && !(writecsr&DMA_DEV2M)) {
158: Ethernet_Transmit(); // Ethernet Transmit
159: }
1.1.1.2 ! root 160: #if 1 /* hack for nextstep 0.8 */
! 161: if(ConfigureParams.System.nMachineType == NEXT_CUBE030) { // for 68030 based NeXT Computer
! 162: if ((channel == CHANNEL_R2M) || (channel == CHANNEL_M2R)) {
! 163: dma[channel].csr = DMA_COMPLETE;
! 164: set_interrupt(interrupt, SET_INT);
! 165: }
! 166: }
! 167: #endif
1.1 root 168: }
169: if(writecsr & DMA_SETSUPDATE) {
170: dma[channel].csr |= DMA_SUPDATE;
171: Log_Printf(LOG_DMA_LEVEL,"DMA set single update");
172: }
173: if(writecsr & DMA_CLRCOMPLETE) {
174: dma[channel].csr &= ~DMA_COMPLETE;
175: Log_Printf(LOG_DMA_LEVEL,"DMA clear complete conditional");
176:
177: set_interrupt(interrupt, RELEASE_INT); // also somewhat experimental...
178: }
179: if(writecsr & DMA_RESET) {
180: dma[channel].csr &= ~(DMA_COMPLETE | DMA_SUPDATE | DMA_ENABLE | DMA_DEV2M);
181: Log_Printf(LOG_WARN,"DMA reset");
182:
183: set_interrupt(interrupt, RELEASE_INT); // also somewhat experimental...
184: }
185: if(writecsr & DMA_INITBUF) { // needs to be filled
186: Log_Printf(LOG_DMA_LEVEL,"DMA initialize buffers");
187: }
188: }
189:
190: void DMA_Saved_Next_Read(void) { // 0x02004000
191: int channel = get_channel(IoAccessCurrentAddress-0x3FF0);
192: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_next);
193: Log_Printf(LOG_DMA_LEVEL,"DMA SNext read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_next, m68k_getpc());
194: }
195:
196: void DMA_Saved_Next_Write(void) {
197: int channel = get_channel(IoAccessCurrentAddress-0x3FF0);
198: dma[channel].saved_next = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
199: Log_Printf(LOG_DMA_LEVEL,"DMA SNext write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_next, m68k_getpc());
200: }
201:
202: void DMA_Saved_Limit_Read(void) { // 0x02004004
203: int channel = get_channel(IoAccessCurrentAddress-0x3FF4);
204: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_limit);
205: Log_Printf(LOG_DMA_LEVEL,"DMA SLimit read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_limit, m68k_getpc());
206: }
207:
208: void DMA_Saved_Limit_Write(void) {
209: int channel = get_channel(IoAccessCurrentAddress-0x3FF4);
210: dma[channel].saved_limit = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
211: Log_Printf(LOG_DMA_LEVEL,"DMA SLimit write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_limit, m68k_getpc());
212: }
213:
214: void DMA_Saved_Start_Read(void) { // 0x02004008
215: int channel = get_channel(IoAccessCurrentAddress-0x3FF8);
216: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_start);
217: Log_Printf(LOG_DMA_LEVEL,"DMA SStart read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_start, m68k_getpc());
218: }
219:
220: void DMA_Saved_Start_Write(void) {
221: int channel = get_channel(IoAccessCurrentAddress-0x3FF8);
222: dma[channel].saved_start = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
223: Log_Printf(LOG_DMA_LEVEL,"DMA SStart write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_start, m68k_getpc());
224: }
225:
226: void DMA_Saved_Stop_Read(void) { // 0x0200400c
227: int channel = get_channel(IoAccessCurrentAddress-0x3FFC);
228: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].saved_stop);
229: Log_Printf(LOG_DMA_LEVEL,"DMA SStop read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_stop, m68k_getpc());
230: }
231:
232: void DMA_Saved_Stop_Write(void) {
233: int channel = get_channel(IoAccessCurrentAddress-0x3FFC);
234: dma[channel].saved_stop = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
235: Log_Printf(LOG_DMA_LEVEL,"DMA SStop write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].saved_stop, m68k_getpc());
236: }
237:
238: void DMA_Next_Read(void) { // 0x02004010
239: int channel = get_channel(IoAccessCurrentAddress-0x4000);
240: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].next);
241: Log_Printf(LOG_DMA_LEVEL,"DMA Next read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].next, m68k_getpc());
1.1.1.2 ! root 242: /* Experimental! Release interrupt here */
! 243: int interrupt = get_interrupt_type(channel);
! 244: set_interrupt(interrupt, RELEASE_INT); // also somewhat experimental...
1.1 root 245: }
246:
247: void DMA_Next_Write(void) {
248: int channel = get_channel(IoAccessCurrentAddress-0x4000);
249: dma[channel].next = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
250: Log_Printf(LOG_DMA_LEVEL,"DMA Next write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].next, m68k_getpc());
251: }
252:
253: void DMA_Limit_Read(void) { // 0x02004014
254: int channel = get_channel(IoAccessCurrentAddress-0x4004);
255: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].limit);
256: Log_Printf(LOG_DMA_LEVEL,"DMA Limit read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].limit, m68k_getpc());
257: }
258:
259: void DMA_Limit_Write(void) {
260: int channel = get_channel(IoAccessCurrentAddress-0x4004);
261: dma[channel].limit = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
262: Log_Printf(LOG_DMA_LEVEL,"DMA Limit write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].limit, m68k_getpc());
263: }
264:
265: void DMA_Start_Read(void) { // 0x02004018
266: int channel = get_channel(IoAccessCurrentAddress-0x4008);
267: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].start);
268: Log_Printf(LOG_DMA_LEVEL,"DMA Start read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].start, m68k_getpc());
269: }
270:
271: void DMA_Start_Write(void) {
272: int channel = get_channel(IoAccessCurrentAddress-0x4008);
273: dma[channel].start = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
274: Log_Printf(LOG_DMA_LEVEL,"DMA Start write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].start, m68k_getpc());
275: }
276:
277: void DMA_Stop_Read(void) { // 0x0200401c
278: int channel = get_channel(IoAccessCurrentAddress-0x400C);
279: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].stop);
280: Log_Printf(LOG_DMA_LEVEL,"DMA Stop read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].stop, m68k_getpc());
281: }
282:
283: void DMA_Stop_Write(void) {
284: int channel = get_channel(IoAccessCurrentAddress-0x400C);
285: dma[channel].stop = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
286: Log_Printf(LOG_DMA_LEVEL,"DMA Stop write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].stop, m68k_getpc());
287: }
288:
289: void DMA_Init_Read(void) { // 0x02004210
290: int channel = get_channel(IoAccessCurrentAddress-0x4200);
291: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].init);
292: Log_Printf(LOG_DMA_LEVEL,"DMA Init read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].init, m68k_getpc());
293: }
294:
295: void DMA_Init_Write(void) {
296: int channel = get_channel(IoAccessCurrentAddress-0x4200);
297: dma[channel].init = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
298: Log_Printf(LOG_DMA_LEVEL,"DMA Init write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].init, m68k_getpc());
299: }
300:
301: void DMA_Size_Read(void) { // 0x02004214
302: int channel = get_channel(IoAccessCurrentAddress-0x4204);
303: IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, dma[channel].size);
304: Log_Printf(LOG_DMA_LEVEL,"DMA Size read at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].size, m68k_getpc());
305: }
306:
307: void DMA_Size_Write(void) {
308: int channel = get_channel(IoAccessCurrentAddress-0x4204);
309: dma[channel].size = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
310: Log_Printf(LOG_DMA_LEVEL,"DMA Size write at $%08x val=$%08x PC=$%08x\n", IoAccessCurrentAddress, dma[channel].size, m68k_getpc());
311: }
312:
313:
314:
315: /* DMA Functions */
316:
317: /*void copy_to_scsidma_buffer(Uint8 device_outbuf[], int outbuf_size) {
318: memcpy(dma_buffer, device_outbuf, outbuf_size);
319: }*/
320:
321: /*void dma_clear_memory(Uint32 datalength) {
322: Uint32 start_addr;
323: Uint32 end_addr;
324:
325: if(dma_init == 0)
326: start_addr = dma_next;
327: else
328: start_addr = dma_init;
329:
330: end_addr = start_addr + datalength;
331:
332: NEXTMemory_Clear(start_addr, end_addr);
333: }*/
334:
335: void dma_memory_read(Uint8 *buf, Uint32 *size, int channel) {
336: Uint32 base_addr;
337: Uint8 align = 16;
338: Uint32 size_count = 0;
339: Uint32 read_addr;
340: int interrupt = get_interrupt_type(channel);
341:
342: if ((channel == CHANNEL_EN_TX) && !ConfigureParams.System.bTurbo)
343: *size = (dma[channel].limit&0x0FFFFFFF) - (dma[channel].init&0x0FFFFFFF);
344: else
345: *size = (dma[channel].limit&0x0FFFFFFF) - (dma[channel].next&0x0FFFFFFF);
346:
347: if(channel == CHANNEL_EN_RX || channel == CHANNEL_EN_TX)
348: align = 32;
349:
350: // if((*size % align) != 0) {
351: // *size -= *size % align;
352: // *size += align;
353: // }
354:
355: if(dma[channel].init == 0)
356: base_addr = dma[channel].next;
357: else
358: base_addr = dma[channel].init;
359:
360: Log_Printf(LOG_WARN, "[DMA] Read from mem: at $%08x, %i bytes",base_addr, *size);
361: for (size_count = 0; size_count < *size; size_count++) {
362: read_addr = base_addr + size_count;
363: buf[size_count] = NEXTMemory_ReadByte(read_addr);
364: }
365: printf("READ FROM MEMORY: %02x\n", buf[0]);
366:
367: dma[channel].csr |= DMA_COMPLETE | DMA_SUPDATE;
368:
369: set_interrupt(interrupt, SET_INT);
370: }
371:
372:
373: void dma_memory_write(Uint8 *buf, Uint32 size, int channel) {
374: Uint32 base_addr, tail_addr;
375: Uint8 align = 16;
376: Uint32 size_count = 0;
377: Uint32 write_addr;
378: Uint32 dma_tail = 0;
379: int interrupt = get_interrupt_type(channel);
380:
381: if(channel == CHANNEL_EN_RX || channel == CHANNEL_EN_TX)
382: align = 32;
383:
384: // if((size % align) != 0) {
385: // size -= size % align;
386: // size += align;
387: // }
388:
389:
390: if(dma[channel].init == 0) {
391: base_addr = dma[channel].next;
392: dma_tail = 0;
393: } else {
394: base_addr = dma[channel].init;
395:
396: /* If the transfer size is greater than (limit - init):
397: * Copy residual bytes to physical addresses at start. */
398: if (size > (dma[channel].limit - dma[channel].init)) {
399: tail_addr = dma[channel].start;
400: dma_tail = size - (dma[channel].limit - dma[channel].init);
401: size = (dma[channel].limit - dma[channel].init);
402: Log_Printf(LOG_WARN, "[DMA] Residual bytes: %i", dma_tail);
403: }
404: }
405:
406: Log_Printf(LOG_WARN, "[DMA] Write to mem: at $%08x, %i bytes",base_addr,size);
407: for (size_count = 0; size_count < size; size_count++) {
408: write_addr = base_addr + size_count;
409: NEXTMemory_WriteByte(write_addr, buf[size_count]);
410: }
411:
412: /* If there are residual bytes, copy them to physical addresses starting
413: * at "start". */
414:
415: if (dma_tail) {
416: Log_Printf(LOG_WARN, "[DMA] Write residual bytes at $%08x, %i bytes",tail_addr,dma_tail);
417: for (size_count = 0; size_count < dma_tail; size_count++) {
418: write_addr = tail_addr + size_count;
419: NEXTMemory_WriteByte(write_addr, buf[size+size_count]);
420: }
421: }
422:
423:
424: /* Test read/write */
425: Log_Printf(LOG_DMA_LEVEL, "DMA Write Test: $%02x,$%02x,$%02x,$%02x\n", NEXTMemory_ReadByte(base_addr),NEXTMemory_ReadByte(base_addr+16),NEXTMemory_ReadByte(base_addr+32),NEXTMemory_ReadByte(base_addr+384));
426: // NEXTMemory_WriteByte(base_addr, 0x77);
427: // Uint8 testvar = NEXTMemory_ReadByte(base_addr);
428: // Log_Printf(LOG_DMA_LEVEL, "Write Test: $%02x at $%08x", testvar, base_addr);
429:
430: dma[channel].init = 0;
431:
432: /* saved limit is checked to calculate packet size
433: by both the rom and netbsd */
434: dma[channel].saved_limit = dma[channel].next + size;
435: dma[channel].saved_next = dma[channel].next;
436:
437: if(!(dma[channel].csr & DMA_SUPDATE)||(channel==CHANNEL_EN_RX)) { // Ethernet: this needs to be checked!
438: dma[channel].next = dma[channel].start;
439: dma[channel].limit = dma[channel].stop;
440: }
441:
442: dma[channel].csr |= DMA_COMPLETE;
443:
444: set_interrupt(interrupt, SET_INT);
445: // set_interrupt(INT_SCSI_DMA, RELEASE_INT);
446: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.