~ubuntu-branches/ubuntu/raring/vice/raring

« back to all changes in this revision

Viewing changes to src/monitor/monitor.c

  • Committer: Bazaar Package Importer
  • Author(s): Laszlo Boszormenyi (GCS)
  • Date: 2009-03-31 00:37:15 UTC
  • mfrom: (1.2.2 upstream)
  • mto: This revision was merged to the branch mainline in revision 17.
  • Revision ID: james.westby@ubuntu.com-20090331003715-mzclchtl0dp7fcl0
Tags: upstream-2.1.dfsg
ImportĀ upstreamĀ versionĀ 2.1.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *  Daniel Sladic <sladic@eecg.toronto.edu>
6
6
 *  Ettore Perazzoli <ettore@comm2000.it>
7
7
 *  Andreas Boose <viceteam@t-online.de>
 
8
 *  Daniel Kahlin <daniel@kahlin.net>
8
9
 *
9
10
 * This file is part of VICE, the Versatile Commodore Emulator.
10
11
 * See README for copyright notice.
37
38
#include <direct.h>
38
39
#endif
39
40
 
 
41
#ifdef HAVE_STRINGS_H
 
42
#include <strings.h>
 
43
#endif
 
44
 
40
45
#include "archdep.h"
41
46
#include "charset.h"
 
47
#include "cmdline.h"
42
48
#include "console.h"
 
49
#include "datasette.h"
43
50
#include "drive.h"
 
51
#include "drivecpu.h"
44
52
#include "interrupt.h"
45
53
#include "ioutil.h"
46
54
#include "kbdbuf.h"
47
55
#include "lib.h"
48
56
#include "log.h"
 
57
#include "machine.h"
 
58
#include "machine-video.h"
 
59
#include "translate.h"
 
60
 
 
61
#ifdef WATCOM_COMPILE
 
62
#include "../mem.h"
 
63
#else
49
64
#include "mem.h"
 
65
#endif
 
66
 
50
67
#include "mon_breakpoint.h"
51
68
#include "mon_disassemble.h"
52
69
#include "mon_memory.h"
56
73
#include "mon_util.h"
57
74
#include "monitor.h"
58
75
#include "montypes.h"
 
76
#include "resources.h"
 
77
#include "screenshot.h"
59
78
#include "signals.h"
60
79
#include "sysfile.h"
61
80
#include "types.h"
 
81
#include "uiapi.h"
62
82
#include "uimon.h"
63
83
#include "vsync.h"
64
84
 
65
85
 
66
86
int mon_stop_output;
67
87
 
 
88
int mon_init_break = -1;
 
89
 
68
90
/* Defines */
69
91
 
70
92
#define MAX_LABEL_LEN 255
75
97
#define OP_RTI 0x40
76
98
#define OP_RTS 0x60
77
99
 
78
 
#define ADDR_LIMIT(x) (LO16(x))
 
100
#define ADDR_LIMIT(x) (addr_mask(x))
79
101
#define BAD_ADDR (new_addr(e_invalid_space, 0))
80
102
 
81
103
#define MONITOR_GET_PC(mem) \
92
114
 
93
115
extern void parse_and_execute_line(char *input);
94
116
 
 
117
monitor_cartridge_commands_t mon_cart_cmd;
 
118
 
95
119
/* Types */
96
120
 
97
121
struct symbol_entry {
143
167
 
144
168
MON_ADDR dot_addr[NUM_MEMSPACES];
145
169
unsigned char data_buf[256];
 
170
unsigned char data_mask_buf[256];
146
171
unsigned int data_buf_len;
147
172
bool asm_mode;
148
173
MON_ADDR asm_mode_addr;
155
180
static bool recording;
156
181
static FILE *recording_fp;
157
182
static char *recording_name;
158
 
bool playback;
159
 
char *playback_name;
160
 
static void playback_commands(const char *filename);
 
183
#define MAX_PLAYBACK 8
 
184
int playback = 0;
 
185
char *playback_name = NULL;
 
186
static void playback_commands(int current_playback);
 
187
static int set_playback_name(const char *param, void *extra_param);
161
188
 
162
189
/* Disassemble the current opcode on entry.  Used for single step.  */
163
190
static int disassemble_on_entry = 0;
198
225
 
199
226
static void set_addr_memspace(MON_ADDR *a, MEMSPACE m)
200
227
{
201
 
    *a = LO16(*a) | LO16_TO_HI16(m);
 
228
    *a = new_addr(m, addr_location(*a));
202
229
}
203
230
 
204
231
bool mon_is_valid_addr(MON_ADDR a)
205
232
{
206
 
    return HI16_TO_LO16(a) != e_invalid_space;
 
233
    return addr_memspace(a) != e_invalid_space;
207
234
}
208
235
 
209
236
bool mon_inc_addr_location(MON_ADDR *a, unsigned inc)
210
237
{
211
 
    unsigned new_loc = LO16(*a) + inc;
212
 
    *a = HI16(*a) | LO16(new_loc);
 
238
    unsigned new_loc = addr_location(*a) + inc;
 
239
    *a = new_addr(addr_memspace(*a), addr_mask(new_loc));
213
240
 
214
 
    return !(new_loc == LO16(new_loc));
 
241
    return !(new_loc == addr_location(new_loc));
215
242
}
216
243
 
217
244
void mon_evaluate_default_addr(MON_ADDR *a)
363
390
        if (!strcasecmp(cpu_type, "z80")) {
364
391
            serchcpu = CPU_Z80;
365
392
        } else {
366
 
            mon_out("Unknown CPU type `%s'\n", cpu_type);
367
 
            return;
 
393
            if (!strcasecmp(cpu_type, "6502dtv")) {
 
394
                serchcpu = CPU_6502DTV;
 
395
            } else {
 
396
                mon_out("Unknown CPU type `%s'\n", cpu_type);
 
397
                return;
 
398
            }
368
399
        }
369
400
    }
370
401
 
503
534
 
504
535
void mon_add_number_to_buffer(int number)
505
536
{
 
537
    unsigned int i = data_buf_len;
506
538
    data_buf[data_buf_len++] = (number & 0xff);
507
539
    if (number > 0xff)
508
540
        data_buf[data_buf_len++] = ( (number>>8) & 0xff);
509
541
    data_buf[data_buf_len] = '\0';
 
542
 
 
543
    for (; i < data_buf_len; i++)
 
544
      data_mask_buf[i]=0xff;
 
545
}
 
546
 
 
547
void mon_add_number_masked_to_buffer(int number, int mask)
 
548
{
 
549
    data_buf[data_buf_len] = (number & 0xff);
 
550
    data_mask_buf[data_buf_len] = mask;
 
551
    data_buf_len++;
 
552
    data_buf[data_buf_len] = '\0';
510
553
}
511
554
 
512
555
void mon_add_string_to_buffer(char *str)
513
556
{
 
557
    unsigned int i = data_buf_len;
514
558
    strcpy((char *) &(data_buf[data_buf_len]), str);
515
559
    data_buf_len += strlen(str);
516
560
    data_buf[data_buf_len] = '\0';
517
561
    lib_free(str);
 
562
 
 
563
    for (; i < data_buf_len; i++)
 
564
      data_mask_buf[i]=0xff;
518
565
}
519
566
 
520
567
static monitor_cpu_type_list_t *montor_list_new(void)
528
575
    lib_free(list);
529
576
}
530
577
 
 
578
void mon_backtrace()
 
579
{
 
580
    BYTE opc;
 
581
    WORD sp, i, addr, n;
 
582
 
 
583
    /* TODO support DTV stack relocation, check memspace handling, move somewhere else */
 
584
    n = 0;
 
585
    sp = (monitor_cpu_type.mon_register_get_val)(default_memspace, e_SP);
 
586
    for(i = sp + 0x100 + 1; i < 0x1ff; i++) {
 
587
        addr = mon_get_mem_val(default_memspace, i);
 
588
        addr += ((WORD)mon_get_mem_val(default_memspace, (WORD)(i + 1))) << 8;
 
589
        addr -= 2;
 
590
        opc = mon_get_mem_val(default_memspace, addr);
 
591
        if(opc == 0x20 /* JSR */) {
 
592
            mon_out("(%d) %04x\n", n, addr);
 
593
        }
 
594
        n++;
 
595
    }
 
596
}
 
597
 
 
598
/* TODO move somewhere else */
 
599
cpuhistory_t cpuhistory[CPUHISTORY_SIZE];
 
600
int cpuhistory_i;
 
601
 
 
602
void monitor_cpuhistory_store(WORD addr, BYTE op, BYTE p1, BYTE p2)
 
603
{
 
604
    ++cpuhistory_i;
 
605
    cpuhistory_i &= (CPUHISTORY_SIZE-1);
 
606
    cpuhistory[cpuhistory_i].addr = addr;
 
607
    cpuhistory[cpuhistory_i].op = op;
 
608
    cpuhistory[cpuhistory_i].p1 = p1;
 
609
    cpuhistory[cpuhistory_i].p2 = p2;
 
610
}
 
611
 
 
612
void mon_cpuhistory(int count)
 
613
{
 
614
#ifdef FEATURE_CPUMEMHISTORY
 
615
    BYTE op, p1, p2, p3 = 0;
 
616
    MEMSPACE mem;
 
617
    WORD loc, addr;
 
618
    int hex_mode = 1;
 
619
    const char *dis_inst;
 
620
    unsigned opc_size;
 
621
    int i, pos;
 
622
 
 
623
    if((count<1)||(count>CPUHISTORY_SIZE)) {
 
624
        count = CPUHISTORY_SIZE;
 
625
    }
 
626
 
 
627
    pos = (cpuhistory_i + 1 - count) & (CPUHISTORY_SIZE-1);
 
628
    
 
629
    for(i=0; i < count; ++i) {
 
630
        addr = cpuhistory[pos].addr;
 
631
        op = cpuhistory[pos].op;
 
632
        p1 = cpuhistory[pos].p1;
 
633
        p2 = cpuhistory[pos].p2;
 
634
 
 
635
        mem = addr_memspace(addr);
 
636
        loc = addr_location(addr);
 
637
 
 
638
        dis_inst = mon_disassemble_to_string_ex(mem, loc, op, p1, p2, p3, hex_mode,
 
639
                                                &opc_size);
 
640
 
 
641
        /* Print the disassembled instruction */
 
642
        mon_out(".%s:%04x   %s\n", mon_memspace_string[mem], loc, dis_inst);
 
643
 
 
644
        pos = (pos+1) & (CPUHISTORY_SIZE-1);
 
645
    }
 
646
#else
 
647
    mon_out("Disabled. configure with --enable-memmap and recompile.\n");
 
648
#endif
 
649
}
 
650
 
 
651
 
 
652
/* TODO move somewhere else */
 
653
BYTE *mon_memmap;
 
654
int mon_memmap_size;
 
655
int mon_memmap_picx;
 
656
int mon_memmap_picy;
 
657
BYTE memmap_state;
 
658
 
 
659
static void mon_memmap_init(void)
 
660
{
 
661
#ifdef FEATURE_CPUMEMHISTORY
 
662
    mon_memmap_picx = 0x100;
 
663
    if (machine_class == VICE_MACHINE_C64DTV) {
 
664
        mon_memmap_picy = 0x2000;
 
665
    } else {
 
666
        mon_memmap_picy = 0x100;
 
667
    }
 
668
    mon_memmap_size = mon_memmap_picx * mon_memmap_picy;
 
669
    mon_memmap = lib_malloc(mon_memmap_size);
 
670
#else
 
671
    mon_memmap = NULL;
 
672
    mon_memmap_size = 0;
 
673
    mon_memmap_picx = 0;
 
674
    mon_memmap_picy = 0;
 
675
#endif
 
676
}
 
677
 
 
678
void mon_memmap_zap(void)
 
679
{
 
680
#ifdef FEATURE_CPUMEMHISTORY
 
681
    memset(mon_memmap, 0, mon_memmap_size);
 
682
#else
 
683
    mon_out("Disabled. configure with --enable-memmap and recompile.\n");
 
684
#endif
 
685
}
 
686
 
 
687
void mon_memmap_show(int mask, MON_ADDR start_addr, MON_ADDR end_addr)
 
688
{
 
689
#ifdef FEATURE_CPUMEMHISTORY
 
690
    int i;
 
691
    BYTE b;
 
692
 
 
693
    if(machine_class == VICE_MACHINE_C64DTV) {
 
694
       mon_out("  addr: IO ROM RAM\n");
 
695
    } else {
 
696
       mon_out("addr: IO ROM RAM\n");
 
697
    }
 
698
 
 
699
    if(start_addr == BAD_ADDR) start_addr = 0;
 
700
    if(end_addr == BAD_ADDR) end_addr = mon_memmap_size-1;
 
701
    if(start_addr>end_addr) start_addr = end_addr;
 
702
 
 
703
    for(i = start_addr; i <= end_addr; ++i) {
 
704
        b = mon_memmap[i];
 
705
        if ((b & mask)!= 0) {
 
706
            if(machine_class == VICE_MACHINE_C64DTV) {
 
707
                mon_out("%06x: %c%c %c%c%c %c%c%c\n",i,
 
708
                    (b&MEMMAP_I_O_R)?'r':'-',
 
709
                    (b&MEMMAP_I_O_W)?'w':'-',
 
710
                    (b&MEMMAP_ROM_R)?'r':'-',
 
711
                    (b&MEMMAP_ROM_W)?'w':'-',
 
712
                    (b&MEMMAP_ROM_X)?'x':'-',
 
713
                    (b&MEMMAP_RAM_R)?'r':'-',
 
714
                    (b&MEMMAP_RAM_W)?'w':'-',
 
715
                    (b&MEMMAP_RAM_X)?'x':'-');
 
716
            } else {
 
717
                mon_out("%04x: %c%c %c%c%c %c%c%c\n",i,
 
718
                    (b&MEMMAP_I_O_R)?'r':'-',
 
719
                    (b&MEMMAP_I_O_W)?'w':'-',
 
720
                    (b&MEMMAP_ROM_R)?'r':'-',
 
721
                    (b&MEMMAP_ROM_W)?'w':'-',
 
722
                    (b&MEMMAP_ROM_X)?'x':'-',
 
723
                    (b&MEMMAP_RAM_R)?'r':'-',
 
724
                    (b&MEMMAP_RAM_W)?'w':'-',
 
725
                    (b&MEMMAP_RAM_X)?'x':'-');
 
726
            }
 
727
        }
 
728
    }
 
729
#else
 
730
    mon_out("Disabled. configure with --enable-memmap and recompile.\n");
 
731
#endif
 
732
}
 
733
 
 
734
void monitor_memmap_store(unsigned int addr, BYTE type)
 
735
{
 
736
    BYTE op = cpuhistory[cpuhistory_i].op;
 
737
 
 
738
    if (inside_monitor) return;
 
739
 
 
740
    /* Ignore reg_pc+2 reads on branches & JSR 
 
741
       and return address read on RTS */
 
742
    if(type & (MEMMAP_ROM_R|MEMMAP_RAM_R)
 
743
      &&(((op & 0x1f) == 0x10)||(op == OP_JSR)
 
744
      ||((op == OP_RTS) && ((addr>0x1ff)||(addr<0x100)))))
 
745
        return;
 
746
 
 
747
    mon_memmap[addr & (mon_memmap_size-1)] |= type;
 
748
}
 
749
 
 
750
#ifdef FEATURE_CPUMEMHISTORY
 
751
BYTE mon_memmap_palette[256*3];
 
752
 
 
753
void mon_memmap_make_palette(void)
 
754
{
 
755
    int i;
 
756
    for(i=0; i<256; ++i) {
 
757
        mon_memmap_palette[i*3+0] = (i&(MEMMAP_RAM_W))?0x80:0+(i&(MEMMAP_ROM_W))?0x60:0+(i&(MEMMAP_I_O_W))?0x1f:0;
 
758
        mon_memmap_palette[i*3+1] = (i&(MEMMAP_RAM_X))?0x80:0+(i&(MEMMAP_ROM_X))?0x60:0+(i&(MEMMAP_I_O_W|MEMMAP_I_O_R))?0x1f:0;
 
759
        mon_memmap_palette[i*3+2] = (i&(MEMMAP_RAM_R))?0x80:0+(i&(MEMMAP_ROM_R))?0x60:0+(i&(MEMMAP_I_O_R))?0x1f:0;
 
760
    }
 
761
}
 
762
#endif
 
763
 
 
764
void mon_memmap_save(const char* filename, int format)
 
765
{
 
766
#ifdef FEATURE_CPUMEMHISTORY
 
767
    const char* drvname;
 
768
 
 
769
    switch(format) {
 
770
        case 1:
 
771
            drvname = "PCX";
 
772
            break;
 
773
        case 2:
 
774
            drvname = "PNG";
 
775
            break;
 
776
        case 3:
 
777
            drvname = "GIF";
 
778
            break;
 
779
        case 4:
 
780
            drvname = "IFF";
 
781
            break;
 
782
        default:
 
783
            drvname = "BMP";
 
784
            break;
 
785
    }
 
786
    if(memmap_screenshot_save(drvname, filename, mon_memmap_picx, mon_memmap_picy, mon_memmap, mon_memmap_palette)) {
 
787
        mon_out("Failed.\n");
 
788
    }
 
789
#else
 
790
    mon_out("Disabled. configure with --enable-memmap and recompile.\n");
 
791
#endif
 
792
}
 
793
 
 
794
void mon_screenshot_save(const char* filename, int format)
 
795
{
 
796
    const char* drvname;
 
797
 
 
798
    switch(format) {
 
799
        case 1:
 
800
            drvname = "PCX";
 
801
            break;
 
802
        case 2:
 
803
            drvname = "PNG";
 
804
            break;
 
805
        case 3:
 
806
            drvname = "GIF";
 
807
            break;
 
808
        case 4:
 
809
            drvname = "IFF";
 
810
            break;
 
811
        default:
 
812
            drvname = "BMP";
 
813
            break;
 
814
    }
 
815
    if(screenshot_save(drvname, filename, machine_video_canvas_get(0))) {
 
816
        mon_out("Failed.\n");
 
817
    }
 
818
}
 
819
 
 
820
void mon_show_pwd(void)
 
821
{
 
822
    mon_out("%s\n", ioutil_current_dir());
 
823
}
 
824
 
 
825
void mon_show_dir(const char *path)
 
826
{
 
827
    struct ioutil_dir_s *dir;
 
828
    char *name;
 
829
    char *mpath;
 
830
 
 
831
    if (path) {
 
832
        mpath=(char *)path;
 
833
    } else {
 
834
        mpath=ioutil_current_dir();
 
835
    }
 
836
    mon_out("Displaying directory: `%s'\n", mpath);
 
837
 
 
838
    dir = ioutil_opendir(mpath);
 
839
    if (!dir) {
 
840
        mon_out("Couldn't open directory.\n");
 
841
        return;
 
842
    }
 
843
 
 
844
    while ( (name = ioutil_readdir(dir)) ) {
 
845
        unsigned int len, isdir;
 
846
        int ret;
 
847
        ret = ioutil_stat(name, &len, &isdir);
 
848
        if (!ret) {
 
849
            if (isdir)
 
850
                mon_out("     <dir> %s\n", name);
 
851
            else
 
852
                mon_out("%10d %s\n", len, name);
 
853
        } else
 
854
            mon_out("%-20s?????\n", name);
 
855
    }
 
856
    ioutil_closedir(dir);
 
857
}
 
858
 
 
859
void mon_resource_get(const char *name)
 
860
{
 
861
    switch(resources_query_type(name)) {
 
862
        case RES_INTEGER:
 
863
        case RES_STRING:
 
864
            mon_out("%s\n",resources_write_item_to_string(name,""));
 
865
            break;
 
866
        default:
 
867
            mon_out("Unknown resource \"%s\".\n",name);
 
868
            return;
 
869
    }
 
870
}
 
871
 
 
872
void mon_resource_set(const char *name, const char* value)
 
873
{
 
874
    switch(resources_query_type(name)) {
 
875
        case RES_INTEGER:
 
876
        case RES_STRING:
 
877
            if(resources_set_value_string(name,value)) {
 
878
                mon_out("Failed.\n");
 
879
            }
 
880
            ui_update_menus();
 
881
            break;
 
882
        default:
 
883
            mon_out("Unknown resource \"%s\".\n",name);
 
884
            return;
 
885
    }
 
886
}
 
887
 
 
888
void mon_reset_machine(int type)
 
889
{
 
890
    switch(type) {
 
891
        case 1:
 
892
            machine_trigger_reset(MACHINE_RESET_MODE_HARD);
 
893
            exit_mon = 1;
 
894
            break;
 
895
        case 8:
 
896
        case 9:
 
897
        case 10:
 
898
        case 11:
 
899
            drivecpu_trigger_reset(type-8);
 
900
            break;
 
901
        default:
 
902
            machine_trigger_reset(MACHINE_RESET_MODE_SOFT);
 
903
            exit_mon = 1;
 
904
            break;
 
905
    }
 
906
}
 
907
 
 
908
void mon_tape_ctrl(int command)
 
909
{
 
910
    if((command<0)||(command>6)) {
 
911
        mon_out("Unknown command.\n");
 
912
    } else {
 
913
        datasette_control(command);
 
914
    }
 
915
}
 
916
 
 
917
void mon_cart_freeze(void)
 
918
{
 
919
    if(mon_cart_cmd.cartridge_trigger_freeze != NULL) {
 
920
        (mon_cart_cmd.cartridge_trigger_freeze)();
 
921
    } else {
 
922
        mon_out("Unsupported.\n");
 
923
   }
 
924
}
 
925
 
531
926
/* *** MISC COMMANDS *** */
532
927
 
533
928
void monitor_init(monitor_interface_t *maincpu_interface_init,
550
945
    asm_mode = 0;
551
946
    next_or_step_stop = 0;
552
947
    recording = FALSE;
553
 
    playback = FALSE;
 
948
    cpuhistory_i = 0;
554
949
 
555
950
    mon_ui_init();
556
951
 
591
986
 
592
987
    for (dnr = 0; dnr < DRIVE_NUM; dnr++)
593
988
        mon_interfaces[monitor_diskspace_mem(dnr)] = drive_interface_init[dnr];
 
989
 
 
990
    mon_memmap_init();
 
991
#ifdef FEATURE_CPUMEMHISTORY
 
992
    mon_memmap_zap();
 
993
    mon_memmap_make_palette();
 
994
#endif
 
995
 
 
996
    if (mon_init_break != -1)
 
997
        mon_breakpoint_add_checkpoint((WORD)mon_init_break, BAD_ADDR, FALSE, FALSE,FALSE, FALSE);
 
998
 
 
999
    if (playback > 0) {
 
1000
        playback_commands(playback);
 
1001
    }
594
1002
}
595
1003
 
596
1004
void monitor_shutdown(void)
604
1012
        montor_list_destroy(list);
605
1013
        list = list_next;
606
1014
    }
 
1015
#ifdef FEATURE_CPUMEMHISTORY                                                                                                                                                                         
 
1016
   lib_free(mon_memmap);                                                                                                                                                                            
 
1017
#endif
 
1018
}
 
1019
 
 
1020
static int monitor_set_initial_breakpoint(const char *param, void *extra_param)
 
1021
{
 
1022
    int val;
 
1023
 
 
1024
    val = strtoul(param, NULL, 0);
 
1025
    if (val >= 0 && val < 65536)
 
1026
        mon_init_break = val;
 
1027
 
 
1028
    return 0;
 
1029
}
 
1030
 
 
1031
static const cmdline_option_t cmdline_options[] = {
 
1032
    { "-moncommands", CALL_FUNCTION, 1,
 
1033
      set_playback_name, NULL, NULL, NULL,
 
1034
      USE_PARAM_ID, USE_DESCRIPTION_ID,
 
1035
      IDCLS_P_NAME, IDCLS_EXECUTE_MONITOR_FROM_FILE,
 
1036
      NULL, NULL },
 
1037
    { "-initbreak", CALL_FUNCTION, 1,
 
1038
      monitor_set_initial_breakpoint, NULL, NULL, NULL,
 
1039
      USE_PARAM_ID, USE_DESCRIPTION_ID,
 
1040
      IDCLS_P_VALUE, IDCLS_SET_INITIAL_BREAKPOINT,
 
1041
      NULL, NULL },
 
1042
    { NULL }
 
1043
};
 
1044
 
 
1045
int monitor_cmdline_options_init(void)
 
1046
{
 
1047
    mon_cart_cmd.cartridge_attach_image = NULL;
 
1048
    mon_cart_cmd.cartridge_detach_image = NULL;
 
1049
    mon_cart_cmd.cartridge_trigger_freeze = NULL;
 
1050
    mon_cart_cmd.cartridge_trigger_freeze_nmi_only = NULL;
 
1051
 
 
1052
    return cmdline_register_options(cmdline_options);
607
1053
}
608
1054
 
609
1055
monitor_interface_t *monitor_interface_new(void)
633
1079
    WORD base;
634
1080
    BYTE rows, cols;
635
1081
    unsigned int r, c;
 
1082
    int bank;
636
1083
 
637
 
    mem_get_screen_parameter(&base, &rows, &cols);
 
1084
    mem_get_screen_parameter(&base, &rows, &cols, &bank);
638
1085
    for (r = 0; r < rows; r++) {
639
1086
        for (c = 0; c < cols; c++) {
640
1087
            BYTE data;
653
1100
    mem_ioreg_list_t *mem_ioreg_list_base;
654
1101
    unsigned int n;
655
1102
    MON_ADDR start,end;
 
1103
    int newbank;
 
1104
    int currbank = mon_interfaces[default_memspace]->current_bank;
 
1105
 
 
1106
    newbank = mon_interfaces[default_memspace]->mem_bank_from_name("io");
 
1107
 
 
1108
    if (newbank >= 0) {
 
1109
        mon_interfaces[default_memspace]->current_bank = newbank;
 
1110
    }
656
1111
 
657
1112
    mem_ioreg_list_base
658
1113
        = mon_interfaces[default_memspace]->mem_ioreg_list_get(
663
1118
        mon_out("%s:\n", mem_ioreg_list_base[n].name);
664
1119
        start = new_addr(default_memspace, mem_ioreg_list_base[n].start);
665
1120
        end = new_addr(default_memspace, mem_ioreg_list_base[n].end);
666
 
        mon_memory_display(e_hexadecimal, start, end);
 
1121
        mon_memory_display(e_hexadecimal, start, end, DF_PETSCII);
667
1122
 
668
1123
        if (mem_ioreg_list_base[n].next == 0)
669
1124
            break;
671
1126
        n++;
672
1127
    }
673
1128
 
 
1129
    mon_interfaces[default_memspace]->current_bank = currbank;
674
1130
    lib_free(mem_ioreg_list_base);
675
1131
}
676
1132
 
714
1170
    mon_out("Changing to directory: `%s'\n", path);
715
1171
}
716
1172
 
717
 
void mon_load_symbols(MEMSPACE mem, const char *filename)
718
 
{
719
 
    /* Switched to a command-line format for the symbol file
720
 
     * so loading just involves "playing back" the commands.
721
 
     * It is no longer possible to just load symbols from a
722
 
     * single memory space.
723
 
     */
724
 
    playback_commands(filename);
725
 
#if 0
726
 
    FILE   *fp;
727
 
    WORD adr;
728
 
    char memspace[MAX_MEMSPACE_NAME_LEN], name[MAX_LABEL_LEN];
729
 
    char *name_ptr;
730
 
    bool found = FALSE;
731
 
    int rc, line_num = 2;
732
 
 
733
 
    if (NULL == (fp = fopen(filename, MODE_READ))) {
734
 
        mon_out("Loading for `%s' failed.\n", filename);
735
 
        return;
736
 
    }
737
 
 
738
 
    mon_out("Loading symbol table from `%s'...\n", filename);
739
 
 
740
 
    if (mem == e_default_space) {
741
 
        if (fscanf(fp, "%10s\n", name) == 1) {
742
 
            for (mem = FIRST_SPACE; mem <= LAST_SPACE; mem++) {
743
 
                if (strcmp(name, mon_memspace_string[mem]) == 0) {
744
 
                    found = TRUE;
745
 
                    break;
746
 
                }
747
 
            }
748
 
        }
749
 
        if (!found) {
750
 
            mon_out(
751
 
                      "Bad label file : expecting a memory space in the first line but found %s\n",
752
 
                      name);
753
 
            return;
754
 
        }
755
 
    }
756
 
 
757
 
    while (!feof(fp)) {
758
 
        rc = fscanf(fp, "%6x %255s\n", (int *) &adr, name);
759
 
        if (rc != 2) {
760
 
            mon_out(
761
 
                      "Bad label file: (line %d) cannot parse argument %d.\n",
762
 
                      line_num, rc + 1);
763
 
            break;
764
 
        }
765
 
        /* FIXME: Check name is a valid label name */
766
 
        name_ptr = (char *)lib_malloc((strlen(name) + 1) * sizeof(char));
767
 
        strcpy(name_ptr, name);
768
 
        mon_out("Read ($%x:%s)\n", adr, name_ptr);
769
 
        mon_add_name_to_symbol_table(new_addr(mem, adr), name_ptr);
770
 
 
771
 
        line_num++;
772
 
    }
773
 
 
774
 
    fclose(fp);
775
 
#endif
776
 
}
777
 
 
778
1173
void mon_save_symbols(MEMSPACE mem, const char *filename)
779
1174
{
780
1175
    FILE *fp;
837
1232
    recording = FALSE;
838
1233
}
839
1234
 
840
 
static void playback_commands(const char *filename)
 
1235
static int set_playback_name(const char *param, void *extra_param)
 
1236
{
 
1237
    if (!playback_name) {
 
1238
        playback_name = strdup(param);
 
1239
        playback = 1;
 
1240
    }
 
1241
    return 0;
 
1242
}
 
1243
 
 
1244
static void playback_commands(int current_playback)
841
1245
{
842
1246
    FILE *fp;
843
1247
    char string[256];
 
1248
    char *filename = playback_name;
844
1249
 
845
1250
    fp = fopen(filename, MODE_READ_TEXT);
846
1251
 
849
1254
 
850
1255
    if (fp == NULL) {
851
1256
        mon_out("Playback for `%s' failed.\n", filename);
 
1257
        free(playback_name);
 
1258
        playback_name = NULL;
 
1259
        --playback;
852
1260
        return;
853
1261
    }
854
1262
 
 
1263
    free(playback_name);
 
1264
    playback_name = NULL;
 
1265
 
855
1266
    while (fgets(string, 255, fp) != NULL) {
856
1267
        if (strcmp(string, "stop\n") == 0)
857
1268
            break;
858
1269
 
859
1270
        string[strlen(string) - 1] = '\0';
860
1271
        parse_and_execute_line(string);
 
1272
 
 
1273
        if (playback > current_playback) {
 
1274
            playback_commands(playback);
 
1275
        }
861
1276
    }
862
1277
 
863
1278
    fclose(fp);
864
 
    playback = FALSE;
 
1279
    --playback;
 
1280
}
 
1281
 
 
1282
void mon_playback_init(const char *filename)
 
1283
{
 
1284
    if (playback < MAX_PLAYBACK) {
 
1285
        playback_name = strdup(filename);
 
1286
        ++playback;
 
1287
    } else {
 
1288
        mon_out("Playback for `%s' failed (recursion > %i).\n", filename, MAX_PLAYBACK);
 
1289
    }
865
1290
}
866
1291
 
867
1292
 
932
1357
    return -1;
933
1358
}
934
1359
 
 
1360
char* mon_prepend_dot_to_name(char* name)
 
1361
{
 
1362
    char* s = malloc(strlen(name) + 2);
 
1363
    strcpy(s, ".");
 
1364
    strcat(s, name);
 
1365
    free(name);
 
1366
    return s;
 
1367
}
 
1368
 
935
1369
void mon_add_name_to_symbol_table(MON_ADDR addr, char *name)
936
1370
{
937
1371
    symbol_entry_t *sym_ptr;
957
1391
    if (old_addr >= 0 && old_addr != loc) {
958
1392
        mon_out("Changing address of label %s from $%04x to $%04x\n",
959
1393
                  name, old_addr, loc);
 
1394
        mon_remove_name_from_symbol_table(mem, name);
960
1395
    }
961
1396
 
962
1397
    /* Add name to name list */
1412
1847
    return 0;
1413
1848
}
1414
1849
 
 
1850
void monitor_change_device(MEMSPACE mem)
 
1851
{
 
1852
    mon_out("Setting default device to `%s'\n",_mon_space_strings[(int) mem]);
 
1853
    default_memspace = mem;
 
1854
 
 
1855
    if(machine_class == VICE_MACHINE_C64DTV) {
 
1856
        switch(mem) {
 
1857
            case e_comp_space:
 
1858
                monitor_cpu_type_set("6502dtv");
 
1859
                break;
 
1860
            case e_disk8_space:
 
1861
            case e_disk9_space:
 
1862
            case e_disk10_space:
 
1863
            case e_disk11_space:
 
1864
            default:
 
1865
                monitor_cpu_type_set("6502");
 
1866
                break;
 
1867
        }
 
1868
    }
 
1869
}
 
1870
 
1415
1871
static void make_prompt(char *str)
1416
1872
{
1417
1873
    if (asm_mode)
1446
1902
 
1447
1903
    uimon_notify_change();
1448
1904
 
 
1905
    if (machine_class == VICE_MACHINE_C64DTV) {
 
1906
        monitor_cpu_type_set("6502dtv");
 
1907
    }
 
1908
 
1449
1909
    dot_addr[e_comp_space] = new_addr(e_comp_space,
1450
1910
                                      MONITOR_GET_PC(e_comp_space));
 
1911
 
 
1912
    if (machine_class == VICE_MACHINE_C64DTV) {
 
1913
        monitor_cpu_type_set("6502");
 
1914
    }
 
1915
 
1451
1916
    for (dnr = 0; dnr < DRIVE_NUM; dnr++) {
1452
1917
        int mem = monitor_diskspace_mem(dnr);
1453
1918
 
1454
1919
        dot_addr[mem] = new_addr(mem, MONITOR_GET_PC(mem));
1455
1920
    }
1456
1921
 
 
1922
    if ((caller_space == e_comp_space) && (machine_class == VICE_MACHINE_C64DTV)) {
 
1923
        monitor_cpu_type_set("6502dtv");
 
1924
    }
 
1925
 
1457
1926
    mon_out("\n** Monitor");
1458
1927
 
1459
1928
    if (caller_space == e_comp_space
1475
1944
        mon_disassemble_instr(dot_addr[caller_space]);
1476
1945
        disassemble_on_entry = 0;
1477
1946
    }
 
1947
 
 
1948
    if ((default_memspace != e_comp_space) && (machine_class == VICE_MACHINE_C64DTV)) {
 
1949
        monitor_cpu_type_set("6502");
 
1950
    }
1478
1951
}
1479
1952
 
1480
1953
static int monitor_process(char *cmd)
1514
1987
 
1515
1988
            parse_and_execute_line(cmd);
1516
1989
 
1517
 
            if (playback)
1518
 
                playback_commands(playback_name);
 
1990
            if (playback > 0) {
 
1991
                playback_commands(playback);
 
1992
            }
1519
1993
        }
1520
1994
    }
1521
1995
    if (last_cmd)