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

More details at:

[https://github.com/davervw] [https://techwithdave.davevw.com/2020/03/simple-emu-c64.html]

Committer:
davervw
Date:
Fri Apr 17 09:15:50 2020 +0000
Revision:
9:b4293b01083b
Parent:
7:f49fa56672d8
comment updates, and implemented optional #define LOCAL_LOAD // for loading from Mbed filesystem

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davervw 0:90de1cbc8a5f 1 // cbmconsole.c - Commodore Console Emulation
davervw 0:90de1cbc8a5f 2 //
davervw 0:90de1cbc8a5f 3 ////////////////////////////////////////////////////////////////////////////////
davervw 0:90de1cbc8a5f 4 //
davervw 0:90de1cbc8a5f 5 // c-simple-emu-cbm (C Portable Version)
davervw 7:f49fa56672d8 6 // C64/6502 Emulator for Terminal Console
davervw 0:90de1cbc8a5f 7 //
davervw 0:90de1cbc8a5f 8 // MIT License
davervw 0:90de1cbc8a5f 9 //
davervw 7:f49fa56672d8 10 // Copyright(c) 2020 by David R. Van Wagner
davervw 0:90de1cbc8a5f 11 // davevw.com
davervw 0:90de1cbc8a5f 12 //
davervw 0:90de1cbc8a5f 13 // Permission is hereby granted, free of charge, to any person obtaining a copy
davervw 0:90de1cbc8a5f 14 // of this software and associated documentation files (the "Software"), to deal
davervw 0:90de1cbc8a5f 15 // in the Software without restriction, including without limitation the rights
davervw 0:90de1cbc8a5f 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
davervw 0:90de1cbc8a5f 17 // copies of the Software, and to permit persons to whom the Software is
davervw 0:90de1cbc8a5f 18 // furnished to do so, subject to the following conditions:
davervw 0:90de1cbc8a5f 19 //
davervw 0:90de1cbc8a5f 20 // The above copyright notice and this permission notice shall be included in all
davervw 0:90de1cbc8a5f 21 // copies or substantial portions of the Software.
davervw 0:90de1cbc8a5f 22 //
davervw 0:90de1cbc8a5f 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
davervw 0:90de1cbc8a5f 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
davervw 0:90de1cbc8a5f 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
davervw 0:90de1cbc8a5f 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
davervw 0:90de1cbc8a5f 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
davervw 0:90de1cbc8a5f 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
davervw 0:90de1cbc8a5f 29 // SOFTWARE.
davervw 0:90de1cbc8a5f 30 //
davervw 0:90de1cbc8a5f 31 ////////////////////////////////////////////////////////////////////////////////
davervw 0:90de1cbc8a5f 32
davervw 0:90de1cbc8a5f 33 #include <mbed.h>
davervw 0:90de1cbc8a5f 34 #include "cbmconsole.h"
davervw 0:90de1cbc8a5f 35
davervw 0:90de1cbc8a5f 36 // locals
davervw 0:90de1cbc8a5f 37 static int supress_first_clear = 1;
davervw 0:90de1cbc8a5f 38 static int supress_next_cr = 0;
davervw 0:90de1cbc8a5f 39 static char buffer[256];
davervw 0:90de1cbc8a5f 40 static int buffer_head = 0;
davervw 0:90de1cbc8a5f 41 static int buffer_tail = 0;
davervw 0:90de1cbc8a5f 42 static int buffer_count = 0;
davervw 0:90de1cbc8a5f 43
davervw 0:90de1cbc8a5f 44 // global references
davervw 0:90de1cbc8a5f 45 extern Serial pc;
davervw 0:90de1cbc8a5f 46
davervw 0:90de1cbc8a5f 47 static void Console_Clear()
davervw 0:90de1cbc8a5f 48 {
davervw 0:90de1cbc8a5f 49 if (supress_first_clear)
davervw 0:90de1cbc8a5f 50 {
davervw 0:90de1cbc8a5f 51 supress_first_clear = 0;
davervw 0:90de1cbc8a5f 52 return;
davervw 0:90de1cbc8a5f 53 }
davervw 0:90de1cbc8a5f 54 pc.printf("\x1B[2J\x1B[H");
davervw 0:90de1cbc8a5f 55 }
davervw 0:90de1cbc8a5f 56
davervw 0:90de1cbc8a5f 57 static void Console_Cursor_Up()
davervw 0:90de1cbc8a5f 58 {
davervw 0:90de1cbc8a5f 59 pc.printf("\x1B[A");
davervw 0:90de1cbc8a5f 60 }
davervw 0:90de1cbc8a5f 61
davervw 0:90de1cbc8a5f 62 static void Console_Cursor_Down()
davervw 0:90de1cbc8a5f 63 {
davervw 0:90de1cbc8a5f 64 pc.printf("\x1B[B");
davervw 0:90de1cbc8a5f 65 }
davervw 0:90de1cbc8a5f 66
davervw 0:90de1cbc8a5f 67 static void Console_Cursor_Left()
davervw 0:90de1cbc8a5f 68 {
davervw 0:90de1cbc8a5f 69 pc.printf("\x1B[D");
davervw 0:90de1cbc8a5f 70 }
davervw 0:90de1cbc8a5f 71
davervw 0:90de1cbc8a5f 72 static void Console_Cursor_Right()
davervw 0:90de1cbc8a5f 73 {
davervw 0:90de1cbc8a5f 74 pc.printf("\x1B[C");
davervw 0:90de1cbc8a5f 75 }
davervw 0:90de1cbc8a5f 76
davervw 0:90de1cbc8a5f 77 static void Console_Cursor_Home()
davervw 0:90de1cbc8a5f 78 {
davervw 0:90de1cbc8a5f 79 pc.printf("\x1B[H");
davervw 0:90de1cbc8a5f 80 }
davervw 0:90de1cbc8a5f 81
davervw 0:90de1cbc8a5f 82 void CBM_Console_WriteChar(unsigned char c)
davervw 0:90de1cbc8a5f 83 {
davervw 0:90de1cbc8a5f 84 // we're emulating, so draw character on local console window
davervw 0:90de1cbc8a5f 85 if (c == 0x0D)
davervw 0:90de1cbc8a5f 86 {
davervw 0:90de1cbc8a5f 87 if (supress_next_cr)
davervw 0:90de1cbc8a5f 88 supress_next_cr = 0;
davervw 0:90de1cbc8a5f 89 else
davervw 0:90de1cbc8a5f 90 pc.putc('\n');
davervw 0:90de1cbc8a5f 91 }
davervw 0:90de1cbc8a5f 92 else if (c >= ' ' && c <= '~')
davervw 0:90de1cbc8a5f 93 {
davervw 0:90de1cbc8a5f 94 //ApplyColor ? .Invoke();
davervw 0:90de1cbc8a5f 95 pc.putc(c);
davervw 0:90de1cbc8a5f 96 }
davervw 0:90de1cbc8a5f 97 else if (c == 157) // left
davervw 0:90de1cbc8a5f 98 Console_Cursor_Left();
davervw 0:90de1cbc8a5f 99 else if (c == 29) // right
davervw 0:90de1cbc8a5f 100 Console_Cursor_Right();
davervw 0:90de1cbc8a5f 101 else if (c == 145) // up
davervw 0:90de1cbc8a5f 102 Console_Cursor_Up();
davervw 0:90de1cbc8a5f 103 else if (c == 17) // down
davervw 0:90de1cbc8a5f 104 Console_Cursor_Down();
davervw 0:90de1cbc8a5f 105 else if (c == 19) // home
davervw 0:90de1cbc8a5f 106 Console_Cursor_Home();
davervw 0:90de1cbc8a5f 107 else if (c == 147)
davervw 0:90de1cbc8a5f 108 {
davervw 0:90de1cbc8a5f 109 Console_Clear();
davervw 0:90de1cbc8a5f 110 }
davervw 0:90de1cbc8a5f 111 }
davervw 0:90de1cbc8a5f 112
davervw 0:90de1cbc8a5f 113 // blocking read to get next typed character
davervw 0:90de1cbc8a5f 114 unsigned char CBM_Console_ReadChar(void)
davervw 0:90de1cbc8a5f 115 {
davervw 0:90de1cbc8a5f 116 unsigned char c;
davervw 0:90de1cbc8a5f 117 if (buffer_count == 0)
davervw 0:90de1cbc8a5f 118 {
davervw 4:0461c100cbbb 119 while (true)
davervw 4:0461c100cbbb 120 {
davervw 4:0461c100cbbb 121 int i = pc.getc();
davervw 4:0461c100cbbb 122 if (i == -1) // no character available
davervw 4:0461c100cbbb 123 {
davervw 4:0461c100cbbb 124 wait(20); // be nice to cpu
davervw 4:0461c100cbbb 125 }
davervw 4:0461c100cbbb 126 else
davervw 4:0461c100cbbb 127 {
davervw 4:0461c100cbbb 128 c = (unsigned char)i;
davervw 4:0461c100cbbb 129 if (c == '\n')
davervw 4:0461c100cbbb 130 c = '\r';
davervw 4:0461c100cbbb 131 break;
davervw 4:0461c100cbbb 132 }
davervw 4:0461c100cbbb 133 }
davervw 0:90de1cbc8a5f 134 // if (c >= ' ' && c <= '~')
davervw 0:90de1cbc8a5f 135 // pc.putc(c); // echo
davervw 0:90de1cbc8a5f 136 if (c == '\r')
davervw 0:90de1cbc8a5f 137 supress_next_cr = true;
davervw 0:90de1cbc8a5f 138 return c;
davervw 0:90de1cbc8a5f 139 }
davervw 0:90de1cbc8a5f 140 c = buffer[buffer_head++];
davervw 0:90de1cbc8a5f 141 if (buffer_head >= sizeof(buffer))
davervw 0:90de1cbc8a5f 142 buffer_head = 0;
davervw 0:90de1cbc8a5f 143 --buffer_count;
davervw 0:90de1cbc8a5f 144 return c;
davervw 0:90de1cbc8a5f 145 }
davervw 0:90de1cbc8a5f 146
davervw 0:90de1cbc8a5f 147 void CBM_Console_Push(const char* s)
davervw 0:90de1cbc8a5f 148 {
davervw 0:90de1cbc8a5f 149 while (s != 0 && *s != 0 && buffer_count < sizeof(buffer))
davervw 0:90de1cbc8a5f 150 {
davervw 0:90de1cbc8a5f 151 buffer[buffer_tail++] = *(s++);
davervw 0:90de1cbc8a5f 152 if (buffer_tail >= sizeof(buffer))
davervw 0:90de1cbc8a5f 153 buffer_tail = 0;
davervw 0:90de1cbc8a5f 154 ++buffer_count;
davervw 0:90de1cbc8a5f 155 }
davervw 0:90de1cbc8a5f 156 }