{"action":"created","issue":{"url":"https://api.github.com/repos/cc65/cc65/issues/324","repository_url":"https://api.github.com/repos/cc65/cc65","labels_url":"https://api.github.com/repos/cc65/cc65/issues/324/labels{/name}","comments_url":"https://api.github.com/repos/cc65/cc65/issues/324/comments","events_url":"https://api.github.com/repos/cc65/cc65/issues/324/events","html_url":"https://github.com/cc65/cc65/issues/324","id":167213017,"number":324,"title":"Raster interrupts kill keyboard","user":{"login":"spektro","id":6050830,"avatar_url":"https://avatars.githubusercontent.com/u/6050830?v=3","gravatar_id":"","url":"https://api.github.com/users/spektro","html_url":"https://github.com/spektro","followers_url":"https://api.github.com/users/spektro/followers","following_url":"https://api.github.com/users/spektro/following{/other_user}","gists_url":"https://api.github.com/users/spektro/gists{/gist_id}","starred_url":"https://api.github.com/users/spektro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/spektro/subscriptions","organizations_url":"https://api.github.com/users/spektro/orgs","repos_url":"https://api.github.com/users/spektro/repos","events_url":"https://api.github.com/users/spektro/events{/privacy}","received_events_url":"https://api.github.com/users/spektro/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":7,"created_at":"2016-07-24T02:14:00Z","updated_at":"2016-08-05T16:38:04Z","closed_at":null,"body":"I have a program for Plus/4 which uses raster interrupts. The interrupt routine works fine (I can split the screen) and the main program runs also well. The problem is that the raster interrupts kill the keyboard. cgetc() function placed in the main program loop receives nothing when I press keys.\r\n\r\nIf I add an interrupt routine without enabling raster interrupts, I can read the keyboard in the main program."},"comment":{"url":"https://api.github.com/repos/cc65/cc65/issues/comments/237899491","html_url":"https://github.com/cc65/cc65/issues/324#issuecomment-237899491","issue_url":"https://api.github.com/repos/cc65/cc65/issues/324","id":237899491,"user":{"login":"greg-king5","id":4145570,"avatar_url":"https://avatars.githubusercontent.com/u/4145570?v=3","gravatar_id":"","url":"https://api.github.com/users/greg-king5","html_url":"https://github.com/greg-king5","followers_url":"https://api.github.com/users/greg-king5/followers","following_url":"https://api.github.com/users/greg-king5/following{/other_user}","gists_url":"https://api.github.com/users/greg-king5/gists{/gist_id}","starred_url":"https://api.github.com/users/greg-king5/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/greg-king5/subscriptions","organizations_url":"https://api.github.com/users/greg-king5/orgs","repos_url":"https://api.github.com/users/greg-king5/repos","events_url":"https://api.github.com/users/greg-king5/events{/privacy}","received_events_url":"https://api.github.com/users/greg-king5/received_events","type":"User","site_admin":false},"created_at":"2016-08-05T16:38:04Z","updated_at":"2016-08-05T16:38:04Z","body":"If you change the first line in `f_IntRoutine()`, then you can see what the problem is (don't define ENABLE_RASTER_INT).\r\n```C\r\n#include <6502.h>\r\n#include <plus4.h>\r\n#include <peekpoke.h>\r\n#include <conio.h>\r\n\r\n#define TEMP_STACK_SIZE 1024\r\n\r\n/* Raster lines */\r\n#define RASTER_LINE_1 0x0137\r\n#define RASTER_LINE_2 0x009e\r\n\r\n/* Macro for setting raster line */\r\n#define m_SetRasterline( RASTERLINE ) TED.imr = ( TED.imr & 0xfe ) | ( ( RASTERLINE & 0x0100 ) >> 8 ); TED.irq_rasterline = ( unsigned char ) ( RASTERLINE & 0x00ff )\r\n/* Macro for waiting past raster column */\r\n#define m_WaitRasterColumn( RASTERCOLUMN ) while ( TED.rastercolumn == RASTERCOLUMN ) {}\r\n\r\n/* Define ENABLE_RASTER_INT to enable raster interrupts */\r\n// #define ENABLE_RASTER_INT\r\n\r\n/* Define ENABLE_READ_KEYBOARD to read user input */\r\n#define ENABLE_READ_KEYBOARD\r\n\r\nvoid f_WaitRasterline ( unsigned int unRasterline );\r\nunsigned char f_IntRoutine ( void );\r\nunsigned char f_RastIntRoutine ( void );\r\n\r\nunsigned char aucTempStack [ TEMP_STACK_SIZE ];\r\n\r\n/*\r\n** ff09 = TED.irr\r\n** ff0a = TED.imr\r\n** ff0b = TED.irq_rasterline\r\n*/\r\nvoid main ( void ) {\r\n    unsigned char ucCount = 0;\r\n\r\n    set_irq (\r\n#ifdef ENABLE_RASTER_INT\r\n             f_RastIntRoutine,\r\n#else\r\n             f_IntRoutine,\r\n#endif\r\n             aucTempStack, TEMP_STACK_SIZE );\r\n\r\n#ifdef ENABLE_RASTER_INT\r\n    SEI ();\r\n    /* Enable raster interrupts */\r\n    TED.imr = TED.imr | 0x02;\r\n    /* Set raster line (9 bits) */\r\n    m_SetRasterline ( RASTER_LINE_1 );\r\n    CLI ();\r\n#endif\r\n\r\n    /* Print key presses */\r\n    for ( ;; ) {\r\n        /* Show that the main program is alive */\r\n        POKE ( 0x0c00, ++ucCount );\r\n\r\n#ifdef ENABLE_READ_KEYBOARD\r\n        /*\r\n        ** Read the keyboard; and, print the read character.\r\n        ** If you enable keyboard reading while the raster interrupts\r\n        ** are running, the main program will halt in cgetc() call .\r\n        */\r\n        cputc ( cgetc () );\r\n#endif\r\n    }\r\n}\r\n\r\nvoid f_WaitRasterline ( unsigned int unRasterline ) {\r\n    unsigned char ucMsb = ( unsigned char ) ( ( unRasterline & 0x0100 ) >> 8 );\r\n    unsigned char ucLsb = ( unsigned char ) ( unRasterline & 0x00ff );\r\n    while ( TED.rasterline_hi == ucMsb ) {}\r\n    while ( TED.rasterline_lo == ucLsb ) {}\r\n}\r\n\r\nunsigned char f_IntRoutine ( void ) {\r\n    TED.bordercolor ^= 0x01;\r\n    return ( IRQ_NOT_HANDLED );\r\n}\r\n\r\nunsigned char f_RastIntRoutine ( void ) {\r\n    unsigned int unRasterline;\r\n\r\n    /* Request new raster interrupt  -- don't stop other interrupts! */\r\n    TED.irr = 0x02;\r\n\r\n    /* Get rasterline */\r\n    unRasterline = TED.imr & 0x01;\r\n    unRasterline = ( unRasterline << 8 ) | TED.irq_rasterline;\r\n\r\n    /* Which raster line? */\r\n    switch ( unRasterline ) {\r\n        case RASTER_LINE_1: {\r\n            /* Set colors */\r\n            m_WaitRasterColumn ( 0x00 );\r\n            TED.bordercolor = BCOLOR_BLUE | CATTR_LUMA3;\r\n            TED.bgcolor     = BCOLOR_BLUE | CATTR_LUMA3;\r\n\r\n            /* Request raster line 2 */\r\n            m_SetRasterline ( RASTER_LINE_2 );\r\n            break;\r\n        }\r\n        case RASTER_LINE_2: {\r\n            /* Set colors */\r\n            m_WaitRasterColumn ( 0x00 );\r\n            TED.bordercolor = BCOLOR_GREEN | CATTR_LUMA3;\r\n            TED.bgcolor     = BCOLOR_GREEN | CATTR_LUMA3;\r\n\r\n            /* Request raster line 1 */\r\n            m_SetRasterline ( RASTER_LINE_1 );\r\n            break;\r\n        }\r\n        default: {}\r\n    }\r\n    return ( IRQ_HANDLED );\r\n}\r\n```\r\n\r\nCommodore's TED computer models use raster interrupts to \"drive\" the Jiffy clock and the keyboard scanner.  If a program uses rasters, then it interferes with the Kernal.  If that program doesn't \"eat\" the interrupts, then the Kernal interferes with the program.  Therefore, your interrupt code will need to call the Kernal's `UDTIM` and `SCNKEY` routines one time during each video frame.\r\n\r\nHowever, cc65 code needs to turn the ROM on and off.  Therefore, we will need to write special functions for the `plus4` library."}}
{"actor":{"display_login":"greg-king5"}}