20 //#define BCM2708_PERI_BASE 0x20000000 //pi0-1
21 //#define BCM2708_PERI_BASE 0xFE000000 //pi4
22 #define BCM2708_PERI_BASE 0x3F000000 //pi3
23 #define BCM2708_PERI_SIZE 0x01000000
24 #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
25 #define GPCLK_BASE (BCM2708_PERI_BASE + 0x101000)
26 #define GPIO_ADDR 0x200000 /* GPIO controller */
27 #define GPCLK_ADDR 0x101000
28 #define CLK_PASSWD 0x5a000000
29 #define CLK_GP0_CTL 0x070
30 #define CLK_GP0_DIV 0x074
36 #define STATUSREGADDR GPIO_CLR = 1<<SA0;GPIO_CLR = 1<<SA1;GPIO_SET = 1<<SA2;
37 #define W16 GPIO_CLR = 1<<SA0;GPIO_CLR = 1<<SA1;GPIO_CLR = 1<<SA2;
38 #define R16 GPIO_SET = 1<<SA0;GPIO_CLR = 1<<SA1;GPIO_CLR = 1<<SA2;
39 #define W8 GPIO_CLR = 1<<SA0;GPIO_SET = 1<<SA1;GPIO_CLR = 1<<SA2;
40 #define R8 GPIO_SET = 1<<SA0;GPIO_SET = 1<<SA1;GPIO_CLR = 1<<SA2;
42 #define PAGE_SIZE (4*1024)
43 #define BLOCK_SIZE (4*1024)
45 #define GPIOSET(no, ishigh) \
50 reset |= (1 << (no)); \
54 #define FASTBASE 0x07FFFFFF
55 //#define FASTSIZE 0xFFFFFF
56 #define FASTSIZE 0xFFFFFFF
57 #define GAYLEBASE 0xD80000 //D7FFFF
58 #define GAYLESIZE 0x6FFFF
60 #define KICKBASE 0xF80000
61 #define KICKSIZE 0x7FFFF
69 volatile unsigned int *gpio;
70 volatile unsigned int *gpclk;
71 volatile unsigned int gpfsel0;
72 volatile unsigned int gpfsel1;
73 volatile unsigned int gpfsel2;
74 volatile unsigned int gpfsel0_o;
75 volatile unsigned int gpfsel1_o;
76 volatile unsigned int gpfsel2_o;
78 // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
79 #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
80 #define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
81 #define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
83 #define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
84 #define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
86 #define GET_GPIO(g) (*(gpio+13)&(1<<g)) // 0 if LOW, (1<<g) if HIGH
88 #define GPIO_PULL *(gpio+37) // Pull up/pull down
89 #define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock
94 uint32_t read8(uint32_t address);
95 void write8(uint32_t address, uint32_t data);
97 uint32_t read16(uint32_t address);
98 void write16(uint32_t address, uint32_t data);
100 void write32(uint32_t address, uint32_t data);
101 uint32_t read32(uint32_t address);
103 uint16_t read_reg(void);
104 void write_reg(unsigned int value);
106 volatile uint16_t srdata;
107 volatile uint32_t srdata2;
108 volatile uint32_t srdata2_old;
111 unsigned char g_kick[524288];
112 unsigned char g_ram[FASTSIZE+1]; /* RAM */
113 unsigned char toggle;
114 static volatile unsigned char ovl;
115 static volatile unsigned char maprom;
118 /* Signal Handler for SIGINT */
119 void sigint_handler(int sig_num)
121 /* Reset handler to catch SIGINT next time.
122 Refer http://en.cppreference.com/w/c/program/signal */
123 printf("\n User provided signal handler for Ctrl+C \n");
125 /* Do a graceful cleanup of the program like: free memory/resources/etc and exit */
130 void* iplThread(void *args){
133 //srdata2_old = read_reg();
137 //printf("thread!/n");
138 if (GET_GPIO(1) == 0){
140 if (srdata != srdata2_old){
141 srdata2 = ((srdata >> 13)&0xff);
142 //printf("STATUS: %d\n", srdata2);
143 srdata2_old = srdata;
144 m68k_set_irq(srdata2);
151 srdata2 = ((srdata >> 13)&0xff);
152 srdata2_old = srdata;
153 m68k_set_irq(srdata2);
156 //printf("STATUS: 0\n");
172 const struct sched_param priority = {99};
174 sched_setscheduler(0, SCHED_RR , &priority);
175 printf("YES locked in memory\n");
176 mlockall(MCL_CURRENT); // lock in memory to keep us from paging out
183 ide0 = ide_allocate("cf");
184 fd = open("hd0.img", O_RDWR);
186 printf("HDD Image hd0.image failed open\n");
188 ide_attach(ide0, 0, fd);
189 ide_reset_begin(ide0);
190 printf("HDD Image hd0.image attached\n");
193 signal(SIGINT, sigint_handler);
196 //Enable 200MHz CLK output on GPIO4, adjust divider and pll source depending on pi model
197 printf("Enable GPCLK0 on GPIO4\n");
199 *(gpclk+ (CLK_GP0_CTL/4)) = CLK_PASSWD | (1 << 5);
201 while ( (*(gpclk+(CLK_GP0_CTL/4))) & (1 << 7));
203 *(gpclk+(CLK_GP0_DIV/4)) = CLK_PASSWD | (6 << 12); //divider , 6=200MHz on pi3
205 *(gpclk+(CLK_GP0_CTL/4)) = CLK_PASSWD | 5 | (1 << 4); //pll? 6=plld, 5=pllc
207 while (((*(gpclk+(CLK_GP0_CTL/4))) & (1 << 7))== 0);
210 SET_GPIO_ALT(4,0); //gpclk0
220 //set gpio0 (aux0) and gpio1 (aux1) to input
224 // Set GPIO pins 6,7 and 8-23 to output
225 for (g=6; g<=23; g++)
230 printf ("Precalculate GPIO8-23 aus Output\n");
231 gpfsel0_o =*(gpio); //store gpio ddr
232 printf ("gpfsel0: %#x\n", gpfsel0_o);
233 gpfsel1_o =*(gpio+1); //store gpio ddr
234 printf ("gpfsel1: %#x\n", gpfsel1_o);
235 gpfsel2_o =*(gpio+2); //store gpio ddr
236 printf ("gpfsel2: %#x\n", gpfsel2_o);
238 // Set GPIO pins 8-23 to input
239 for (g=8; g<=23; g++)
243 printf ("Precalculate GPIO8-23 as Input\n");
244 gpfsel0 =*(gpio); //store gpio ddr
245 printf ("gpfsel0: %#x\n", gpfsel0);
246 gpfsel1 =*(gpio+1); //store gpio ddr
247 printf ("gpfsel1: %#x\n", gpfsel1);
248 gpfsel2 =*(gpio+2); //store gpio ddr
249 printf ("gpfsel2: %#x\n", gpfsel2);
258 //reset cpld statemachine first
268 fp = fopen("kick.rom", "rb");
271 printf("kick.rom cannot be opened\n");
273 printf("kick.rom found, using that instead of motherboard rom\n");
276 unsigned int reads = fread(&g_kick, sizeof(g_kick), 1, fp);
278 printf("failed loading kick.rom\n");
280 printf("loaded kick.rom\n");
288 m68k_write_memory_8(0xbfe201,0x0001); //AMIGA OVL
289 m68k_write_memory_8(0xbfe001,0x0001); //AMIGA OVL high (ROM@0x0)
295 m68k_set_cpu_type(M68K_CPU_TYPE_68030);
297 srdata2_old = read_reg();
298 printf("STATUS: %d\n", srdata2_old);
305 //err = pthread_create(&id, NULL, &iplThread, NULL);
307 printf("\ncan't create IPL thread :[%s]", strerror(err));
309 printf("\n IPL Thread created successfully\n");
317 //printf("IRQ:0x%06x\n",CheckIrq());
325 if (GET_GPIO(1) == 0 || CheckIrq() == 1){
327 // if (CheckIrq() == 1) srdata |= (1 << 14);
328 if (srdata != srdata2_old){
329 srdata2 = ((srdata >> 13)&0xff);
330 //printf("STATUS: %d\n", srdata2);
331 srdata2_old = srdata;
332 m68k_set_irq(srdata2);
339 srdata2 = ((srdata >> 13)&0xff);
340 srdata2_old = srdata;
341 m68k_set_irq(srdata2);
342 //printf("STATUS: 0\n");
354 void cpu_pulse_reset(void){
364 int cpu_irq_ack(int level)
366 printf("cpu irq ack\n");
372 unsigned int m68k_read_memory_8(unsigned int address){
374 if(address>GAYLEBASE && address<GAYLEBASE + GAYLESIZE){
375 return readGayleB(address);
378 if(address>FASTBASE){
379 return g_ram[address- FASTBASE];
383 if (ovl == 1 && address<KICKSIZE){
384 return g_kick[address];}
385 if (ovl == 0 && (address>KICKBASE && address<KICKBASE + KICKSIZE)){
386 return g_kick[address-KICKBASE];}
389 if (address < 0xffffff){
390 return read8((uint32_t)address);
396 unsigned int m68k_read_memory_16(unsigned int address){
398 if(address>GAYLEBASE && address<GAYLEBASE + GAYLESIZE){
399 return readGayle(address);
402 if(address>FASTBASE){
403 uint16_t value = *(uint16_t*)&g_ram[address- FASTBASE];
404 value = (value << 8) | (value >> 8);
409 if (ovl == 1 && address<KICKSIZE ){
410 uint16_t value = *(uint16_t*)&g_kick[address];
411 return (value << 8) | (value >> 8);}
412 if (ovl == 0 && (address>KICKBASE && address<KICKBASE + KICKSIZE)){
413 //printf("kread16 addr: %x\n",address);
414 uint16_t value = *(uint16_t*)&g_kick[address-KICKBASE];
415 return (value << 8) | (value >> 8);}
418 if (address < 0xffffff){
419 return (unsigned int)read16((uint32_t)address);
425 unsigned int m68k_read_memory_32(unsigned int address){
427 if(address>GAYLEBASE && address<GAYLEBASE + GAYLESIZE){
428 return readGayleL(address);
431 if(address>FASTBASE){
432 uint32_t value = *(uint32_t*)&g_ram[address- FASTBASE];
433 value = ((value << 8) & 0xFF00FF00 ) | ((value >> 8) & 0xFF00FF );
434 return value << 16 | value >> 16;
438 if (ovl == 1 && address<KICKSIZE){
439 uint32_t value = *(uint32_t*)&g_kick[address];
440 value = ((value << 8) & 0xFF00FF00 ) | ((value >> 8) & 0xFF00FF );
441 return value << 16 | value >> 16;}
443 if (ovl == 0 && (address>KICKBASE && address<KICKBASE + KICKSIZE)){
444 //printf("kread32/n");
445 uint32_t value = *(uint32_t*)&g_kick[address-KICKBASE];
446 value = ((value << 8) & 0xFF00FF00 ) | ((value >> 8) & 0xFF00FF );
447 return value << 16 | value >> 16;}
450 if (address < 0xffffff){
451 uint16_t a = read16(address);
452 uint16_t b = read16(address+2);
453 return (a << 16) | b;
459 void m68k_write_memory_8(unsigned int address, unsigned int value){
462 if (address == 0xbfe001){
463 ovl = (value & (1<<0));
464 printf("OVL:%x\n", ovl );
468 if(address>GAYLEBASE && address<GAYLEBASE + GAYLESIZE){
469 writeGayleB(address, value);
474 if(address>FASTBASE){
475 g_ram[address- FASTBASE] = value;
479 if (address < 0xffffff){
480 write8((uint32_t)address,value);
487 void m68k_write_memory_16(unsigned int address, unsigned int value){
488 // if (address==0xdff030) printf("%c", value);
490 if(address>GAYLEBASE && address<GAYLEBASE + GAYLESIZE){
491 writeGayle(address,value);
495 if (address == 0xbfe001)
496 printf("16CIA Output:%x\n", value );
499 if(address>FASTBASE){
500 uint16_t* dest = (uint16_t*)&g_ram[address- FASTBASE];
501 value = (value << 8) | (value >> 8);
506 if (address < 0xffffff){
507 write16((uint32_t)address,value);
513 void m68k_write_memory_32(unsigned int address, unsigned int value){
516 if(address>GAYLEBASE && address<GAYLEBASE + GAYLESIZE){
517 writeGayleL(address, value);
520 if(address>FASTBASE){
521 uint32_t* dest = (uint32_t*)&g_ram[address- FASTBASE];
522 value = ((value << 8) & 0xFF00FF00 ) | ((value >> 8) & 0xFF00FF );
523 value = value << 16 | value >> 16;
528 if (address < 0xffffff){
529 write16(address , value >> 16);
530 write16(address+2 , value );
538 void write32(uint32_t address, uint32_t data){
539 write16(address+2 , data);
540 write16(address , data >>16 );
543 uint32_t read32(uint32_t address){
544 uint16_t a = read16(address+2);
545 uint16_t b = read16(address);
550 void write16(uint32_t address, uint32_t data)
552 uint32_t addr_h_s = (address & 0x0000ffff) << 8;
553 uint32_t addr_h_r = (~address & 0x0000ffff) << 8;
554 uint32_t addr_l_s = (address >> 16) << 8;
555 uint32_t addr_l_r = (~address >> 16) << 8;
556 uint32_t data_s = (data & 0x0000ffff) << 8;
557 uint32_t data_r = (~data & 0x0000ffff) << 8;
559 // asm volatile ("dmb" ::: "memory");
562 *(gpio + 1) = gpfsel1_o;
563 *(gpio + 2) = gpfsel2_o;
565 *(gpio + 7) = addr_h_s;
566 *(gpio + 10) = addr_h_r;
570 *(gpio + 7) = addr_l_s;
571 *(gpio + 10) = addr_l_r;
576 *(gpio + 7) = data_s;
577 *(gpio + 10) = data_r;
582 *(gpio + 1) = gpfsel1;
583 *(gpio + 2) = gpfsel2;
584 while ((GET_GPIO(0)));
585 // asm volatile ("dmb" ::: "memory");
589 void write8(uint32_t address, uint32_t data)
592 if ((address & 1) == 0)
593 data = data + (data << 8); //EVEN, A0=0,UDS
594 else data = data & 0xff ; //ODD , A0=1,LDS
595 uint32_t addr_h_s = (address & 0x0000ffff) << 8;
596 uint32_t addr_h_r = (~address & 0x0000ffff) << 8;
597 uint32_t addr_l_s = (address >> 16) << 8;
598 uint32_t addr_l_r = (~address >> 16) << 8;
599 uint32_t data_s = (data & 0x0000ffff) << 8;
600 uint32_t data_r = (~data & 0x0000ffff) << 8;
603 // asm volatile ("dmb" ::: "memory");
606 *(gpio + 1) = gpfsel1_o;
607 *(gpio + 2) = gpfsel2_o;
609 *(gpio + 7) = addr_h_s;
610 *(gpio + 10) = addr_h_r;
614 *(gpio + 7) = addr_l_s;
615 *(gpio + 10) = addr_l_r;
620 *(gpio + 7) = data_s;
621 *(gpio + 10) = data_r;
626 *(gpio + 1) = gpfsel1;
627 *(gpio + 2) = gpfsel2;
628 while ((GET_GPIO(0)));
629 // asm volatile ("dmb" ::: "memory");
634 uint32_t read16(uint32_t address)
637 uint32_t addr_h_s = (address & 0x0000ffff) << 8;
638 uint32_t addr_h_r = (~address & 0x0000ffff) << 8;
639 uint32_t addr_l_s = (address >> 16) << 8;
640 uint32_t addr_l_r = (~address >> 16) << 8;
642 // asm volatile ("dmb" ::: "memory");
646 *(gpio + 1) = gpfsel1_o;
647 *(gpio + 2) = gpfsel2_o;
649 *(gpio + 7) = addr_h_s;
650 *(gpio + 10) = addr_h_r;
654 *(gpio + 7) = addr_l_s;
655 *(gpio + 10) = addr_l_r;
663 *(gpio + 1) = gpfsel1;
664 *(gpio + 2) = gpfsel2;
667 while (!(GET_GPIO(0)));
669 asm volatile ("nop" ::);
670 asm volatile ("nop" ::);
671 asm volatile ("nop" ::);
674 // asm volatile ("dmb" ::: "memory");
675 return (val >>8)&0xffff;
679 uint32_t read8(uint32_t address)
682 uint32_t addr_h_s = (address & 0x0000ffff) << 8;
683 uint32_t addr_h_r = (~address & 0x0000ffff) << 8;
684 uint32_t addr_l_s = (address >> 16) << 8;
685 uint32_t addr_l_r = (~address >> 16) << 8;
687 // asm volatile ("dmb" ::: "memory");
690 *(gpio + 1) = gpfsel1_o;
691 *(gpio + 2) = gpfsel2_o;
693 *(gpio + 7) = addr_h_s;
694 *(gpio + 10) = addr_h_r;
698 *(gpio + 7) = addr_l_s;
699 *(gpio + 10) = addr_l_r;
706 *(gpio + 1) = gpfsel1;
707 *(gpio + 2) = gpfsel2;
710 while (!(GET_GPIO(0)));
712 asm volatile ("nop" ::);
713 asm volatile ("nop" ::);
714 asm volatile ("nop" ::);
717 // asm volatile ("dmb" ::: "memory");
719 val = (val >>8)&0xffff;
720 if ((address & 1) == 0)
721 val = (val >> 8) & 0xff ; //EVEN, A0=0,UDS
723 val = val & 0xff ; //ODD , A0=1,LDS
729 /******************************************************/
731 void write_reg(unsigned int value)
733 asm volatile ("dmb" ::: "memory");
735 asm volatile ("nop" ::);
736 asm volatile ("nop" ::);
737 asm volatile ("nop" ::);
738 //Write Status register
744 *(gpio + 1) = gpfsel1_o;
745 *(gpio + 2) = gpfsel2_o;
746 *(gpio + 7) = (value & 0xffff) << 8;
747 *(gpio + 10) = (~value & 0xffff) << 8;
749 GPIO_CLR = 1 << 7; //delay
754 *(gpio + 1) = gpfsel1;
755 *(gpio + 2) = gpfsel2;
756 asm volatile ("dmb" ::: "memory");
760 uint16_t read_reg(void)
764 asm volatile ("dmb" ::: "memory");
766 asm volatile ("nop" ::);
767 asm volatile ("nop" ::);
768 asm volatile ("nop" ::);
771 *(gpio + 1) = gpfsel1;
772 *(gpio + 2) = gpfsel2;
775 GPIO_CLR = 1 << 6; //delay
780 asm volatile ("dmb" ::: "memory");
782 return (uint16_t)(val >> 8);
787 // Set up a memory regions to access GPIO
792 if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
793 printf("can't open /dev/mem \n");
799 NULL, //Any adddress in our space will do
800 BCM2708_PERI_SIZE, //Map length
801 PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
802 MAP_SHARED, //Shared with other processes
803 mem_fd, //File to map
804 BCM2708_PERI_BASE //Offset to GPIO peripheral
807 close(mem_fd); //No need to keep mem_fd open after mmap
809 if (gpio_map == MAP_FAILED) {
810 printf("gpio mmap error %d\n", (int)gpio_map);//errno also set!
814 gpio = ((volatile unsigned *)gpio_map) + GPIO_ADDR/4;
815 gpclk = ((volatile unsigned *)gpio_map) + GPCLK_ADDR/4;