amiga.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include <stdio.h>
  2. #include <exec/types.h>
  3. #include <exec/io.h>
  4. #include <exec/ports.h>
  5. #include <exec/memory.h>
  6. #include <intuition/intuition.h>
  7. #include <intuition/intuitionbase.h>
  8. #include <intuition/screens.h>
  9. #include <proto/exec.h>
  10. #include <proto/dos.h>
  11. #include <proto/intuition.h>
  12. #include <devices/inputevent.h>
  13. #include <devices/keyboard.h>
  14. #include "minilisp.h"
  15. #include "alloc.h"
  16. #define WIDTH 512
  17. #define HEIGHT 250
  18. #define BPP 1
  19. #define DEPTH 8
  20. // http://cahirwpz.users.sourceforge.net/libnix/swapstack.html#swapstack
  21. unsigned long __stack=128000; // stack requirements (bytes) for swapstack.o from libnix
  22. struct Library *intuition_base;
  23. struct Library *gfx_base;
  24. struct Window *window;
  25. struct Cell* buffer_cell;
  26. Cell* amiga_fbfs_open() {
  27. return alloc_int(1);
  28. }
  29. Cell* amiga_fbfs_read() {
  30. return alloc_int(0);
  31. }
  32. Cell* amiga_fbfs_write(Cell* arg) {
  33. // TODO: render buffer to window rastport using chunky->planar conversion
  34. uint8_t* src = (uint8_t*)buffer_cell->ar.addr;
  35. uint8_t* dest1 = (uint8_t*)window->RPort->BitMap->Planes[0];
  36. uint8_t* dest2 = (uint8_t*)window->RPort->BitMap->Planes[1];
  37. int i, j, x, y;
  38. uint32_t screenw = window->WScreen->Width;
  39. uint32_t pitch;
  40. uint32_t offset;
  41. int bitplanes;
  42. int bpr;
  43. bitplanes=window->RPort->BitMap->Depth;
  44. bpr=window->RPort->BitMap->BytesPerRow;
  45. offset=window->LeftEdge/8 + ((window->TopEdge)*bpr);
  46. pitch=bpr - window->Width/8;
  47. /*printf("topedge: %d barheight: %d\r\n",window->TopEdge,window->WScreen->BarLayer->Height);
  48. printf("screenw: %d winw: %d\r\n",screenw,window->Width);
  49. printf("pitch: %d\r\n",pitch);
  50. printf("offset: %d\r\n",offset);
  51. printf("src: %p\r\n",src);
  52. printf("bitplane: %p\r\n",dest1);*/
  53. dest1+=offset;
  54. //dest2+=offset;
  55. j=0;
  56. // 8 bytes become 1
  57. for (y=0; y<HEIGHT; y++) {
  58. for (i=0; i<WIDTH; i+=8) {
  59. uint8_t d = 0;
  60. d|=((*src++)&1)<<7;
  61. d|=((*src++)&1)<<6;
  62. d|=((*src++)&1)<<5;
  63. d|=((*src++)&1)<<4;
  64. d|=((*src++)&1)<<3;
  65. d|=((*src++)&1)<<2;
  66. d|=((*src++)&1)<<1;
  67. d|=((*src++)&1);
  68. *dest1++ = d;
  69. //*dest2++ = d;
  70. }
  71. dest1+=pitch;
  72. dest2+=pitch;
  73. //printf("line: %d\r\n",y);
  74. }
  75. return NULL;
  76. }
  77. Cell* amiga_fbfs_mmap(Cell* arg) {
  78. long sz = WIDTH*HEIGHT*BPP;
  79. int x,y;
  80. uint8_t* dest;
  81. buffer_cell = alloc_num_bytes(sz);
  82. printf("[amiga_fbfs_mmap] buffer_cell->addr: %p\n",buffer_cell->ar.addr);
  83. window = OpenWindowTags(NULL, WA_Title, (ULONG) "interim/amiga",
  84. WA_Left, 0,
  85. WA_Top, 0,
  86. WA_Width, WIDTH,
  87. WA_Height, HEIGHT,
  88. WA_Flags, WFLG_NOCAREREFRESH,
  89. WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_GADGETUP,
  90. TAG_DONE);
  91. return buffer_cell;
  92. }
  93. Cell* amiga_keyfs_open() {
  94. return alloc_int(1);
  95. }
  96. char key_to_rune[] = {
  97. 0,
  98. 0,
  99. '1','2','3','4','5','6','7','8','9','0','/','"',9,9,
  100. '\t','q','w','e','r','t','z','u','i','o','p','-','+',9,0,0,
  101. 0,'a','s','d','f','g','h','j','k','l','(',')',0,0,'*',0,0,'<',
  102. 'y','x','c','v','b','n','m',',','.','-',0,0,0,0,
  103. 0,' ',9,0,0,10,0,0,0,0,
  104. 0,0,0,0,0,0,0,0,0,0,
  105. 0,0,0,0,0,0,0,0,0,0,
  106. 0,0,0,0,0,0,0,0,0,0,
  107. 0,0,0,0,0,0,0,0,0,0,
  108. 0,0,0,0,0,0,0,0,0,0,
  109. 0,0,0,0,0,0,0,0,0,0,
  110. 0,0,0,0,0,0,0,0,0,0,
  111. 0,0,0,0,0,0,0,0,0,0,
  112. 0,0,0,0,0,0,0,0,0,0
  113. };
  114. Cell* amiga_keyfs_read() {
  115. Cell* key = alloc_string_copy(" ");
  116. uint8_t* magic = (void*)0xbfec01;
  117. uint8_t k = *magic;
  118. ((char*)key->ar.addr)[0] = 0;
  119. if (!(k&1)) {
  120. // keyup
  121. return key;
  122. }
  123. k>>=1;
  124. k=128-k;
  125. printf("keyin: %d\r\n",k);
  126. ((char*)key->ar.addr)[0] = key_to_rune[k];
  127. return key;
  128. }
  129. void mount_amiga_keyfs() {
  130. fs_mount_builtin("/keyboard", amiga_keyfs_open, amiga_keyfs_read, 0, 0, 0);
  131. }
  132. void mount_posixfs();
  133. void mount_amiga_fbfs() {
  134. fs_mount_builtin("/framebuffer", amiga_fbfs_open, amiga_fbfs_read, amiga_fbfs_write, 0, amiga_fbfs_mmap);
  135. insert_global_symbol(alloc_sym("screen-width"),alloc_int(512));
  136. insert_global_symbol(alloc_sym("screen-height"),alloc_int(250));
  137. insert_global_symbol(alloc_sym("screen-bpp"),alloc_int(1));
  138. mount_amiga_keyfs();
  139. mount_posixfs();
  140. }
  141. void uart_puts(char* str) {
  142. printf(str);
  143. }
  144. void uart_putc(char c) {
  145. printf("%c",c);
  146. }
  147. void handle_window_events(struct Window *);
  148. void cleanup_amiga() {
  149. if (window) CloseWindow(window);
  150. if (gfx_base) CloseLibrary(gfx_base);
  151. if (intuition_base) CloseLibrary(intuition_base);
  152. }
  153. void mount_amiga() {
  154. // TODO: exit if stack too small
  155. atexit(cleanup_amiga);
  156. intuition_base = OpenLibrary("intuition.library", 37);
  157. if (intuition_base == NULL) {
  158. printf("error: could not open intuition.library v37\r\n");
  159. return;
  160. }
  161. mount_amiga_fbfs();
  162. //amiga_fbfs_mmap(NULL);
  163. }