6502 emulator for Commodore 64 ROMs, serial terminal edition for MBED. Recommend terminal echo on, line edit on, caps lock, 115200bps, implicit carriage return on newline, currently non-buffered so don't paste lots of stuff

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cbmconsole.cpp Source File

cbmconsole.cpp

00001 // cbmconsole.c - Commodore Console Emulation
00002 //
00003 ////////////////////////////////////////////////////////////////////////////////
00004 //
00005 // c-simple-emu-cbm (C Portable Version)
00006 // C64/6502 Emulator for Terminal Console
00007 //
00008 // MIT License
00009 //
00010 // Copyright(c) 2020 by David R. Van Wagner
00011 // davevw.com
00012 //
00013 // Permission is hereby granted, free of charge, to any person obtaining a copy
00014 // of this software and associated documentation files (the "Software"), to deal
00015 // in the Software without restriction, including without limitation the rights
00016 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00017 // copies of the Software, and to permit persons to whom the Software is
00018 // furnished to do so, subject to the following conditions:
00019 //
00020 // The above copyright notice and this permission notice shall be included in all
00021 // copies or substantial portions of the Software.
00022 //
00023 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00024 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00025 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
00026 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00027 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00028 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00029 // SOFTWARE.
00030 //
00031 ////////////////////////////////////////////////////////////////////////////////
00032 
00033 #include <mbed.h>
00034 #include "cbmconsole.h"
00035 
00036 // locals
00037 static int supress_first_clear = 1;
00038 static int supress_next_cr = 0;
00039 static char buffer[256];
00040 static int buffer_head = 0;
00041 static int buffer_tail = 0;
00042 static int buffer_count = 0;
00043 
00044 // global references
00045 extern Serial pc;
00046 
00047 static void Console_Clear()
00048 {
00049     if (supress_first_clear)
00050     {
00051         supress_first_clear = 0;
00052         return;
00053     }
00054     pc.printf("\x1B[2J\x1B[H");
00055 }
00056 
00057 static void Console_Cursor_Up()
00058 {
00059     pc.printf("\x1B[A");
00060 }
00061 
00062 static void Console_Cursor_Down()
00063 {
00064     pc.printf("\x1B[B");
00065 }
00066 
00067 static void Console_Cursor_Left()
00068 {
00069     pc.printf("\x1B[D");
00070 }
00071 
00072 static void Console_Cursor_Right()
00073 {
00074     pc.printf("\x1B[C");
00075 }
00076 
00077 static void Console_Cursor_Home()
00078 {
00079     pc.printf("\x1B[H");
00080 }
00081 
00082 void CBM_Console_WriteChar(unsigned char c)
00083 {
00084     // we're emulating, so draw character on local console window
00085     if (c == 0x0D)
00086     {
00087         if (supress_next_cr)
00088             supress_next_cr = 0;
00089         else
00090             pc.putc('\n');
00091     }
00092     else if (c >= ' ' && c <= '~')
00093     {
00094         //ApplyColor ? .Invoke();
00095         pc.putc(c);
00096     }
00097     else if (c == 157) // left
00098         Console_Cursor_Left();
00099     else if (c == 29) // right
00100         Console_Cursor_Right();
00101     else if (c == 145) // up
00102         Console_Cursor_Up();
00103     else if (c == 17) // down
00104         Console_Cursor_Down();
00105     else if (c == 19) // home
00106         Console_Cursor_Home();
00107     else if (c == 147)
00108     {
00109         Console_Clear();
00110     }
00111 }
00112 
00113 // blocking read to get next typed character
00114 unsigned char CBM_Console_ReadChar(void)
00115 {
00116     unsigned char c;
00117     if (buffer_count == 0)
00118     {
00119         while (true)
00120         {
00121             int i = pc.getc();
00122             if (i == -1) // no character available
00123             {
00124                 wait(20); // be nice to cpu
00125             }
00126             else
00127             {
00128                 c = (unsigned char)i;
00129                 if (c == '\n')
00130                     c = '\r';
00131                 break;
00132             }
00133         }
00134 //      if (c >= ' ' && c <= '~')
00135 //          pc.putc(c); // echo
00136         if (c == '\r')
00137             supress_next_cr = true;
00138         return c;
00139     }
00140     c = buffer[buffer_head++];
00141     if (buffer_head >= sizeof(buffer))
00142         buffer_head = 0;
00143     --buffer_count;
00144     return c;
00145 }
00146 
00147 void CBM_Console_Push(const char* s)
00148 {
00149     while (s != 0 && *s != 0 && buffer_count < sizeof(buffer))
00150     {
00151         buffer[buffer_tail++] = *(s++);
00152         if (buffer_tail >= sizeof(buffer))
00153             buffer_tail = 0;
00154         ++buffer_count;
00155     }
00156 }