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


Ignore:
Files:
5 added
8 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r40b2112 r7b50125  
    11bios.abs
     2bios.elf
    23midas.abs
     4midas.elf
    35
    4 build
     6build/*
    57buchla
     8buchla.exe
    69mkdisk
     10mkdisk.exe
    711
    812buchla.disk
  • Makefile

    r40b2112 r7b50125  
    44GCC :=                  gcc
    55SDL2 :=                 /opt/sdl2
     6EXT :=
    67else
    78GCC :=                  x86_64-w64-mingw32-gcc
    89SDL2 :=                 /opt/sdl2-win
     10EXT :=                  .exe
    911endif
    1012
     
    3234FLAGS_LNK :=    $(FLAGS) -pthread -Wall -Wextra
    3335LIBS :=                 $(SDL2_LIB)/libSDL2.a \
     36                                $(SDL2_LIB)/libSDL2_net.a \
    3437                                $(SDL2_LIB)/libSDL2_ttf.a \
    3538                                $(SDL2_LIB)/libfreetype.a \
     
    4144FLAGS_LNK :=    $(FLAGS) -Wall -Wextra
    4245LIBS :=                 $(SDL2_LIB)/libSDL2.a \
     46                                $(SDL2_LIB)/libSDL2_net.a \
    4347                                $(SDL2_LIB)/libSDL2_ttf.a \
    4448                                $(SDL2_LIB)/libfreetype.a \
     
    6064                                $(SDL2_LIB)/libSDL2.a \
    6165                                $(SDL2_LIB)/libSDL2main.a \
     66                                $(SDL2_LIB)/libSDL2_net.a \
    6267                                $(SDL2_LIB)/libSDL2_ttf.a \
    6368                                $(SDL2_LIB)/libfreetype.a \
    6469                                -l gdi32 \
    6570                                -l imm32 \
     71                                -l iphlpapi \
    6672                                -l ole32 \
    6773                                -l oleaut32 \
    6874                                -l version \
    69                                 -l winmm
     75                                -l winmm \
     76                                -l ws2_32
    7077endif
    7178
    7279HEADERS :=              $(wildcard cpu/*.h) $(wildcard emu/*.h)
    7380
    74 all:                    buchla buchla.disk
     81all:                    buchla$(EXT) buchla.disk
    7582
    76 build:
    77                                 mkdir build
    78 
    79 build/gen:              | build
     83build/gen:
    8084                                gcc $(FLAGS) -o build/gen cpu/m68kmake.c
    8185
     
    9094
    9195$(GEN_CP) $(GEN_HP): \
    92                                 build/gen | build
     96                                build/gen
    9397                                cd cpu; ../build/gen ../build
    9498
     
    100104CPU_OP :=               $(CPU_O:%=build/%)
    101105
    102 build/%.o:              cpu/%.c $(HEADERS) $(GEN_HP) | build
     106build/%.o:              cpu/%.c $(HEADERS) $(GEN_HP)
    103107                                $(GCC) $(FLAGS_CPU) -c -o $@ $<
    104108
    105109EMU_C :=                main.c cpu.c vid.c fpu.c tim.c lcd.c ser.c mid.c fdd.c snd.c \
    106                                 led.c kbd.c sdl.c
     110                                led.c kbd.c sdl.c gdb.c
    107111EMU_O :=                $(EMU_C:.c=.o)
    108112EMU_OP :=               $(EMU_O:%=build/%)
    109113
    110 build/%.o:              emu/%.c $(HEADERS) | build
     114build/%.o:              emu/%.c $(HEADERS)
    111115                                $(GCC) $(FLAGS_EMU) -c -o $@ $<
    112116
    113 buchla:                 $(CPU_OP) $(GEN_OP)     $(EMU_OP)
    114                                 $(GCC) $(FLAGS_LNK) -o buchla \
     117buchla$(EXT):   $(CPU_OP) $(GEN_OP)     $(EMU_OP)
     118                                $(GCC) $(FLAGS_LNK) -o buchla$(EXT) \
    115119                                $(CPU_OP) $(GEN_OP) $(EMU_OP) \
    116120                                $(LIBS)
    117121
    118 mkdisk:                 emu/mkdisk.c
    119                                 $(GCC) $(FLAGS_AUX) -o mkdisk emu/mkdisk.c
     122mkdisk$(EXT):   emu/mkdisk.c
     123                                $(GCC) $(FLAGS_AUX) -o mkdisk$(EXT) emu/mkdisk.c
    120124
    121 buchla.disk:    mkdisk midas.abs
    122                                 ./mkdisk
     125buchla.disk:    mkdisk$(EXT) midas.abs
     126                                ./mkdisk$(EXT)
    123127
    124 run:                    buchla buchla.disk
    125                                 ./buchla
     128run:                    buchla$(EXT) buchla.disk
     129                                ./buchla$(EXT) ${EMU_OPTS}
    126130
    127 val:                    buchla buchla.disk
     131val:                    buchla$(EXT) buchla.disk
    128132                                valgrind --leak-resolution=high --track-fds=yes --leak-check=full \
    129                                 --show-reachable=yes --suppressions=misc/buchla.supp ./buchla
     133                                --show-reachable=yes --suppressions=misc/buchla.supp \
     134                                ./buchla$(EXT) ${EMU_OPTS}
    130135
    131136clean:
    132                                 rm -rf build
    133                                 rm -f buchla
    134                                 rm -f mkdisk
     137                                rm -f build/gen build/*.c build/*.h build/*.o
     138                                rm -f buchla$(EXT)
     139                                rm -f mkdisk$(EXT)
    135140                                rm -f buchla.disk
  • emu/all.h

    r40b2112 r7b50125  
    2828
    2929#include <SDL2/SDL.h>
     30#include <SDL2/SDL_net.h>
    3031#include <SDL2/SDL_ttf.h>
    3132
     
    4748
    4849extern int32_t sdl_verbose;
     50extern int32_t gdb_verbose;
    4951extern int32_t cpu_verbose;
    5052extern int32_t fpu_verbose;
     
    6163extern const char *bios;
    6264extern const char *disk;
     65extern const char *font;
     66
     67extern SDL_atomic_t run;
    6368
    6469extern void sdl_init(void);
    6570extern void sdl_quit(void);
     71extern void sdl_loop(void);
    6672
     73extern void gdb_init(void);
     74extern void gdb_quit(void);
     75extern void gdb_loop(void);
     76extern void gdb_inst(bool bp);
     77
     78extern SDL_mutex *cpu_mutex;
     79
     80extern void cpu_init(void);
     81extern void cpu_quit(void);
    6782extern void cpu_loop(void);
     83
     84extern uint8_t cpu_peek(int32_t addr);
     85extern void cpu_poke(int32_t addr, uint8_t val);
    6886
    6987extern void fpu_init(void);
     
    97115extern void ser_write(uint32_t off, int32_t sz, uint32_t val);
    98116
     117extern void ser_sdl(void);
    99118extern void ser_text(SDL_TextInputEvent *ev);
    100119extern void ser_key(SDL_KeyboardEvent *ev);
  • emu/cpu.c

    r40b2112 r7b50125  
    5252} hw_t;
    5353
     54static uint64_t freq;
     55static uint64_t quan;
     56
     57SDL_mutex *cpu_mutex;
     58
    5459static bool reset = true;
    5560
     
    6974static hw_t hw_map[] = {
    7075        { 0x180000, 0x200000, 0, fpu_init, fpu_quit, fpu_exec, fpu_read, fpu_write },
    71         { 0x200000, 0x280000, 0, vid_init, vid_quit, vid_exec, vid_read, vid_write },
     76        { 0x200000, 0x280002, 0, vid_init, vid_quit, vid_exec, vid_read, vid_write },
    7277        { 0x3a0001, 0x3a4001, 4, tim_init, tim_quit, tim_exec, tim_read, tim_write },
    7378        { 0x3a4001, 0x3a8001, 0, lcd_init, lcd_quit, lcd_exec, lcd_read, lcd_write },
     
    379384        }
    380385
    381         // handle loading midas.abs
     386        // once midas.abs gets loaded, activate RAM
    382387
    383388        if (addr == APP_START) {
     389                ram_data[addr] = (uint8_t)val;
    384390                ram_rw_beg = APP_START;
    385391                ram_rw_end = RAM_START + RAM_SIZE;
     
    462468}
    463469
     470uint8_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
     483void 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
    464494static void inst_cb(void)
    465495{
    466496        uint32_t pc = m68k_get_reg(NULL, M68K_REG_PC);
    467497        uint32_t op = m68k_read_memory_16(pc);
     498
     499        gdb_inst(op == 0x4e4f);
    468500
    469501        if (op == 0x4e4d) {
     
    619651}
    620652
    621 void cpu_loop(void)
    622 {
     653void 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
    623666        hw_init();
    624667        bios_init();
    625668
    626         inf("entering CPU loop");
    627669        m68k_init();
    628670        m68k_set_cpu_type(M68K_CPU_TYPE_68000);
    629671        m68k_set_instr_hook_callback(inst_cb);
    630672        m68k_pulse_reset();
    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) {
     673}
     674
     675void cpu_quit(void)
     676{
     677        hw_quit();
     678        SDL_DestroyMutex(cpu_mutex);
     679}
     680
     681void cpu_loop(void)
     682{
     683        inf("entering CPU loop");
     684        int32_t count = 0;
     685
     686        while (SDL_AtomicGet(&run) != 0) {
    643687                uint64_t until = SDL_GetPerformanceCounter() + quan;
     688
     689                if (SDL_LockMutex(cpu_mutex) < 0) {
     690                        fail("SDL_LockMutex() failed: %s", SDL_GetError());
     691                }
    644692
    645693                m68k_execute(CPU_FREQ / PER_SEC);
     
    652700                m68k_set_irq(irq);
    653701
    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;
     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);
     708                }
     709
     710                while (SDL_GetPerformanceCounter() < until) {
     711                        for (int32_t i = 0; i < 100; ++i) {
     712                                _mm_pause();
    666713                        }
    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                         }
    687                 }
    688 
    689                 while (SDL_GetPerformanceCounter() < until) {
    690                         _mm_pause();
    691714                }
    692715        }
    693716
    694717        inf("leaving CPU loop");
    695         hw_quit();
    696 }
     718}
  • emu/main.c

    r40b2112 r7b50125  
    2525static verb_flag_t verb_flags[] = {
    2626        { "sdl", &sdl_verbose },
     27        { "gdb", &gdb_verbose },
    2728        { "cpu", &cpu_verbose },
    2829        { "fpu", &fpu_verbose },
     
    4041const char *bios = "bios.abs";
    4142const char *disk = "buchla.disk";
     43const char *font = "ttf/vera-sans-mono.ttf";
     44
     45SDL_atomic_t run;
    4246
    4347static void usage(FILE *fh)
    4448{
    45         fprintf(fh, "usage: buchla [-h] [-v comp [-v comp [...]]] [-b bios] [-d disk]\n");
     49        fprintf(fh, "usage: buchla [-h] [-v comp [-v comp [...]]] [-b bios] [-d disk] [-f font]\n");
    4650        fprintf(fh, "where comp is one of: ");
    4751
     
    8387                }
    8488
     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
    85100                if (strcmp(argv[i], "-v") == 0) {
    86101                        if (++i == argc) {
     
    118133}
    119134
     135static int32_t cpu_thread(void *data)
     136{
     137        (void)data;
     138
     139        cpu_loop();
     140        return 0;
     141}
     142
     143static int32_t gdb_thread(void *data)
     144{
     145        (void)data;
     146
     147        gdb_loop();
     148        return 0;
     149}
     150
    120151int32_t main(int32_t argc, char *argv[])
    121152{
    122153        parse_args(argc, argv);
    123154        sdl_init();
     155        gdb_init();
     156        cpu_init();
    124157
    125         cpu_loop();
     158        SDL_AtomicSet(&run, 1);
     159        SDL_Thread *thr_cpu = SDL_CreateThread(cpu_thread, "cpu", NULL);
    126160
     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();
    127178        sdl_quit();
    128179        return 0;
  • emu/sdl.c

    r40b2112 r7b50125  
    1818#include <all.h>
    1919
    20 int32_t sdl_verbose = false;
     20int32_t sdl_verbose = 0;
    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
     26typedef void (*sdl_func_t)(void);
     27
     28static sdl_func_t sdl_funcs[] = {
     29        ser_sdl
     30};
    2531
    2632void sdl_init(void)
     
    3238
    3339        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        }
    3444
    3545        if (TTF_Init() < 0) {
     
    4454{
    4555        TTF_Quit();
     56        SDLNet_Quit();
    4657        SDL_Quit();
    4758}
     59
     60void 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

    r40b2112 r7b50125  
    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 
    4139#define REG_IER_ISR 0
    4240#define REG_CFR_SR  1
     
    6058static SDL_Window *win;
    6159static SDL_Renderer *ren;
     60static SDL_atomic_t frame;
    6261
    6362static TTF_Font *fon;
     
    7069static int32_t bel = 0;
    7170
    72 static void update(void)
    73 {
     71static 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
     77static 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
     94static 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
     109static void down(void)
     110{
     111        if (cur_y < CON_H - 1) {
     112                ++cur_y;
     113                return;
     114        }
     115
     116        scroll();
     117}
     118
     119static 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
     153static 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
     168void 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
    74182        if (SDL_FillRect(sur, NULL, bel == 0 ? CON_BGR : CON_BEL) < 0) {
    75183                fail("SDL_FillRect() failed: %s", SDL_GetError());
     
    86194
    87195        for (int32_t y = 0; y < CON_H; ++y) {
    88                 SDL_Surface *lin = TTF_RenderText_Blended(fon, (char *)mem[y], CON_FGR);
     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);
    89209
    90210                if (lin == NULL) {
     
    118238}
    119239
    120 static 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 
    126 static 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 
    143 static 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 
    158 static void down(void)
    159 {
    160         if (cur_y < CON_H - 1) {
    161                 ++cur_y;
    162                 return;
    163         }
    164 
    165         scroll();
    166 }
    167 
    168 static 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 
    202 static 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 
    209240void ser_key(SDL_KeyboardEvent *ev)
    210241{
     
    252283        }
    253284
    254         SDL_RWops *ops = SDL_RWFromFile(CON_FONT, "rb");
     285        SDL_AtomicSet(&frame, 1);
     286
     287        SDL_RWops *ops = SDL_RWFromFile(font, "rb");
    255288
    256289        if (ops == NULL) {
    257                 fail("error while opening font file " CON_FONT ": %s", SDL_GetError());
     290                fail("error while opening font file %s: %s", font, SDL_GetError());
    258291        }
    259292
     
    261294
    262295        if (fon == NULL) {
    263                 fail("error while loading font file " CON_FONT ": %s", TTF_GetError());
     296                fail("error while loading font file %s: %s", font, TTF_GetError());
    264297        }
    265298
     
    286319                mem[y][CON_W] = 0;
    287320        }
    288 
    289         update();
    290321}
    291322
     
    309340
    310341                if (bel == BEL_CYC - 1 || bel == 0) {
    311                         update();
     342                        SDL_AtomicAdd(&frame, 1);
    312343                }
    313344        }
  • readme.txt

    r40b2112 r7b50125  
    2626  https://libsdl.org/
    2727
    28 The SDL2 website also hosts the SDL2_ttf project, which adds support
    29 for TrueType fonts to SDL2. SDL2_ttf, in turn, requires the FreeType
    30 library, which is available from the FreeType website:
     28The SDL2 website also hosts the SDL2_net and SDL2_ttf projects, which
     29add support for networking and TrueType fonts to SDL2
     30
     31SDL2_ttf, in turn, requires the FreeType library, which is available
     32from the FreeType website:
    3133
    3234  https://www.freetype.org/
     
    6769  make install
    6870
    69   # Build and install SDL2_ttf last
     71  # Build and install SDL2_ttf, now that we have FreeType and SDL2
    7072
    7173  tar zxvf SDL2_ttf-2.0.14.tar.gz
     
    7678  ../configure --prefix=/opt/sdl2 \
    7779    --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
    7892
    7993  make
     
    99113Then, to cross-build the emulator, invoke
    100114
    101   make buchla WIN=1
     115  make buchla.exe WIN=1
    102116
    103117from the top-level directory of this repository. Defining the "WIN"
     
    105119library directory.
    106120
     121In addition to the emulator, we need to build the mkdisk utility,
     122which we'll use to create a 720-KiB floppy disk image that can be read
     123by the Buchla firmware.
     124
     125Building mkdisk works pretty much like building the emulator. On Linux
     126and OS X, invoke
     127
     128  make mkdisk
     129
     130from the top-level directory of this repository. To cross-build the
     131Windows version, invoke
     132
     133  make mkdisk.exe WIN=1
     134
     135instead.
     136
     137
     138Running the emulator
     139--------------------
     140
     141This is where this repository, buchla-emu, meets its companion
     142repository, buchla-68k. We assume that you built the following files
     143according to the instructions in the buchla-68k repository:
     144
     145  bios.abs
     146  midas.abs
     147
     148Please copy (or symlink) them into the top-level directory of this
     149repository, buchla-emu.
     150
     151bios.abs contains the Buchla 700's BIOS code. The file is loaded by
     152the emulator directly to emulate the BIOS PROM.
     153
     154midas.abs is the MIDAS VII software. Unlike the BIOS, which resides in
     155a PROM, it is loaded from a floppy disk. To create this floppy disk,
     156we need the mkdisk utility.
     157
     158mkdisk expects to be run from inside the directory that contains
     159midas.abs and produces a disk image file, buchla.disk in the same
     160directory. 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
     168Now we have everything in place to run the emulator. On Linux and OS X
     169you can invoke it directly from the top-level directory of this
     170repository:
     171
     172  ~/buchla-emu$ ./buchla
     173
     174If you prefer to install the emulator elsewhere, be sure to copy the
     175following 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
     182This also applies to copying the cross-compiled Windows emulator to a
     183Windows machine.
     184
     185If you would like to keep the BIOS code, disk image, and font separate
     186from the emulator executable, check out the emulator's -b, -d, and -f
     187command line options. Use -h for an overview of all available options.
     188
     189
     190Cross-debugging the firmware
     191----------------------------
     192
     193While the emulator is running, it listens on TCP port 12053 for
     194incoming connections from a GDB cross-debugger. This allows for
     195comfortable source-level debugging of the cross-compiled BIOS and
     196MIDAS VII code, while it runs in the emulator.
     197
     198We assume that you have a GCC cross-toolchain in /opt/cross-m68k, as
     199described in the buchla-68k repository. Based on that, we build a
     200GDB 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
     218The Buchla firmware uses its own (Atari-like) object and executable
     219file format. However, the cross-toolchain and the cross-debugger
     220support the ELF standard.
     221
     222When you built the BIOS and MIDAS VII software, you ended up with two
     223files in the Buchla's executable file format, bios.abs and midas.abs.
     224However, the cross-build process also produces matching ELF files,
     225bios.elf and midas.elf, suitable for the cross-debugger.
     226
     227Depending on whether you would like to cross-debug the BIOS or MIDAS
     228VII, you'd specify either bios.elf or midas.elf when invoking the
     229cross-debugger.
     230
     231To follow along the following example, copy (or symlink) bios.elf and
     232midas.elf from the buchla-68k repository into the top-level directory
     233of this repository.
     234
     235In order to open a debug session for the BIOS, run the cross-debugger
     236with bios.abs and connect it to the running emulator using GDB's
     237
     238  target remote :12053
     239
     240command. 12053 is the port on which the emulator listens for incoming
     241GDB 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
     253From 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
     266In order to debug MIDAS VII, run the cross-debugger with midas.elf,
     267instead:
     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  [...]
     273
    107274
    108275Emulated hardware
     
    118285  * Motorola MC6840: Timers.
    119286
    120   * Motorola MC6850: Serial console and MIDI ports.
     287  * Rockwell R65C52: Serial console and MIDI ports.
    121288
    122289  * Epson SED1335: LCD controller.
     
    166333
    167334      2. A second chip for the actual sound generation. This is likely
    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).
    171 
    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).
     335         a DSP.
     336
     337         XXX - Details to be filled in.
    176338
    177339         We don't know how many of the envelopes not related to FM
     
    190352would be great to be able to compare the emulation to real hardware.
    191353
    192 If it's non-functional, this is also fine. We might be able to gain
    193 some insights from reading the FPU microcode PROMs.
     354If your Buchla is non-functional, this is also fine. We might be able
     355to gain some insights from reading out the FPU microcode PROMs.
Note: See TracChangeset for help on using the changeset viewer.