Advertisement
Guest User

dont look again

a guest
Oct 17th, 2019
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.18 KB | None | 0 0
  1. // XMega65 Kernal Development Template
  2. // Each function of the kernal is a no-args function
  3. // The functions are placed in the SYSCALLS table surrounded by JMP and NOP
  4.  
  5. #pragma cpu(rom6502)
  6.  
  7. import "string"
  8.  
  9. #pragma link("mega65hyper.ld")
  10.  
  11.  
  12. const char* RASTER = 0xd012;
  13. const char* VIC_MEMORY = 0xd018;
  14. const char* SCREEN = 0x0400;
  15. const char* BGCOL = 0xd021;
  16. const char* COLS = 0xd800;
  17. const char BLACK = 0;
  18. const char BLUE = 6;
  19. const char WHITE = 1;
  20.  
  21. char[] MESSAGE = "checkpoint 5.3";
  22. char[] FIRST = "checkpoint 5.3 berr0185";
  23.  
  24. const unsigned char STATE_NOTRUNNING = $00;
  25. const unsigned char STATE_NEW = $01;
  26. const unsigned char STATE_READY = $02;
  27. const unsigned char STATE_READYSUSPENDED = $03;
  28. const unsigned char STATE_BLOCKEDSUSPENDED = $04;
  29. const unsigned char STATE_BLOCKED = $05;
  30. const unsigned char STATE_RUNNING = $06;
  31. const unsigned char STATE_EXIT = $07;
  32.  
  33. // Process Descriptor Block definition
  34. struct process_descriptor_block {
  35.   // Unique identifier for the process
  36.   unsigned char process_id;
  37.  
  38.   // Current state of the process
  39.   unsigned char process_state;
  40.  
  41.   // Human readable name of the process
  42.   char* process_name;
  43.  
  44.   // Where this process is stored when not running
  45.   // i.e., where in the $20000-$5FFFF memory range the
  46.   // process is stored when not running.
  47.   unsigned long storage_start_address;
  48.   unsigned long storage_end_address;
  49.  
  50.   // Stored registers and related machine state for this
  51.   // process (for the $D640-$D67E machine state registers)
  52.   unsigned char* stored_state;
  53. };
  54.  
  55. // Process stored state will live at $C000-$C7FF, with 256 bytes
  56. // for each process reserved
  57. const unsigned char *stored_pdbs = $C000;
  58. // 8 processes x 16 bytes = 128 bytes for names
  59. const char *process_names = $C800;
  60. // 8 processes x 64 bytes context state = 512 bytes
  61. const unsigned char *process_context_states = $C900;
  62.  
  63. // Which is the current running process?
  64. volatile unsigned char running_pdb=$ff;
  65.  
  66. // Counter for helping determine the next available proccess ID.
  67. volatile unsigned char pid_counter=0;
  68.  
  69. unsigned char next_free_pid()
  70. {
  71.   unsigned short i;
  72.  
  73.   // Start with the next process ID
  74.   unsigned char pid=++pid_counter;
  75.    
  76.   // then make sure that it isn't currently in use by another process
  77.   // This loop must terminate according to the Pigeon Hole Principlle,
  78.   // i.e., there are more possible PIDs than there are processes, so
  79.   // iterating through them will find at least one.
  80.   unsigned char stepped=1;
  81.   while(stepped) {
  82.     stepped=0;
  83.     for(i=0;i<8;i++) {
  84.       struct process_descriptor_block *p
  85.     =(struct process_descriptor_block*)((unsigned short)stored_pdbs+(i<<8));
  86.       if (pid==p->process_id) { pid++; stepped=1; }
  87.     }
  88.   }
  89.  
  90.   return pid;
  91. }
  92.  
  93. void describe_pdb(unsigned char pdb_number)
  94. {
  95.   unsigned char i;
  96.   struct process_descriptor_block *p
  97.     =(struct process_descriptor_block *)(((unsigned short)stored_pdbs)+(((unsigned short)pdb_number)<<8));
  98.  
  99.   print_to_screen("pdb#");
  100.   print_hex((word)pdb_number);
  101.   print_to_screen(":");
  102.   print_newline();
  103.  
  104.   print_to_screen("  pid:          ");
  105.   print_hex((word)p->process_id);
  106.   print_newline();
  107.  
  108.   print_to_screen("  state:        ");
  109.   switch(p->process_state) {
  110.     case STATE_NEW: print_to_screen("new"); break;
  111.     case STATE_RUNNING: print_to_screen("running"); break;
  112.     case STATE_BLOCKED: print_to_screen("blocked"); break;
  113.     case STATE_READY: print_to_screen("ready"); break;
  114.     case STATE_BLOCKEDSUSPENDED: print_to_screen("blockedsuspended"); break;
  115.     case STATE_READYSUSPENDED: print_to_screen("readysuspended"); break;
  116.     case STATE_EXIT: print_to_screen("exit"); break;
  117.     default:
  118.        // Unknown state
  119.        print_hex((word)p->process_state);
  120.   }
  121.   print_newline();
  122.  
  123.   print_to_screen("  process name: ");
  124.   char *n=p->process_name;
  125.   for(i=0;n[i];i++) {
  126.     print_char(n[i]);
  127.   }
  128.   print_newline();
  129.  
  130.   print_to_screen("  mem start:    $");
  131.   print_dhex(p->storage_start_address);
  132.   print_newline();
  133.  
  134.   print_to_screen("  mem end:      $");
  135.   print_dhex(p->storage_end_address);
  136.   print_newline();
  137.  
  138.   print_to_screen("  pc:           $");
  139.   unsigned short *ss=p->stored_state;
  140.   print_hex(ss[4]);
  141.   print_newline();
  142.  
  143.  
  144. }
  145.  
  146. // Setup a new process descriptor block
  147. void initialise_pdb(unsigned char pdb_number,char *name)
  148. {
  149.    unsigned char i;
  150.  
  151.   struct process_descriptor_block *p
  152.     =(struct process_descriptor_block *)(((unsigned short)stored_pdbs)+(((unsigned short)pdb_number)<<8));
  153.  
  154.   // Setup process ID
  155.   p->process_id = next_free_pid();
  156.   //XXX - Call the function next_free_pid() to get a process ID for the
  157.   //process in this PDB, and store it in p->process_id
  158.    
  159.  
  160.   // Setup process name
  161.   // (32 bytes space for each to fit 16 chars + nul)
  162.   // (we could just use 17 bytes, but kickc can't multiply by 17)
  163.   p->process_name=process_names+(((short)i)<<5);
  164.   char *pn=p->process_name;
  165.  
  166.   for(int i = 0; i < 17; i++)
  167.   {
  168.     pn[i]=name[i];
  169.   }
  170.  
  171.   //XXX - copy the string in the array 'name' into the array 'p->process_name'
  172.   //XXX - To make your life easier, do something like char *pn=p->process_name
  173.   //      Then you can just do something along the lines of pn[...]=name[...]
  174.   //      in a loop to copy the name into place.
  175.   //      (The arrays are both 17 bytes long)
  176.  
  177.   // Set process state as not running.
  178.   //XXX - Put the value STATE_NOTRUNNING into p->process_state
  179.   p->process_state = STATE_NOTRUNNING;
  180.  
  181.  
  182.   // Set stored memory area
  183.   // (for now, we just use fixed 8KB steps from $30000-$3FFFF
  184.   // corresponding to the PDB number
  185.   //XXX - Set p->storage_start_address to the correct start address
  186.   //for a process that is in this PDB.
  187.   //The correct address is $30000 + (((unsigned dword)pdb_number)*$2000);
  188.   p->storage_start_address = $30000 + (((unsigned dword)pdb_number)*$2000);
  189.  
  190.   //XXX - Then do the same for the end address of the process
  191.   //This gets stored into p->storage_end_address and the correct
  192.   //address is $31FFF + (((unsigned dword)pdb_number)*$2000);
  193.   p->storage_end_address = $31FFF + (((unsigned dword)pdb_number)*$2000);
  194.  
  195.  
  196.   // Initialise processor state for standard entry at $080D
  197.   // Everything to zero, except for a few things we will set manually
  198.  
  199.   // 64 bytes context switching state for each process
  200.   p->stored_state=process_context_states+(((unsigned short)pdb_number)<<6);
  201.   unsigned char *ss=p->stored_state;
  202.  
  203.   //XXX - Set all 64 bytes of the array 'ss' to zero, to clear the context
  204.   //switching state
  205.   for(i=0;i<63;i++)
  206.   {
  207.     ss[i] = $00;
  208.   }
  209.  
  210.   // Set tandard CPU flags (8-bit stack, interrupts disabled)
  211.   ss[7] = $24;
  212.  
  213.   //XXX - Set the stack pointer to $01FF
  214.   //(This requires a bit of fiddly pointer arithmetic, so to save you
  215.   //the trouble working it out, you can use the following as the left
  216.   //side of the expression:   *(unsigned short *)&ss[x] = ...
  217.   //where x is the offset of the stack pointer low byte (SPL) in the
  218.   //Hypervisor saved state registers in Appendix D of the MEGA65 User's
  219.   //Guide. i.e., if it were at $D640, x would be replaced with 0, and
  220.   //if it were at $D641, x would be replaced with 1, and so on.
  221.   //XXX - Note that the MEGA65 User's Guide has been updated on FLO.
  222.   //You will required the latest version, as otherwise SPL is not listed.
  223.  
  224.   int x = 5;
  225.   *(unsigned short *)&ss[x] = $01FF;
  226.  
  227.   //XXX - Set the program counter to $080D
  228.   //(This requires a bit of fiddly pointer arithmetic, so to save you
  229.   //the trouble working it out, you can use the following as the left
  230.   //side of the expression:   *(unsigned short *)&ss[x] = ...
  231.   //where x is the offset of the program counter low byte (PCL) in the
  232.   //Hypervisor saved state registers in Appendix D of the MEGA65 User's
  233.   //Guide.
  234.  
  235.   x = 8;
  236.   *(unsigned short *)&ss[x] = $080D;
  237.  
  238.  
  239.   return;
  240.  
  241. }
  242.  
  243. void resume_pdb(unsigned char pdb_number)
  244. {
  245.   struct process_descriptor_block *p
  246.     =(struct process_descriptor_block *)(((unsigned short)stored_pdbs)+(((unsigned short)pdb_number)<<8));
  247.  
  248.   // Copy stored memory into place
  249.   // Copy from $0000-$03FF and $0800-$1FFF, so that we don't overwrite
  250.   // the screen
  251.   dma_copy((unsigned dword)(p->storage_start_address), $0000, $0400);
  252.   dma_copy((unsigned dword)(p->storage_start_address)+$0800, $0800, $1800);
  253.   //XXX - Copy $0400 bytes from p->storage_start_address to location $0000
  254.   //XXX - Copy $1800 bytes from p->storage_start_address+$0800 to location $0800
  255.   //      (Use (unsigned dword)(p->storage_start_address)+offset to pass these
  256.   //       addresses in calls to dma_copy() to cast them to the correct type.)
  257.  
  258.   // Load stored CPU state into Hypervisor saved register area at $FFD3640
  259.   unsigned char *ss=p->stored_state;
  260.   //XXX - Use a for() loop to copy 63 bytes from ss[0]--ss[62] to ((unsigned char *)$D640)[0]
  261.   //      -- ((unsigned char *)$D640)[62] (dma_copy doesn't work for this for some slightly
  262.   //      complex reasons.)
  263.   for(int i = 0; i < 63; i++)
  264.   {
  265.     ((unsigned char *)$D640)[i] = ss[i];
  266.   }
  267.  
  268.   // Set state of process to running
  269.   //XXX - Set p->process_state to STATE_RUNNING
  270.   p->process_state = STATE_RUNNING;
  271.  
  272.   // Mark this PDB as the running process
  273.   //XXX - Set running_pdb to the PDB number we are resuming
  274.   running_pdb = pdb_number;
  275.  
  276.  
  277.   // Exit hypervisor and cause CPU register values (including PC) to be restored from
  278.   // those loaded from p->stored_state
  279.   exit_hypervisor();
  280. }
  281.  
  282. struct dma_list
  283. {
  284.   unsigned char request_format0a;
  285.   unsigned char source_mb_option80;
  286.   unsigned char source_mb;
  287.   unsigned char dest_mb_option81;
  288.   unsigned char dest_mb;
  289.   unsigned char end_of_options00;
  290.  
  291.   unsigned char cmd; // $00 = copy + end of list
  292.   unsigned short size;
  293.   unsigned short source_addr;
  294.   unsigned char source_bank;
  295.   unsigned short dest_addr;
  296.   unsigned char dest_bank;
  297.   unsigned char modulo00;
  298.  
  299. };
  300.  
  301. void dma_copy(unsigned long src,unsigned long dest,unsigned short length)
  302. {
  303.   struct dma_list list;
  304.   list.request_format0a=$0a;
  305.   list.source_mb_option80=$80;
  306.   list.dest_mb_option81=$81;
  307.   list.end_of_options00=$00;
  308.   list.cmd=$00;
  309.   list.modulo00=$00;
  310.  
  311.   list.size=length;
  312.   list.dest_mb=(unsigned char)(dest>>20);
  313.   list.dest_bank=(dest>>16)&0x7f;
  314.   list.dest_addr=(unsigned word)dest;
  315.  
  316.   // Work around missing fragments in KickC
  317.   list.source_mb=(unsigned char)(src>>20);
  318.   list.source_bank=(src>>16)&0x7f;
  319.  
  320.   list.source_addr=(unsigned word)src;
  321.  
  322.   // DMA list lives in hypervisor memory, so use correct list address
  323.   // when triggering
  324.   // (Variables in KickC usually end up in ZP, so we have to provide the
  325.   // base page correction
  326.   if (!(>&list))
  327.     *(unsigned char *)$D701 = $BF+(>&list);
  328.   else
  329.     *(unsigned char *)$D701 = (>&list);
  330.   *(unsigned char *)$D702 = $7F;
  331.   *(unsigned char *)$D704 = $FF;
  332.   *(unsigned char *)$D705 = <&list;
  333.  
  334. }
  335.  
  336. volatile unsigned char lpeek_value = $12;
  337. unsigned char lpeek(unsigned long address)
  338. {
  339.   // Work around all sorts of fun problems in KickC
  340.   //  dma_copy(address,$BF00+((unsigned short)<&lpeek_value),1);  
  341.   unsigned dword t = (unsigned dword)&lpeek_value;
  342.   if (>((unsigned short)&lpeek_value)) t+=$FFF0000;
  343.   else t += $FFFBF00;
  344.  
  345.  
  346.   unsigned char *c = $BF00 + (unsigned char *)&t;
  347.  
  348.   dma_copy(address,t,1);
  349.  
  350.   return lpeek_value;
  351. }
  352.  
  353. volatile unsigned char *current_screen_line = SCREEN;
  354. volatile unsigned char current_screen_x = 0;
  355.  
  356. void print_char(char c)
  357. {
  358.    current_screen_line[current_screen_x++]=c;
  359. }
  360.  
  361. void print_to_screen(char *message)
  362. {
  363.   char *c=message;
  364.   while(*c) {
  365.     current_screen_line[current_screen_x++]=*c;
  366.     c++;
  367.   }
  368. }
  369.  
  370. void print_newline()
  371. {
  372.   current_screen_line+=40;
  373.   current_screen_x=0;
  374. }
  375.  
  376.  
  377. void print_hex(unsigned word value)
  378. {
  379.   char[5] hex;
  380.   unsigned char i;
  381.   for(i=0;i<8;i++) {
  382.     if (value<0xa000) hex[i]='0'+(char)(value>>12);
  383.     else hex[i]=(char)(value>>12)-9;
  384.     value<<=4;
  385.   }
  386.   hex[4]=0;
  387.   print_to_screen(hex);
  388. }
  389.  
  390. void print_dhex(unsigned dword value)
  391. {
  392.   print_hex((word)(value>>16));
  393.   print_hex((unsigned word)value);
  394. }
  395.  
  396. unsigned char load_program(unsigned char pdb_number)
  397. {
  398.   // Search through packed programs for the one we need
  399.   unsigned long address=$20000;
  400.   unsigned char i;
  401.   unsigned char match=0;
  402.  
  403.  
  404.   struct process_descriptor_block *pdb
  405.     =(struct process_descriptor_block*)
  406.     ((unsigned short)stored_pdbs+(((unsigned short)pdb_number)<<8));
  407.  
  408.  
  409.  
  410.   while(lpeek(address)) {
  411.  
  412.     // Check for name match
  413.     for(i=0;i<16;i++) {
  414.  
  415.       unsigned char c1=lpeek(address+i);
  416.       unsigned char *n=pdb->process_name;
  417.       unsigned char c2=n[i];
  418.  
  419.       if ((c1==0)&&(c2==0))
  420.     {
  421.       match=1;
  422.       break;
  423.     }
  424.       if (c1!=c2)
  425.     break;
  426.     }
  427.  
  428.  
  429.     if (match) {
  430.  
  431.       // Found program -- now copy it into place
  432.       unsigned short length;
  433.       unsigned char *hb=((unsigned char *)&length)+1;
  434.       length = lpeek(address+16);
  435.       *hb = lpeek(address+17);
  436.  
  437.       // XXX - Make sure it fits the allocated memory
  438.      
  439.       // Copy program into place.
  440.       // As the program is formatted as a C64 program with a
  441.       // $0801 header, we copy it to offset $07FF.
  442.  
  443.       unsigned dword dest=pdb->storage_start_address;
  444.       dest+=$07FF;
  445.  
  446.       dma_copy(address+32,dest,length);
  447.  
  448.       // Mark process as now runnable
  449.       pdb->process_state=STATE_READY;
  450.  
  451.       return 0;
  452.     }
  453.  
  454.     unsigned long new_address=(dword)lpeek(address+18);
  455.     new_address|=((dword)(lpeek(address+19)))<<8;
  456.     new_address|=((dword)(lpeek(address+20)))<<16;
  457.  
  458.     address=new_address;
  459.  
  460.   }
  461.  
  462.   // Failed to find program
  463.   return 1;
  464. }
  465.  
  466. void main() {
  467.  
  468. }
  469.  
  470. void exit_hypervisor()
  471. {
  472.     // Exit hypervisor
  473.     *(char *)$D67F = $01;
  474. }
  475.  
  476. //Sample sys calls to display a character on screen
  477. void syscall00()
  478. {
  479.   exit_hypervisor();
  480. }
  481. void syscall01()
  482. {
  483.   exit_hypervisor();
  484. }
  485.  
  486. void syscall02()
  487. {
  488.   exit_hypervisor();
  489. }
  490.  
  491. void syscall03()
  492. {
  493.     describe_pdb(running_pdb);
  494.  
  495.     exit_hypervisor();
  496. }
  497.  
  498. void syscall04()
  499. {
  500.     exit_hypervisor();
  501. }
  502.  
  503. void syscall05()
  504. {
  505.     exit_hypervisor();
  506. }
  507.  
  508. void syscall06()
  509. {
  510.     exit_hypervisor();
  511. }
  512.  
  513. void syscall07()
  514. {
  515.     exit_hypervisor();
  516. }
  517.  
  518. void syscall08()
  519. {
  520.     exit_hypervisor();
  521. }
  522.  
  523. void syscall09()
  524. {
  525.     exit_hypervisor();
  526. }
  527.  
  528. void syscall0A()
  529. {
  530.     exit_hypervisor();
  531. }
  532.  
  533. void syscall0B()
  534. {
  535.     exit_hypervisor();
  536. }
  537.  
  538. void syscall0C()
  539. {
  540.     exit_hypervisor();
  541. }
  542.  
  543. void syscall0D()
  544. {
  545.     exit_hypervisor();
  546. }
  547.  
  548. void syscall0E()
  549. {
  550.     exit_hypervisor();
  551. }
  552.  
  553. void syscall0F()
  554. {
  555.     exit_hypervisor();
  556. }
  557.  
  558. void syscall10()
  559. {
  560.     exit_hypervisor();
  561. }
  562.  
  563. void SECURENTR()
  564. {
  565.     exit_hypervisor();
  566. }
  567.  
  568. void SECUREXIT()
  569. {
  570.     exit_hypervisor();
  571. }
  572.  
  573. void syscall13()
  574. {
  575.     exit_hypervisor();
  576. }
  577.  
  578. void syscall14()
  579. {
  580.     exit_hypervisor();
  581. }
  582.  
  583. void syscall15()
  584. {
  585.     exit_hypervisor();
  586. }
  587.  
  588. void syscall16()
  589. {
  590.     exit_hypervisor();
  591. }
  592.  
  593. void syscall17()
  594. {
  595.     exit_hypervisor();
  596. }
  597.  
  598. void syscall18()
  599. {
  600.     exit_hypervisor();
  601. }
  602.  
  603. void syscall19()
  604. {
  605.     exit_hypervisor();
  606. }
  607.  
  608. void syscall1A()
  609. {
  610.     exit_hypervisor();
  611. }
  612.  
  613. void syscall1B()
  614. {
  615.     exit_hypervisor();
  616. }
  617.  
  618. void syscall1C()
  619. {
  620.     exit_hypervisor();
  621. }
  622.  
  623. void syscall1D()
  624. {
  625.     exit_hypervisor();
  626. }
  627.  
  628. void syscall1E()
  629. {
  630.     exit_hypervisor();
  631. }
  632.  
  633. void syscall1F()
  634. {
  635.     exit_hypervisor();
  636. }
  637.  
  638. void syscall20()
  639. {
  640.     exit_hypervisor();
  641. }
  642.  
  643. void syscall21()
  644. {
  645.     exit_hypervisor();
  646. }
  647.  
  648. void syscall22()
  649. {
  650.     exit_hypervisor();
  651. }
  652.  
  653. void syscall23()
  654. {
  655.     exit_hypervisor();
  656. }
  657.  
  658. void syscall24()
  659. {
  660.     exit_hypervisor();
  661. }
  662.  
  663. void syscall25()
  664. {
  665.     exit_hypervisor();
  666. }
  667.  
  668. void syscall26()
  669. {
  670.     exit_hypervisor();
  671. }
  672.  
  673. void syscall27()
  674. {
  675.     exit_hypervisor();
  676. }
  677.  
  678. void syscall28()
  679. {
  680.     exit_hypervisor();
  681. }
  682.  
  683. void syscall29()
  684. {
  685.     exit_hypervisor();
  686. }
  687.  
  688. void syscall2A()
  689. {
  690.     exit_hypervisor();
  691. }
  692.  
  693. void syscall2B()
  694. {
  695.     exit_hypervisor();
  696. }
  697.  
  698. void syscall2C()
  699. {
  700.     exit_hypervisor();
  701. }
  702.  
  703. void syscall2D()
  704. {
  705.     exit_hypervisor();
  706. }
  707.  
  708. void syscall2E()
  709. {
  710.     exit_hypervisor();
  711. }
  712.  
  713. void syscall2F()
  714. {
  715.     exit_hypervisor();
  716. }
  717.  
  718. void syscall30()
  719. {
  720.     exit_hypervisor();
  721. }
  722.  
  723. void syscall31()
  724. {
  725.     exit_hypervisor();
  726. }
  727.  
  728. void syscall32()
  729. {
  730.     exit_hypervisor();
  731. }
  732.  
  733. void syscall33()
  734. {
  735.     exit_hypervisor();
  736. }
  737.  
  738. void syscall34()
  739. {
  740.     exit_hypervisor();
  741. }
  742.  
  743. void syscall35()
  744. {
  745.     exit_hypervisor();
  746. }
  747.  
  748. void syscall36()
  749. {
  750.     exit_hypervisor();
  751. }
  752.  
  753. void syscall37()
  754. {
  755.     exit_hypervisor();
  756. }
  757.  
  758. void syscall38()
  759. {
  760.     exit_hypervisor();
  761. }
  762.  
  763. void syscall39()
  764. {
  765.     exit_hypervisor();
  766. }
  767.  
  768. void syscall3A()
  769. {
  770.     exit_hypervisor();
  771. }
  772.  
  773. void syscall3B()
  774. {
  775.     exit_hypervisor();
  776. }
  777.  
  778. void syscall3C()
  779. {
  780.     exit_hypervisor();
  781. }
  782.  
  783. void syscall3D()
  784. {
  785.     exit_hypervisor();
  786. }
  787.  
  788. void syscall3E()
  789. {
  790.     exit_hypervisor();
  791. }
  792.  
  793. void syscall3F()
  794. {
  795.     exit_hypervisor();
  796. }
  797.  
  798. void RESET()
  799. {
  800.  
  801.     //Initializes screen memory
  802.     *VIC_MEMORY = 0x14;
  803.    
  804.     //Fill the screen
  805.     memset(SCREEN, ' ', 40*25);
  806.  
  807.     //Sets the colour of every char on screen (white)
  808.     memset(COLS, WHITE, 40*25);
  809.  
  810.     /*Print the message
  811.     char* sc = SCREEN+40; //one line down
  812.     char* msg = FIRST; //the msg to display
  813.  
  814.     //copy routine that copies the string
  815.     while(*msg)
  816.     {
  817.         *sc++ = *msg++;
  818.     }*/
  819.  
  820.     current_screen_line = SCREEN;
  821.         print_newline();
  822.     print_newline();
  823.         print_newline();
  824.  
  825.         initialise_pdb(0,"program1.prg");
  826.     load_program(0);
  827.     resume_pdb(0);     
  828.     //describe_pdb(0);
  829.  
  830.     //Forever loop displaying two white lines
  831.     while(true)
  832.     {
  833.         if(*RASTER==54 || *RASTER==66)
  834.         {
  835.             *BGCOL = WHITE;
  836.         }
  837.         else
  838.         {
  839.             *BGCOL = BLACK;
  840.         }  
  841.     }
  842.  
  843.     exit_hypervisor();
  844.  
  845. }
  846.  
  847. void PAGFAULT()
  848. {
  849.     exit_hypervisor();
  850. }
  851.  
  852. void RESTORKEY()
  853. {
  854.     exit_hypervisor();
  855. }
  856.  
  857. void ALTTABKEY()
  858. {
  859.     exit_hypervisor();
  860. }
  861.  
  862. void VF011RD()
  863. {
  864.     exit_hypervisor();
  865. }
  866.  
  867. void VF011WR()
  868. {
  869.     exit_hypervisor();
  870. }
  871.  
  872. void RESERVED()
  873. {
  874.     exit_hypervisor();
  875. }
  876.  
  877. void CPUKIL()
  878. {
  879.     exit_hypervisor();
  880. }
  881.  
  882. //Now we select the SYSCALL segment to hold the SYSCALL/trap entry point table.
  883. #pragma data_seg(Syscall)
  884.  
  885. //The structure of each entry point is JMP (handler address) + NOP,
  886. // We have a char (xjmp) to hold the opcode for the JMP instruction,
  887. //and then put the address of the SYSCALL/trap handler in the next
  888. //two points as a pointer, and end with the NOP instruction opcode.
  889. struct SysCall
  890. {
  891.     char xjmp;      //Holds $4C, the JMP $nnnn opcode
  892.     void()* syscall;    //Holds handler address, will be the target of the JMP
  893.     char xnop;      //Holds $EA, the NOP opcode
  894. };
  895.  
  896. //To save writing 0x4c and 0xEA all the time, we define them as constants
  897. const char JMP = 0x4c;
  898. const char NOP = 0xea;
  899.  
  900. //Each line is an instance of the struct SysCall from above, with the JMP
  901. //opcode value, the address of the handler routine and the NOP opcode.
  902. export struct SysCall[] SYSCALLS =
  903. {
  904.     { JMP, &syscall00, NOP },
  905.     { JMP, &syscall01, NOP },
  906.     { JMP, &syscall02, NOP },
  907.     { JMP, &syscall03, NOP },
  908.     { JMP, &syscall04, NOP },
  909.     { JMP, &syscall05, NOP },
  910.     { JMP, &syscall06, NOP },
  911.     { JMP, &syscall07, NOP },
  912.     { JMP, &syscall08, NOP },
  913.     { JMP, &syscall09, NOP },
  914.     { JMP, &syscall0A, NOP },
  915.     { JMP, &syscall0B, NOP },
  916.     { JMP, &syscall0C, NOP },
  917.     { JMP, &syscall0D, NOP },
  918.     { JMP, &syscall0E, NOP },
  919.     { JMP, &syscall0F, NOP },
  920.     { JMP, &syscall10, NOP },
  921.     { JMP, &SECURENTR, NOP },
  922.     { JMP, &SECUREXIT, NOP },
  923.     { JMP, &syscall13, NOP },
  924.     { JMP, &syscall14, NOP },
  925.     { JMP, &syscall15, NOP },
  926.     { JMP, &syscall16, NOP },
  927.     { JMP, &syscall17, NOP },
  928.     { JMP, &syscall18, NOP },
  929.     { JMP, &syscall19, NOP },
  930.     { JMP, &syscall1A, NOP },
  931.     { JMP, &syscall1B, NOP },
  932.     { JMP, &syscall1C, NOP },
  933.     { JMP, &syscall1D, NOP },
  934.     { JMP, &syscall1E, NOP },
  935.     { JMP, &syscall1F, NOP },
  936.     { JMP, &syscall20, NOP },
  937.     { JMP, &syscall21, NOP },
  938.     { JMP, &syscall22, NOP },
  939.     { JMP, &syscall23, NOP },
  940.     { JMP, &syscall24, NOP },
  941.     { JMP, &syscall25, NOP },
  942.     { JMP, &syscall26, NOP },
  943.     { JMP, &syscall27, NOP },
  944.     { JMP, &syscall28, NOP },
  945.     { JMP, &syscall29, NOP },
  946.     { JMP, &syscall2A, NOP },
  947.     { JMP, &syscall2B, NOP },
  948.     { JMP, &syscall2C, NOP },
  949.     { JMP, &syscall2D, NOP },
  950.     { JMP, &syscall2E, NOP },
  951.     { JMP, &syscall2F, NOP },
  952.     { JMP, &syscall30, NOP },
  953.     { JMP, &syscall31, NOP },
  954.     { JMP, &syscall32, NOP },
  955.     { JMP, &syscall33, NOP },
  956.     { JMP, &syscall34, NOP },
  957.     { JMP, &syscall35, NOP },
  958.     { JMP, &syscall36, NOP },
  959.     { JMP, &syscall37, NOP },
  960.     { JMP, &syscall38, NOP },
  961.     { JMP, &syscall39, NOP },
  962.     { JMP, &syscall3A, NOP },
  963.     { JMP, &syscall3B, NOP },
  964.     { JMP, &syscall3C, NOP },
  965.     { JMP, &syscall3D, NOP },
  966.     { JMP, &syscall3E, NOP },
  967.     { JMP, &syscall3F, NOP }
  968. };
  969.  
  970. //Function for undefined traps
  971. void undefined_trap()
  972. {
  973.    
  974. }
  975.  
  976.  
  977.  
  978. //IN this example we only had 2 syscalls defined, so rather than having
  979. //another 62 lines, we can just ask KickC to make the TRAP table begin
  980. //at the next mulitple of $100, ie at $8100
  981. export align(0x100) struct SysCall[] SYSCALL_RESET =
  982. {
  983.     { JMP, &RESET, NOP },
  984.     { JMP, &undefined_trap, NOP },
  985.     { JMP, &undefined_trap, NOP },
  986.     { JMP, &undefined_trap, NOP },
  987.     { JMP, &undefined_trap, NOP },
  988.     { JMP, &undefined_trap, NOP },
  989.     { JMP, &undefined_trap, NOP },
  990.     { JMP, &undefined_trap, NOP },
  991.     { JMP, &undefined_trap, NOP },
  992.     { JMP, &undefined_trap, NOP },
  993.     { JMP, &undefined_trap, NOP },
  994.     { JMP, &undefined_trap, NOP },
  995.     { JMP, &undefined_trap, NOP },
  996.     { JMP, &undefined_trap, NOP },
  997.     { JMP, &undefined_trap, NOP },
  998.     { JMP, &undefined_trap, NOP },
  999.     { JMP, &undefined_trap, NOP },
  1000.     { JMP, &undefined_trap, NOP },
  1001.     { JMP, &undefined_trap, NOP },
  1002.     { JMP, &undefined_trap, NOP },
  1003.     { JMP, &undefined_trap, NOP },
  1004.     { JMP, &undefined_trap, NOP },
  1005.     { JMP, &undefined_trap, NOP },
  1006.     { JMP, &undefined_trap, NOP },
  1007.     { JMP, &undefined_trap, NOP },
  1008.     { JMP, &undefined_trap, NOP },
  1009.     { JMP, &undefined_trap, NOP },
  1010.     { JMP, &undefined_trap, NOP },
  1011.     { JMP, &undefined_trap, NOP },
  1012.     { JMP, &undefined_trap, NOP },
  1013.     { JMP, &undefined_trap, NOP },
  1014.     { JMP, &undefined_trap, NOP },
  1015.     { JMP, &undefined_trap, NOP },
  1016.     { JMP, &undefined_trap, NOP },
  1017.     { JMP, &undefined_trap, NOP },
  1018.     { JMP, &undefined_trap, NOP },
  1019.     { JMP, &undefined_trap, NOP },
  1020.     { JMP, &undefined_trap, NOP },
  1021.     { JMP, &undefined_trap, NOP },
  1022.     { JMP, &undefined_trap, NOP },
  1023.     { JMP, &undefined_trap, NOP },
  1024.     { JMP, &undefined_trap, NOP },
  1025.     { JMP, &undefined_trap, NOP },
  1026.     { JMP, &undefined_trap, NOP },
  1027.     { JMP, &undefined_trap, NOP },
  1028.     { JMP, &undefined_trap, NOP },
  1029.     { JMP, &undefined_trap, NOP },
  1030.     { JMP, &undefined_trap, NOP },
  1031.     { JMP, &undefined_trap, NOP }
  1032. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement