Changes in / [7b50125:40b2112] in buchla-emu


Ignore:
Files:
5 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r7b50125 r40b2112  
    11bios.abs
    2 bios.elf
    32midas.abs
    4 midas.elf
    53
    6 build/*
     4build
    75buchla
    8 buchla.exe
    96mkdisk
    10 mkdisk.exe
    117
    128buchla.disk
  • Makefile

    r7b50125 r40b2112  
    44GCC :=                  gcc
    55SDL2 :=                 /opt/sdl2
    6 EXT :=
    76else
    87GCC :=                  x86_64-w64-mingw32-gcc
    98SDL2 :=                 /opt/sdl2-win
    10 EXT :=                  .exe
    119endif
    1210
     
    3432FLAGS_LNK :=    $(FLAGS) -pthread -Wall -Wextra
    3533LIBS :=                 $(SDL2_LIB)/libSDL2.a \
    36                                 $(SDL2_LIB)/libSDL2_net.a \
    3734                                $(SDL2_LIB)/libSDL2_ttf.a \
    3835                                $(SDL2_LIB)/libfreetype.a \
     
    4441FLAGS_LNK :=    $(FLAGS) -Wall -Wextra
    4542LIBS :=                 $(SDL2_LIB)/libSDL2.a \
    46                                 $(SDL2_LIB)/libSDL2_net.a \
    4743                                $(SDL2_LIB)/libSDL2_ttf.a \
    4844                                $(SDL2_LIB)/libfreetype.a \
     
    6460                                $(SDL2_LIB)/libSDL2.a \
    6561                                $(SDL2_LIB)/libSDL2main.a \
    66                                 $(SDL2_LIB)/libSDL2_net.a \
    6762                                $(SDL2_LIB)/libSDL2_ttf.a \
    6863                                $(SDL2_LIB)/libfreetype.a \
    6964                                -l gdi32 \
    7065                                -l imm32 \
    71                                 -l iphlpapi \
    7266                                -l ole32 \
    7367                                -l oleaut32 \
    7468                                -l version \
    75                                 -l winmm \
    76                                 -l ws2_32
     69                                -l winmm
    7770endif
    7871
    7972HEADERS :=              $(wildcard cpu/*.h) $(wildcard emu/*.h)
    8073
    81 all:                    buchla$(EXT) buchla.disk
     74all:                    buchla buchla.disk
    8275
    83 build/gen:
     76build:
     77                                mkdir build
     78
     79build/gen:              | build
    8480                                gcc $(FLAGS) -o build/gen cpu/m68kmake.c
    8581
     
    9490
    9591$(GEN_CP) $(GEN_HP): \
    96                                 build/gen
     92                                build/gen | build
    9793                                cd cpu; ../build/gen ../build
    9894
     
    104100CPU_OP :=               $(CPU_O:%=build/%)
    105101
    106 build/%.o:              cpu/%.c $(HEADERS) $(GEN_HP)
     102build/%.o:              cpu/%.c $(HEADERS) $(GEN_HP) | build
    107103                                $(GCC) $(FLAGS_CPU) -c -o $@ $<
    108104
    109105EMU_C :=                main.c cpu.c vid.c fpu.c tim.c lcd.c ser.c mid.c fdd.c snd.c \
    110                                 led.c kbd.c sdl.c gdb.c
     106                                led.c kbd.c sdl.c
    111107EMU_O :=                $(EMU_C:.c=.o)
    112108EMU_OP :=               $(EMU_O:%=build/%)
    113109
    114 build/%.o:              emu/%.c $(HEADERS)
     110build/%.o:              emu/%.c $(HEADERS) | build
    115111                                $(GCC) $(FLAGS_EMU) -c -o $@ $<
    116112
    117 buchla$(EXT):   $(CPU_OP) $(GEN_OP)     $(EMU_OP)
    118                                 $(GCC) $(FLAGS_LNK) -o buchla$(EXT) \
     113buchla:                 $(CPU_OP) $(GEN_OP)     $(EMU_OP)
     114                                $(GCC) $(FLAGS_LNK) -o buchla \
    119115                                $(CPU_OP) $(GEN_OP) $(EMU_OP) \
    120116                                $(LIBS)
    121117
    122 mkdisk$(EXT):   emu/mkdisk.c
    123                                 $(GCC) $(FLAGS_AUX) -o mkdisk$(EXT) emu/mkdisk.c
     118mkdisk:                 emu/mkdisk.c
     119                                $(GCC) $(FLAGS_AUX) -o mkdisk emu/mkdisk.c
    124120
    125 buchla.disk:    mkdisk$(EXT) midas.abs
    126                                 ./mkdisk$(EXT)
     121buchla.disk:    mkdisk midas.abs
     122                                ./mkdisk
    127123
    128 run:                    buchla$(EXT) buchla.disk
    129                                 ./buchla$(EXT) ${EMU_OPTS}
     124run:                    buchla buchla.disk
     125                                ./buchla
    130126
    131 val:                    buchla$(EXT) buchla.disk
     127val:                    buchla buchla.disk
    132128                                valgrind --leak-resolution=high --track-fds=yes --leak-check=full \
    133                                 --show-reachable=yes --suppressions=misc/buchla.supp \
    134                                 ./buchla$(EXT) ${EMU_OPTS}
     129                                --show-reachable=yes --suppressions=misc/buchla.supp ./buchla
    135130
    136131clean:
    137                                 rm -f build/gen build/*.c build/*.h build/*.o
    138                                 rm -f buchla$(EXT)
    139                                 rm -f mkdisk$(EXT)
     132                                rm -rf build
     133                                rm -f buchla
     134                                rm -f mkdisk
    140135                                rm -f buchla.disk
  • emu/all.h

    r7b50125 r40b2112  
    2828
    2929#include <SDL2/SDL.h>
    30 #include <SDL2/SDL_net.h>
    3130#include <SDL2/SDL_ttf.h>
    3231
     
    4847
    4948extern int32_t sdl_verbose;
    50 extern int32_t gdb_verbose;
    5149extern int32_t cpu_verbose;
    5250extern int32_t fpu_verbose;
     
    6361extern const char *bios;
    6462extern const char *disk;
    65 extern const char *font;
    66 
    67 extern SDL_atomic_t run;
    6863
    6964extern void sdl_init(void);
    7065extern void sdl_quit(void);
    71 extern void sdl_loop(void);
    7266
    73 extern void gdb_init(void);
    74 extern void gdb_quit(void);
    75 extern void gdb_loop(void);
    76 extern void gdb_inst(bool bp);
    77 
    78 extern SDL_mutex *cpu_mutex;
    79 
    80 extern void cpu_init(void);
    81 extern void cpu_quit(void);
    8267extern void cpu_loop(void);
    83 
    84 extern uint8_t cpu_peek(int32_t addr);
    85 extern void cpu_poke(int32_t addr, uint8_t val);
    8668
    8769extern void fpu_init(void);
     
    11597extern void ser_write(uint32_t off, int32_t sz, uint32_t val);
    11698
    117 extern void ser_sdl(void);
    11899extern void ser_text(SDL_TextInputEvent *ev);
    119100extern void ser_key(SDL_KeyboardEvent *ev);
  • emu/cpu.c

    r7b50125 r40b2112  
    5252} hw_t;
    5353
    54 static uint64_t freq;
    55 static uint64_t quan;
    56 
    57 SDL_mutex *cpu_mutex;
    58 
    5954static bool reset = true;
    6055
     
    7469static hw_t hw_map[] = {
    7570        { 0x180000, 0x200000, 0, fpu_init, fpu_quit, fpu_exec, fpu_read, fpu_write },
    76         { 0x200000, 0x280002, 0, vid_init, vid_quit, vid_exec, vid_read, vid_write },
     71        { 0x200000, 0x280000, 0, vid_init, vid_quit, vid_exec, vid_read, vid_write },
    7772        { 0x3a0001, 0x3a4001, 4, tim_init, tim_quit, tim_exec, tim_read, tim_write },
    7873        { 0x3a4001, 0x3a8001, 0, lcd_init, lcd_quit, lcd_exec, lcd_read, lcd_write },
     
    384379        }
    385380
    386         // once midas.abs gets loaded, activate RAM
     381        // handle loading midas.abs
    387382
    388383        if (addr == APP_START) {
    389                 ram_data[addr] = (uint8_t)val;
    390384                ram_rw_beg = APP_START;
    391385                ram_rw_end = RAM_START + RAM_SIZE;
     
    468462}
    469463
    470 uint8_t cpu_peek(int32_t addr)
    471 {
    472         if (addr >= RAM_START && addr <= RAM_START + RAM_SIZE - 1) {
    473                 return ram_data[addr - RAM_START];
    474         }
    475 
    476         if (addr >= ROM_START && addr <= ROM_START + ROM_SIZE - 1) {
    477                 return rom_data[addr - ROM_START];
    478         }
    479 
    480         return 0;
    481 }
    482 
    483 void cpu_poke(int32_t addr, uint8_t val)
    484 {
    485         if (addr >= RAM_START && addr <= RAM_START + RAM_SIZE - 1) {
    486                 ram_data[addr - RAM_START] = val;
    487         }
    488 
    489         if (addr >= ROM_START && addr <= ROM_START + ROM_SIZE - 1) {
    490                 rom_data[addr - ROM_START] = val;
    491         }
    492 }
    493 
    494464static void inst_cb(void)
    495465{
    496466        uint32_t pc = m68k_get_reg(NULL, M68K_REG_PC);
    497467        uint32_t op = m68k_read_memory_16(pc);
    498 
    499         gdb_inst(op == 0x4e4f);
    500468
    501469        if (op == 0x4e4d) {
     
    651619}
    652620
    653 void cpu_init(void)
    654 {
    655         cpu_mutex = SDL_CreateMutex();
    656 
    657         if (cpu_mutex == NULL) {
    658                 fail("SDL_CreateMutex() failed: %s", SDL_GetError());
    659         }
    660 
    661         freq = SDL_GetPerformanceFrequency();
    662         quan = freq / PER_SEC;
    663 
    664         inf("freq %" PRIu64 " quan %" PRIu64, freq, quan);
    665 
     621void cpu_loop(void)
     622{
    666623        hw_init();
    667624        bios_init();
    668625
     626        inf("entering CPU loop");
    669627        m68k_init();
    670628        m68k_set_cpu_type(M68K_CPU_TYPE_68000);
    671629        m68k_set_instr_hook_callback(inst_cb);
    672630        m68k_pulse_reset();
    673 }
    674 
    675 void cpu_quit(void)
    676 {
    677         hw_quit();
    678         SDL_DestroyMutex(cpu_mutex);
    679 }
    680 
    681 void cpu_loop(void)
    682 {
    683         inf("entering CPU loop");
    684         int32_t count = 0;
    685 
    686         while (SDL_AtomicGet(&run) != 0) {
     631
     632        uint64_t freq = SDL_GetPerformanceFrequency();
     633        uint64_t quan = freq / PER_SEC;
     634        inf("freq %" PRIu64 " quan %" PRIu64, freq, quan);
     635
     636        bool run = true;
     637
     638#if defined EMU_LINUX
     639        SDL_Scancode down = SDL_SCANCODE_UNKNOWN;
     640#endif
     641
     642        while (run) {
    687643                uint64_t until = SDL_GetPerformanceCounter() + quan;
    688 
    689                 if (SDL_LockMutex(cpu_mutex) < 0) {
    690                         fail("SDL_LockMutex() failed: %s", SDL_GetError());
    691                 }
    692644
    693645                m68k_execute(CPU_FREQ / PER_SEC);
     
    700652                m68k_set_irq(irq);
    701653
    702                 if (SDL_UnlockMutex(cpu_mutex) < 0) {
    703                         fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
    704                 }
    705 
    706                 if ((++count & 0x1ff) == 0) {
    707                         SDL_Delay(0);
     654                SDL_Event ev;
     655
     656                while (SDL_PollEvent(&ev) > 0) {
     657#if defined EMU_LINUX
     658                        // Work around duplicate key-down events on Linux.
     659
     660                        if (ev.type == SDL_KEYDOWN) {
     661                                if (down == ev.key.keysym.scancode) {
     662                                        continue;
     663                                }
     664
     665                                down = ev.key.keysym.scancode;
     666                        }
     667                        else if (ev.type == SDL_KEYUP) {
     668                                down = SDL_SCANCODE_UNKNOWN;
     669                        }
     670#endif
     671
     672                        if (ev.type == SDL_QUIT ||
     673                                        (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE)) {
     674                                run = false;
     675                                continue;
     676                        }
     677
     678                        if (ev.type == SDL_TEXTINPUT) {
     679                                ser_text(&ev.text);
     680                                continue;
     681                        }
     682
     683                        if (ev.type == SDL_KEYDOWN) {
     684                                ser_key(&ev.key);
     685                                continue;
     686                        }
    708687                }
    709688
    710689                while (SDL_GetPerformanceCounter() < until) {
    711                         for (int32_t i = 0; i < 100; ++i) {
    712                                 _mm_pause();
    713                         }
     690                        _mm_pause();
    714691                }
    715692        }
    716693
    717694        inf("leaving CPU loop");
    718 }
     695        hw_quit();
     696}
  • emu/main.c

    r7b50125 r40b2112  
    2525static verb_flag_t verb_flags[] = {
    2626        { "sdl", &sdl_verbose },
    27         { "gdb", &gdb_verbose },
    2827        { "cpu", &cpu_verbose },
    2928        { "fpu", &fpu_verbose },
     
    4140const char *bios = "bios.abs";
    4241const char *disk = "buchla.disk";
    43 const char *font = "ttf/vera-sans-mono.ttf";
    44 
    45 SDL_atomic_t run;
    4642
    4743static void usage(FILE *fh)
    4844{
    49         fprintf(fh, "usage: buchla [-h] [-v comp [-v comp [...]]] [-b bios] [-d disk] [-f font]\n");
     45        fprintf(fh, "usage: buchla [-h] [-v comp [-v comp [...]]] [-b bios] [-d disk]\n");
    5046        fprintf(fh, "where comp is one of: ");
    5147
     
    8783                }
    8884
    89                 if (strcmp(argv[i], "-f") == 0) {
    90                         if (++i == argc) {
    91                                 usage(stderr);
    92                                 fprintf(stderr, "missing argument to -f\n");
    93                                 exit(1);
    94                         }
    95 
    96                         font = argv[i];
    97                         continue;
    98                 }
    99 
    10085                if (strcmp(argv[i], "-v") == 0) {
    10186                        if (++i == argc) {
     
    133118}
    134119
    135 static int32_t cpu_thread(void *data)
    136 {
    137         (void)data;
    138 
    139         cpu_loop();
    140         return 0;
    141 }
    142 
    143 static int32_t gdb_thread(void *data)
    144 {
    145         (void)data;
    146 
    147         gdb_loop();
    148         return 0;
    149 }
    150 
    151120int32_t main(int32_t argc, char *argv[])
    152121{
    153122        parse_args(argc, argv);
    154123        sdl_init();
    155         gdb_init();
    156         cpu_init();
    157124
    158         SDL_AtomicSet(&run, 1);
    159         SDL_Thread *thr_cpu = SDL_CreateThread(cpu_thread, "cpu", NULL);
     125        cpu_loop();
    160126
    161         if (thr_cpu == NULL) {
    162                 fail("SDL_CreateThread() failed: %s", SDL_GetError());
    163         }
    164 
    165         SDL_Thread *thr_gdb = SDL_CreateThread(gdb_thread, "gdb", NULL);
    166 
    167         if (thr_gdb == NULL) {
    168                 fail("SDL_CreateThread() failed: %s", SDL_GetError());
    169         }
    170 
    171         sdl_loop();
    172 
    173         SDL_WaitThread(thr_cpu, NULL);
    174         SDL_WaitThread(thr_gdb, NULL);
    175 
    176         cpu_quit();
    177         gdb_quit();
    178127        sdl_quit();
    179128        return 0;
  • emu/sdl.c

    r7b50125 r40b2112  
    1818#include <all.h>
    1919
    20 int32_t sdl_verbose = 0;
     20int32_t sdl_verbose = false;
    2121
    2222#define ver(...) _ver(sdl_verbose, 0, __VA_ARGS__)
    2323#define ver2(...) _ver(sdl_verbose, 1, __VA_ARGS__)
    2424#define ver3(...) _ver(sdl_verbose, 2, __VA_ARGS__)
    25 
    26 typedef void (*sdl_func_t)(void);
    27 
    28 static sdl_func_t sdl_funcs[] = {
    29         ser_sdl
    30 };
    3125
    3226void sdl_init(void)
     
    3832
    3933        SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_VERBOSE);
    40 
    41         if (SDLNet_Init() < 0) {
    42                 fail("SDLNet_Init() failed: %s", SDLNet_GetError());
    43         }
    4434
    4535        if (TTF_Init() < 0) {
     
    5444{
    5545        TTF_Quit();
    56         SDLNet_Quit();
    5746        SDL_Quit();
    5847}
    59 
    60 void sdl_loop(void)
    61 {
    62         inf("entering SDL loop");
    63 
    64 #if defined EMU_LINUX
    65         SDL_Scancode down = SDL_SCANCODE_UNKNOWN;
    66 #endif
    67 
    68         while (SDL_AtomicGet(&run) != 0) {
    69                 for (int32_t i = 0; i < ARRAY_COUNT(sdl_funcs); ++i) {
    70                         sdl_funcs[i]();
    71                 }
    72 
    73                 SDL_Event ev;
    74 
    75                 while (SDL_PollEvent(&ev) > 0) {
    76 #if defined EMU_LINUX
    77                         // Work around duplicate key-down events on Linux.
    78 
    79                         if (ev.type == SDL_KEYDOWN) {
    80                                 if (down == ev.key.keysym.scancode) {
    81                                         continue;
    82                                 }
    83 
    84                                 down = ev.key.keysym.scancode;
    85                         }
    86                         else if (ev.type == SDL_KEYUP) {
    87                                 down = SDL_SCANCODE_UNKNOWN;
    88                         }
    89 #endif
    90 
    91                         if (ev.type == SDL_QUIT ||
    92                                         (ev.type == SDL_KEYDOWN && ev.key.keysym.sym == SDLK_ESCAPE)) {
    93                                 ver("quit");
    94                                 SDL_AtomicSet(&run, 0);
    95                                 continue;
    96                         }
    97 
    98                         if (ev.type == SDL_TEXTINPUT) {
    99                                 ser_text(&ev.text);
    100                                 continue;
    101                         }
    102 
    103                         if (ev.type == SDL_KEYDOWN) {
    104                                 ser_key(&ev.key);
    105                                 continue;
    106                         }
    107 
    108                         SDL_Delay(50);
    109                 }
    110         }
    111 
    112         inf("leaving SDL loop");
    113 }
  • emu/ser.c

    r7b50125 r40b2112  
    3737#define CON_FGR ((SDL_Color){ .r = 255, .b = 255, .g = 255, .a = 255 })
    3838
     39#define CON_FONT "ttf/vera-sans-mono.ttf"
     40
    3941#define REG_IER_ISR 0
    4042#define REG_CFR_SR  1
     
    5860static SDL_Window *win;
    5961static SDL_Renderer *ren;
    60 static SDL_atomic_t frame;
    6162
    6263static TTF_Font *fon;
     
    6970static int32_t bel = 0;
    7071
    71 static void scroll(void)
    72 {
    73         memmove(mem, mem + 1, (CON_H - 1) * (CON_W + 1));
    74         memset(mem + (CON_H - 1), ' ', CON_W);
    75 }
    76 
    77 static void forw(void)
    78 {
    79         if (cur_x < CON_W - 1) {
    80                 ++cur_x;
    81                 return;
    82         }
    83 
    84         if (cur_y == CON_H - 1) {
    85                 cur_x = 0;
    86                 scroll();
    87                 return;
    88         }
    89 
    90         cur_x = 0;
    91         ++cur_y;
    92 }
    93 
    94 static void back(void)
    95 {
    96         if (cur_x > 0) {
    97                 --cur_x;
    98                 return;
    99         }
    100 
    101         if (cur_y == 0) {
    102                 return;
    103         }
    104 
    105         cur_x = CON_W - 1;
    106         --cur_y;
    107 }
    108 
    109 static void down(void)
    110 {
    111         if (cur_y < CON_H - 1) {
    112                 ++cur_y;
    113                 return;
    114         }
    115 
    116         scroll();
    117 }
    118 
    119 static void echo(uint8_t c)
    120 {
    121         if (c < 32) {
    122                 switch (c) {
    123                 case '\r':
    124                         cur_x = 0;
    125                         break;
    126 
    127                 case '\n':
    128                         down();
    129                         break;
    130 
    131                 case '\b':
    132                         back();
    133                         break;
    134 
    135                 case '\a':
    136                         bel = BEL_CYC;
    137                         break;
    138 
    139                 default:
    140                         echo('^');
    141                         echo((uint8_t)(c + '@'));
    142                         return;
    143                 }
    144         }
    145         else {
    146                 mem[cur_y][cur_x] = c;
    147                 forw();
    148         }
    149 
    150         SDL_AtomicAdd(&frame, 1);
    151 }
    152 
    153 static void out(int32_t un, uint8_t c)
    154 {
    155         if (SDL_LockMutex(cpu_mutex) < 0) {
    156                 fail("SDL_LockMutex() failed: %s", SDL_GetError());
    157         }
    158 
    159         state[un].rdr = c;
    160         state[un].rdr_ok = true;
    161         state[un].irq_r = true;
    162 
    163         if (SDL_UnlockMutex(cpu_mutex) < 0) {
    164                 fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
    165         }
    166 }
    167 
    168 void ser_sdl(void)
    169 {
    170         ver3("ser_sdl()");
    171 
    172         static int32_t last = 0;
    173         int32_t now = SDL_AtomicGet(&frame);
    174 
    175         if (last == now) {
    176                 ver3("no update");
    177                 return;
    178         }
    179 
    180         last = now;
    181 
     72static void update(void)
     73{
    18274        if (SDL_FillRect(sur, NULL, bel == 0 ? CON_BGR : CON_BEL) < 0) {
    18375                fail("SDL_FillRect() failed: %s", SDL_GetError());
     
    19486
    19587        for (int32_t y = 0; y < CON_H; ++y) {
    196                 char line[CON_W + 1];
    197 
    198                 if (SDL_LockMutex(cpu_mutex) < 0) {
    199                         fail("SDL_LockMutex() failed: %s", SDL_GetError());
    200                 }
    201 
    202                 memcpy(line, mem[y], CON_W + 1);
    203 
    204                 if (SDL_UnlockMutex(cpu_mutex) < 0) {
    205                         fail("SDL_UnlockMutex() failed: %s", SDL_GetError());
    206                 }
    207 
    208                 SDL_Surface *lin = TTF_RenderText_Blended(fon, line, CON_FGR);
     88                SDL_Surface *lin = TTF_RenderText_Blended(fon, (char *)mem[y], CON_FGR);
    20989
    21090                if (lin == NULL) {
     
    238118}
    239119
     120static void scroll(void)
     121{
     122        memmove(mem, mem + 1, (CON_H - 1) * (CON_W + 1));
     123        memset(mem + (CON_H - 1), ' ', CON_W);
     124}
     125
     126static void forw(void)
     127{
     128        if (cur_x < CON_W - 1) {
     129                ++cur_x;
     130                return;
     131        }
     132
     133        if (cur_y == CON_H - 1) {
     134                cur_x = 0;
     135                scroll();
     136                return;
     137        }
     138
     139        cur_x = 0;
     140        ++cur_y;
     141}
     142
     143static void back(void)
     144{
     145        if (cur_x > 0) {
     146                --cur_x;
     147                return;
     148        }
     149
     150        if (cur_y == 0) {
     151                return;
     152        }
     153
     154        cur_x = CON_W - 1;
     155        --cur_y;
     156}
     157
     158static void down(void)
     159{
     160        if (cur_y < CON_H - 1) {
     161                ++cur_y;
     162                return;
     163        }
     164
     165        scroll();
     166}
     167
     168static void echo(uint8_t c)
     169{
     170        if (c < 32) {
     171                switch (c) {
     172                case '\r':
     173                        cur_x = 0;
     174                        break;
     175
     176                case '\n':
     177                        down();
     178                        break;
     179
     180                case '\b':
     181                        back();
     182                        break;
     183
     184                case '\a':
     185                        bel = BEL_CYC;
     186                        break;
     187
     188                default:
     189                        echo('^');
     190                        echo((uint8_t)(c + '@'));
     191                        return;
     192                }
     193        }
     194        else {
     195                mem[cur_y][cur_x] = c;
     196                forw();
     197        }
     198
     199        update();
     200}
     201
     202static void out(int32_t un, uint8_t c)
     203{
     204        state[un].rdr = c;
     205        state[un].rdr_ok = true;
     206        state[un].irq_r = true;
     207}
     208
    240209void ser_key(SDL_KeyboardEvent *ev)
    241210{
     
    283252        }
    284253
    285         SDL_AtomicSet(&frame, 1);
    286 
    287         SDL_RWops *ops = SDL_RWFromFile(font, "rb");
     254        SDL_RWops *ops = SDL_RWFromFile(CON_FONT, "rb");
    288255
    289256        if (ops == NULL) {
    290                 fail("error while opening font file %s: %s", font, SDL_GetError());
     257                fail("error while opening font file " CON_FONT ": %s", SDL_GetError());
    291258        }
    292259
     
    294261
    295262        if (fon == NULL) {
    296                 fail("error while loading font file %s: %s", font, TTF_GetError());
     263                fail("error while loading font file " CON_FONT ": %s", TTF_GetError());
    297264        }
    298265
     
    319286                mem[y][CON_W] = 0;
    320287        }
     288
     289        update();
    321290}
    322291
     
    340309
    341310                if (bel == BEL_CYC - 1 || bel == 0) {
    342                         SDL_AtomicAdd(&frame, 1);
     311                        update();
    343312                }
    344313        }
  • readme.txt

    r7b50125 r40b2112  
    2626  https://libsdl.org/
    2727
    28 The SDL2 website also hosts the SDL2_net and SDL2_ttf projects, which
    29 add support for networking and TrueType fonts to SDL2
    30 
    31 SDL2_ttf, in turn, requires the FreeType library, which is available
    32 from the FreeType website:
     28The SDL2 website also hosts the SDL2_ttf project, which adds support
     29for TrueType fonts to SDL2. SDL2_ttf, in turn, requires the FreeType
     30library, which is available from the FreeType website:
    3331
    3432  https://www.freetype.org/
     
    6967  make install
    7068
    71   # Build and install SDL2_ttf, now that we have FreeType and SDL2
     69  # Build and install SDL2_ttf last
    7270
    7371  tar zxvf SDL2_ttf-2.0.14.tar.gz
     
    7876  ../configure --prefix=/opt/sdl2 \
    7977    --with-sdl-prefix=/opt/sdl2 --with-freetype-prefix=/opt/sdl2
    80 
    81   make
    82   make install
    83 
    84   # Build and install SDL2_net last
    85 
    86   tar zxvf SDL2_net-2.0.1.tar.gz
    87   cd SDL2_net-2.0.1
    88   mkdir build
    89   cd build
    90 
    91   ../configure --prefix=/opt/sdl2 --with-sdl-prefix=/opt/sdl2
    9278
    9379  make
     
    11399Then, to cross-build the emulator, invoke
    114100
    115   make buchla.exe WIN=1
     101  make buchla WIN=1
    116102
    117103from the top-level directory of this repository. Defining the "WIN"
    118104variable selects the cross-toolchain and "/opt/sdl2-win" as the
    119105library directory.
    120 
    121 In addition to the emulator, we need to build the mkdisk utility,
    122 which we'll use to create a 720-KiB floppy disk image that can be read
    123 by the Buchla firmware.
    124 
    125 Building mkdisk works pretty much like building the emulator. On Linux
    126 and OS X, invoke
    127 
    128   make mkdisk
    129 
    130 from the top-level directory of this repository. To cross-build the
    131 Windows version, invoke
    132 
    133   make mkdisk.exe WIN=1
    134 
    135 instead.
    136 
    137 
    138 Running the emulator
    139 --------------------
    140 
    141 This is where this repository, buchla-emu, meets its companion
    142 repository, buchla-68k. We assume that you built the following files
    143 according to the instructions in the buchla-68k repository:
    144 
    145   bios.abs
    146   midas.abs
    147 
    148 Please copy (or symlink) them into the top-level directory of this
    149 repository, buchla-emu.
    150 
    151 bios.abs contains the Buchla 700's BIOS code. The file is loaded by
    152 the emulator directly to emulate the BIOS PROM.
    153 
    154 midas.abs is the MIDAS VII software. Unlike the BIOS, which resides in
    155 a PROM, it is loaded from a floppy disk. To create this floppy disk,
    156 we need the mkdisk utility.
    157 
    158 mkdisk expects to be run from inside the directory that contains
    159 midas.abs and produces a disk image file, buchla.disk in the same
    160 directory. For example, on Linux:
    161 
    162   ~/buchla-emu$ ls -l midas.abs
    163   lrwxrwxrwx 1 emu emu 23 Jul 30 18:07 midas.abs -> ../buchla-68k/midas.abs
    164   ~/buchla-emu$ ./mkdisk
    165   ~/buchla-emu$ ls -l buchla.disk
    166   -rw-r--r-- 1 emu emu 737280 Aug  6 09:44 buchla.disk
    167 
    168 Now we have everything in place to run the emulator. On Linux and OS X
    169 you can invoke it directly from the top-level directory of this
    170 repository:
    171 
    172   ~/buchla-emu$ ./buchla
    173 
    174 If you prefer to install the emulator elsewhere, be sure to copy the
    175 following files:
    176 
    177   buchla | buchla.exe     emulator executable (.exe for Windows)
    178   ttf/vera-sans-mono.ttf  emulator font
    179   bios.abs                BIOS code
    180   buchla.disk             disk image
    181 
    182 This also applies to copying the cross-compiled Windows emulator to a
    183 Windows machine.
    184 
    185 If you would like to keep the BIOS code, disk image, and font separate
    186 from the emulator executable, check out the emulator's -b, -d, and -f
    187 command line options. Use -h for an overview of all available options.
    188 
    189 
    190 Cross-debugging the firmware
    191 ----------------------------
    192 
    193 While the emulator is running, it listens on TCP port 12053 for
    194 incoming connections from a GDB cross-debugger. This allows for
    195 comfortable source-level debugging of the cross-compiled BIOS and
    196 MIDAS VII code, while it runs in the emulator.
    197 
    198 We assume that you have a GCC cross-toolchain in /opt/cross-m68k, as
    199 described in the buchla-68k repository. Based on that, we build a
    200 GDB cross-debugger:
    201 
    202   # If you haven't yet done so, add the cross-toolchain to your
    203   # PATH, so that the GDB build can find it.
    204 
    205   export PATH="/opt/cross-m68k/bin:${PATH}"
    206 
    207   tar zxvf gdb-7.12.tar.gz
    208   cd gdb-7.12
    209 
    210   mkdir build
    211   cd build
    212 
    213   ../configure --prefix=/opt/cross-m68k --target=m68k-none-elf
    214 
    215   make -j2
    216   make install
    217 
    218 The Buchla firmware uses its own (Atari-like) object and executable
    219 file format. However, the cross-toolchain and the cross-debugger
    220 support the ELF standard.
    221 
    222 When you built the BIOS and MIDAS VII software, you ended up with two
    223 files in the Buchla's executable file format, bios.abs and midas.abs.
    224 However, the cross-build process also produces matching ELF files,
    225 bios.elf and midas.elf, suitable for the cross-debugger.
    226 
    227 Depending on whether you would like to cross-debug the BIOS or MIDAS
    228 VII, you'd specify either bios.elf or midas.elf when invoking the
    229 cross-debugger.
    230 
    231 To follow along the following example, copy (or symlink) bios.elf and
    232 midas.elf from the buchla-68k repository into the top-level directory
    233 of this repository.
    234 
    235 In order to open a debug session for the BIOS, run the cross-debugger
    236 with bios.abs and connect it to the running emulator using GDB's
    237 
    238   target remote :12053
    239 
    240 command. 12053 is the port on which the emulator listens for incoming
    241 GDB connections.
    242 
    243   host:~/buchla-emu$ m68k-none-elf-gdb ./bios.elf
    244   GNU gdb (GDB) 7.12
    245   Copyright (C) 2016 Free Software Foundation, Inc.
    246   [...]
    247   (gdb) target remote :12053
    248   Remote debugging using :12053
    249   trwzsup () at rom/bios.s:832
    250   832           move.l  0(a0,d0),d0     | Get routine address
    251   (gdb)
    252 
    253 From here on, everything is pretty much standard GDB, for example:
    254 
    255   (gdb) break pscan
    256   Breakpoint 1 at 0x105a64: file rom/romp.c, line 3403.
    257   (gdb) cont
    258   [...]
    259   (gdb) bt
    260   #0  pscan () at rom/romp.c:3403
    261   #1  0x00105e96 in main () at rom/romp.c:3587
    262   #2  0x00105fd6 in Croot (cp=0x0) at prolog/croot.c:141
    263   #3  0x00105f52 in start1 () at prolog/fsmain.s:59
    264   (gdb)
    265 
    266 In order to debug MIDAS VII, run the cross-debugger with midas.elf,
    267 instead:
    268 
    269   host:~/buchla-emu$ m68k-none-elf-gdb ./midas.elf
    270   GNU gdb (GDB) 7.12
    271   Copyright (C) 2016 Free Software Foundation, Inc.
    272   [...]
    273106
    274107
     
    285118  * Motorola MC6840: Timers.
    286119
    287   * Rockwell R65C52: Serial console and MIDI ports.
     120  * Motorola MC6850: Serial console and MIDI ports.
    288121
    289122  * Epson SED1335: LCD controller.
     
    333166
    334167      2. A second chip for the actual sound generation. This is likely
    335          a DSP.
     168         a DSP, possibly a Hitachi HD61810, which supports a 16-bit
     169         floating-point format that's also found in the firmware
     170         source code (12-bit mantissa, 4-bit exponent).
    336171
    337          XXX - Details to be filled in.
     172         This chip takes in the current levels of a voice's envelopes
     173         and, based on them, performs the FM synthesis for this voice
     174         by modulating the user-drawn carrier waves A and B according
     175         to the selected FM configuration (algorithm).
    338176
    339177         We don't know how many of the envelopes not related to FM
     
    352190would be great to be able to compare the emulation to real hardware.
    353191
    354 If your Buchla is non-functional, this is also fine. We might be able
    355 to gain some insights from reading out the FPU microcode PROMs.
     192If it's non-functional, this is also fine. We might be able to gain
     193some insights from reading the FPU microcode PROMs.
Note: See TracChangeset for help on using the changeset viewer.