git.haldean.org x6502 / 853f592
Block device support in IO bus. No docs on this yet because it's barely tested at all. Will Haldean Brown 7 years ago
8 changed file(s) with 117 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
11 x6502
22 debug-names.h
33 a.o65
4 sample_programs/diskread/gd
00 #ifndef __6502_FUNCTIONS__
11 #define __6502_FUNCTIONS__
2
3 #include <stdlib.h>
24
35 #include "cpu.h"
46
57 #define ZP(x) ((uint8_t) (x))
68 #define STACK_PUSH(m) (m)->mem[(m)->sp-- + STACK_START]
79 #define STACK_POP(m) (m)->mem[++(m)->sp + STACK_START]
10
11 #ifdef DEBUG
12 #define debugf(...) fprintf(stderr, __VA_ARGS__)
13 #else
14 #define debugf(...) do {} while (0)
15 #endif
816
917 static inline size_t mem_abs(uint8_t low, uint8_t high, uint8_t off) {
1018 return (uint16_t) off + (uint16_t) low + ((uint16_t) high << 8);
11
22 #include <ncurses.h>
33 #include <stdio.h>
4 #include <stdlib.h>
45 #include <sys/select.h>
56 #include <sys/time.h>
67
1213 uint8_t io_modeflags = 0x00;
1314 uint8_t io_supports_paint;
1415
16 FILE *blck0 = NULL;
17
1518 WINDOW *window = NULL;
1619
1720 void init_vterm();
1821 void update_vterm(cpu *, uint16_t);
1922 void finish_vterm();
23
24 void set_block_source(FILE *source) {
25 blck0 = source;
26 }
2027
2128 void init_io() {
2229 initscr();
4249 getch();
4350 }
4451
45 if (io_modeflags & IO_MODEFLAG_VTERM) {
46 finish_vterm();
47 }
52 endwin();
4853 }
4954
5055 void init_vterm() {
100105
101106 if (get_emu_flag(m, EMU_FLAG_DIRTY)) {
102107 uint16_t addr = m->dirty_mem_addr;
103
104 #ifdef DEBUG
105 fprintf(stderr, "dirty address %04X has value %02x\n",
106 addr, m->mem[addr]);
107 #endif
108 debugf("dirty address %04X has value %02x\n", addr, m->mem[addr]);
108109
109110 if (addr == IO_PUTCHAR) {
110111 if (io_modeflags & IO_MODEFLAG_VTERM) {
119120 update_paint(m->mem[addr]);
120121 } else if (IO_VTERM_START <= addr && addr < IO_VTERM_END) {
121122 update_vterm(m, addr);
123 } else if (addr == IO_BLCK0_ADDRL
124 || addr == IO_BLCK0_ADDRH
125 || addr == IO_BLCK0_READ) {
126 if (blck0 == NULL) {
127 finish_vterm();
128 fprintf(stderr, "tried to read from unattached block device\n");
129 exit(-1);
130 return;
131 }
132
133 uint16_t read_addr =
134 m->mem[IO_BLCK0_ADDRH] << 8 | m->mem[IO_BLCK0_ADDRL];
135 int res = fseek(blck0, read_addr, SEEK_SET);
136 if (res) {
137 debugf("ERROR: fseek returned %d\n", res);
138 m->mem[IO_BLCK0_ERR] = IO_BLCK_ERR_SEEK;
139 return;
140 }
141
142 res = fgetc(blck0);
143 if (res == EOF) {
144 debugf("ERROR: fgetc returned EOF\n");
145 m->mem[IO_BLCK0_ERR] = IO_BLCK_ERR_EOF;
146 return;
147 }
148 m->mem[IO_BLCK0_READ] = 0xFF & res;
149 m->mem[IO_BLCK0_ERR] = 0x00;
122150 }
123151 }
124152 }
00 #ifndef __6502_IO__
1
2 #include <stdio.h>
13
24 #include "cpu.h"
35
6 #define IO_PAINT 0xFEE8
47 #define IO_PUTCHAR 0xFF00
58 #define IO_GETCHAR 0xFF01
69 #define IO_MODEFLAGS 0xFF02
7 #define IO_PAINT 0xFEE8
10
11 // writing to ADDRL, ADDRH or READ will trigger an interrupt that will read from
12 // the disk address specified by ADDRL and ADDRH and write the result into READ.
13 // if errors are encountered, ERR will be nonzero.
14 #define IO_BLCK0_ADDRL 0xFF03
15 #define IO_BLCK0_ADDRH 0xFF04
16 #define IO_BLCK0_READ 0xFF05
17 #define IO_BLCK0_WRITE 0xFF06
18 #define IO_BLCK0_ERR 0xFF07
19
20 #define IO_BLCK_ERR_EOF 0x01
21 #define IO_BLCK_ERR_SEEK 0x02
822
923 #define IO_VTERM_START 0xFB00
1024 #define IO_VTERM_END 0xFF00
2640 #define IO_PAINT_UNDERLINE 0x40
2741 #define IO_PAINT_BOLD 0x80
2842
43 void set_block_source(FILE *source);
2944 void init_io();
3045 void finish_io();
3146 void handle_io(cpu *m);
00 #include "cpu.h"
11 #include "emu.h"
2 #include "functions.h"
3 #include "io.h"
24 #include "opcodes.h"
35
46 #include <ctype.h>
1113 printf("usage: x6502 [OPTION]... [FILE] \n");
1214 printf("options:\n");
1315 printf("\t-b addr\t\tthe base address at which code will be loaded\n");
16 printf("\t-d file\t\ta binary file to back the block device\n");
1417 printf("\t\t\t(optional, defaults to zero)\n");
1518 }
1619
1720 int main(int argc, char *argv[]) {
1821 int base_addr = 0x1000;
22 char *blck0_file = NULL;
1923
2024 int c;
21 while ((c = getopt(argc, argv, "hb:")) != -1) {
25 while ((c = getopt(argc, argv, "hb:d:")) != -1) {
2226 switch (c) {
2327 case 'b':
2428 base_addr = atoi(optarg);
29 break;
30
31 case 'd':
32 blck0_file = optarg;
2533 break;
2634
2735 case 'h':
2937 return 0;
3038
3139 case '?':
32 if (optopt == 'b') {
40 if (optopt == 'b' || optopt == 'd') {
3341 fprintf(stderr, "Option -%c requires an argument.\n", optopt);
3442 }
3543 usage();
4351 return -1;
4452 }
4553
46 FILE *in_f = fopen(argv[optind], "rb");
54 debugf("using %s as a backing file for block device 0\n", blck0_file);
55 if (blck0_file != NULL) {
56 FILE *blck0 = fopen(blck0_file, "r+");
57 if (blck0 == NULL) {
58 fprintf(stderr, "block file %s does not exist.\n", blck0_file);
59 return -1;
60 }
61 set_block_source(blck0);
62 }
63
64 FILE *in_f = fopen(argv[optind], "r");
4765 int b;
4866 int i = base_addr;
4967 cpu *m = new_cpu(base_addr);
0 cli
1 lda #$02 ; set WAIT_TERMINATE flag
2 sta $FF02
3 lda #$03
4 sta $FF03
5 lda #$00
6 sta $FF04
7 lda #$00
8 cmp $FF07
9 beq printchar
10 lda #'e'
11 sta $FF00
12 lda #'r'
13 sta $FF00
14 sta $FF00
15 jmp done
16 printchar:
17 lda $FF05
18 sta $FF00
19 done:
0 #include <errno.h>
1 #include <stdio.h>
2 #include <string.h>
3
4 int main() {
5 FILE *f = fopen("testdisk.bin", "w");
6 if (f == NULL) {
7 printf("could not open file, err: %s", strerror(errno));
8 return 1;
9 }
10 fprintf(f, "hello, world!");
11 fclose(f);
12 return 0;
13 }