6502 RAM/bus emulation with VGA display
Dependencies: fastlib mbed vga640x480g
Fork of vga640x480graphic by
main.cpp@1:f9ed7e40eccf, 2015-05-03 (annotated)
- Committer:
- brandin
- Date:
- Sun May 03 17:48:25 2015 +0000
- Revision:
- 1:f9ed7e40eccf
- Parent:
- 0:770395da503c
emulating 6502 RAM/bus with VGA display
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gertk | 0:770395da503c | 1 | /* |
gertk | 0:770395da503c | 2 | * 640x480 60Hz fullgraphic monochrome VGA Driver demo program |
gertk | 0:770395da503c | 3 | * |
gertk | 0:770395da503c | 4 | * Copyright (C) 2011 by Ivo van Poorten <ivop(at)euronet.nl> |
gertk | 0:770395da503c | 5 | * and Gert van der Knokke <gertk(at)xs4all.nl> |
gertk | 0:770395da503c | 6 | * This file is licensed under the terms of the GNU Lesser |
gertk | 0:770395da503c | 7 | * General Public License, version 3. |
gertk | 0:770395da503c | 8 | * |
gertk | 0:770395da503c | 9 | * Inspired by Simon's (not Ford) Cookbook entry and Cliff Biffle's |
gertk | 0:770395da503c | 10 | * assembly code. |
gertk | 0:770395da503c | 11 | */ |
gertk | 0:770395da503c | 12 | |
gertk | 0:770395da503c | 13 | #include "mbed.h" |
brandin | 1:f9ed7e40eccf | 14 | #include "vga640x480g.h" // vga p5, p8, p25 |
brandin | 1:f9ed7e40eccf | 15 | |
brandin | 1:f9ed7e40eccf | 16 | //Serial display(p9,p10); |
brandin | 1:f9ed7e40eccf | 17 | |
brandin | 1:f9ed7e40eccf | 18 | DigitalOut resety(p17/*, 1*/); |
brandin | 1:f9ed7e40eccf | 19 | DigitalOut clocky(p18/*, 1*/); |
brandin | 1:f9ed7e40eccf | 20 | DigitalIn rw(p19); |
brandin | 1:f9ed7e40eccf | 21 | DigitalOut addressDisable(p20/*, 1*/); |
brandin | 1:f9ed7e40eccf | 22 | BusInOut mixBus(p21, p22, p23, p24, p16, p26, p27, p28); |
brandin | 1:f9ed7e40eccf | 23 | BusIn addrHigh(p29, p30); |
brandin | 1:f9ed7e40eccf | 24 | |
brandin | 1:f9ed7e40eccf | 25 | BusOut addrLeds(LED1, LED2, LED3, LED4); |
brandin | 1:f9ed7e40eccf | 26 | Serial pc(USBTX, USBRX); // tx, rx |
brandin | 1:f9ed7e40eccf | 27 | |
brandin | 1:f9ed7e40eccf | 28 | LocalFileSystem local("local"); // Create the local filesystem under the name "local" |
brandin | 1:f9ed7e40eccf | 29 | |
brandin | 1:f9ed7e40eccf | 30 | char memory[4*256]; |
brandin | 1:f9ed7e40eccf | 31 | |
brandin | 1:f9ed7e40eccf | 32 | void halfcycle() { |
brandin | 1:f9ed7e40eccf | 33 | wait_ms(1); |
brandin | 1:f9ed7e40eccf | 34 | } |
brandin | 1:f9ed7e40eccf | 35 | |
brandin | 1:f9ed7e40eccf | 36 | void busDisplay(int addr, int data, int flags) { |
brandin | 1:f9ed7e40eccf | 37 | char tmp[255]; |
brandin | 1:f9ed7e40eccf | 38 | sprintf(tmp, "%04X %04X", addr, data); |
brandin | 1:f9ed7e40eccf | 39 | vga_putstring(400,370,tmp,WHITE); |
brandin | 1:f9ed7e40eccf | 40 | // display.putc(0x76); |
brandin | 1:f9ed7e40eccf | 41 | // display.putc((addr & 0x00f0) >> 4); |
brandin | 1:f9ed7e40eccf | 42 | // display.putc(addr & 0x000f); |
brandin | 1:f9ed7e40eccf | 43 | // display.putc((data & 0xf0) >> 4); |
brandin | 1:f9ed7e40eccf | 44 | // display.putc(data & 0x0f); |
brandin | 1:f9ed7e40eccf | 45 | // display.putc(0x77); |
brandin | 1:f9ed7e40eccf | 46 | // display.putc(((addr & 0x0300) >> 8) | (flags << 2)); |
brandin | 1:f9ed7e40eccf | 47 | // pc.printf("%X %X %X\r\n", addr, data, flags); |
brandin | 1:f9ed7e40eccf | 48 | } |
gertk | 0:770395da503c | 49 | |
gertk | 0:770395da503c | 50 | // visual feedback |
brandin | 1:f9ed7e40eccf | 51 | //DigitalOut myled(LED1); |
gertk | 0:770395da503c | 52 | |
gertk | 0:770395da503c | 53 | // define serial port for debug |
brandin | 1:f9ed7e40eccf | 54 | //Serial linktopc(USBTX,USBRX); |
gertk | 0:770395da503c | 55 | |
brandin | 1:f9ed7e40eccf | 56 | void draw() { |
gertk | 0:770395da503c | 57 | // init the VGA subsystem (always do this first!) |
brandin | 1:f9ed7e40eccf | 58 | //init_vga(); |
gertk | 0:770395da503c | 59 | |
gertk | 0:770395da503c | 60 | int s,t; |
gertk | 0:770395da503c | 61 | |
gertk | 0:770395da503c | 62 | // serial port on at 115200 baud |
brandin | 1:f9ed7e40eccf | 63 | //linktopc.baud(115200); |
brandin | 1:f9ed7e40eccf | 64 | //setbuf(stdout, NULL); // no buffering for this filehandle |
gertk | 0:770395da503c | 65 | |
gertk | 0:770395da503c | 66 | // clear the screen |
gertk | 0:770395da503c | 67 | vga_cls(); |
gertk | 0:770395da503c | 68 | |
gertk | 0:770395da503c | 69 | // draw some circles |
brandin | 1:f9ed7e40eccf | 70 | //for (t=10; t<200; t+=5) |
brandin | 1:f9ed7e40eccf | 71 | //vga_circle(20+t,399-t,t,WHITE); |
gertk | 0:770395da503c | 72 | |
gertk | 0:770395da503c | 73 | // draw some boxes |
brandin | 1:f9ed7e40eccf | 74 | //for (t=10; t<100; t+=5) |
brandin | 1:f9ed7e40eccf | 75 | //vga_box(400+t,100+t,400+t*2,100+t*2,WHITE); |
gertk | 0:770395da503c | 76 | |
gertk | 0:770395da503c | 77 | // circumfence the screen |
gertk | 0:770395da503c | 78 | vga_box(0,0,639,479,WHITE); |
gertk | 0:770395da503c | 79 | |
gertk | 0:770395da503c | 80 | // show the complete character set |
gertk | 0:770395da503c | 81 | for (s=0; s<4; s++) { |
gertk | 0:770395da503c | 82 | for (t=0; t<64; t++) { |
gertk | 0:770395da503c | 83 | vga_putchar(20+t*8,20+16*s,t+s*64,WHITE); |
gertk | 0:770395da503c | 84 | } |
gertk | 0:770395da503c | 85 | } |
gertk | 0:770395da503c | 86 | |
gertk | 0:770395da503c | 87 | // put a string on screen |
brandin | 1:f9ed7e40eccf | 88 | //vga_putstring(400,370,"Hello World!",WHITE); |
gertk | 0:770395da503c | 89 | |
gertk | 0:770395da503c | 90 | // draw some lines |
brandin | 1:f9ed7e40eccf | 91 | //vga_line(400,390,500,390,WHITE); |
brandin | 1:f9ed7e40eccf | 92 | //vga_line(500,475,600,375,WHITE); |
gertk | 0:770395da503c | 93 | |
gertk | 0:770395da503c | 94 | // draw a filled box |
gertk | 0:770395da503c | 95 | vga_filledbox(450,330,550,360,1); |
gertk | 0:770395da503c | 96 | |
gertk | 0:770395da503c | 97 | // draw some more boxes |
brandin | 1:f9ed7e40eccf | 98 | //for (t=10; t<320; t+=5) |
brandin | 1:f9ed7e40eccf | 99 | //vga_box(100+t,440-t/16,110+t,440+t/16,WHITE); |
brandin | 1:f9ed7e40eccf | 100 | return; |
brandin | 1:f9ed7e40eccf | 101 | } |
brandin | 1:f9ed7e40eccf | 102 | |
brandin | 1:f9ed7e40eccf | 103 | int main() { |
brandin | 1:f9ed7e40eccf | 104 | resety = 1; clocky = 1; addressDisable = 1; |
brandin | 1:f9ed7e40eccf | 105 | int addr, haddr, _rw; |
brandin | 1:f9ed7e40eccf | 106 | init_vga(); |
brandin | 1:f9ed7e40eccf | 107 | resety = 0; |
brandin | 1:f9ed7e40eccf | 108 | int count = 0; |
brandin | 1:f9ed7e40eccf | 109 | // serial port on at 115200 baud |
brandin | 1:f9ed7e40eccf | 110 | //pc.baud(115200); |
brandin | 1:f9ed7e40eccf | 111 | //setbuf(stdout, NULL); // no buffering for this filehandle |
brandin | 1:f9ed7e40eccf | 112 | draw(); |
brandin | 1:f9ed7e40eccf | 113 | // display.baud(9600); |
brandin | 1:f9ed7e40eccf | 114 | // display.putc(0x76); |
brandin | 1:f9ed7e40eccf | 115 | // display.putc('h');display.putc('E');display.putc('L');display.putc('o'); |
brandin | 1:f9ed7e40eccf | 116 | //// pc.printf("Hello World!\r\n"); |
brandin | 1:f9ed7e40eccf | 117 | // wait(1.0); |
brandin | 1:f9ed7e40eccf | 118 | FILE *fp = fopen("/local/6502.OUT", "r"); |
brandin | 1:f9ed7e40eccf | 119 | for (int i=0; i<256; i++) { |
brandin | 1:f9ed7e40eccf | 120 | int c = fgetc(fp); |
brandin | 1:f9ed7e40eccf | 121 | addr = 2*256 + i; |
brandin | 1:f9ed7e40eccf | 122 | if (c >= 0) { |
brandin | 1:f9ed7e40eccf | 123 | memory[addr] = c & 0xff; |
brandin | 1:f9ed7e40eccf | 124 | } else { |
brandin | 1:f9ed7e40eccf | 125 | break; |
brandin | 1:f9ed7e40eccf | 126 | } |
brandin | 1:f9ed7e40eccf | 127 | busDisplay(addr, memory[addr], 0); |
brandin | 1:f9ed7e40eccf | 128 | //wait_ms(125); |
gertk | 0:770395da503c | 129 | } |
brandin | 1:f9ed7e40eccf | 130 | // reset vector |
brandin | 1:f9ed7e40eccf | 131 | memory[3*256 + 0xfc] = 0; |
brandin | 1:f9ed7e40eccf | 132 | memory[3*256 + 0xfd] = 0x80; |
brandin | 1:f9ed7e40eccf | 133 | fclose(fp); |
brandin | 1:f9ed7e40eccf | 134 | // display.putc(0x76); |
brandin | 1:f9ed7e40eccf | 135 | // display.putc('G');display.putc('o'); |
brandin | 1:f9ed7e40eccf | 136 | // wait(1.0); |
brandin | 1:f9ed7e40eccf | 137 | // |
brandin | 1:f9ed7e40eccf | 138 | //// pc.printf("run...\r\n"); |
brandin | 1:f9ed7e40eccf | 139 | while(1) { |
brandin | 1:f9ed7e40eccf | 140 | if (count++ == 10) { |
brandin | 1:f9ed7e40eccf | 141 | resety = 1; |
brandin | 1:f9ed7e40eccf | 142 | } |
brandin | 1:f9ed7e40eccf | 143 | //XXX use timer |
brandin | 1:f9ed7e40eccf | 144 | clocky = 0; |
brandin | 1:f9ed7e40eccf | 145 | mixBus.input(); |
brandin | 1:f9ed7e40eccf | 146 | addressDisable = 0; |
brandin | 1:f9ed7e40eccf | 147 | halfcycle(); |
brandin | 1:f9ed7e40eccf | 148 | addr = mixBus.read(); |
brandin | 1:f9ed7e40eccf | 149 | haddr = addrHigh.read(); |
brandin | 1:f9ed7e40eccf | 150 | addr = addr + (haddr * 256); |
brandin | 1:f9ed7e40eccf | 151 | clocky = 1; |
brandin | 1:f9ed7e40eccf | 152 | addressDisable = 1; |
brandin | 1:f9ed7e40eccf | 153 | _rw = rw; |
brandin | 1:f9ed7e40eccf | 154 | if (_rw) { |
brandin | 1:f9ed7e40eccf | 155 | mixBus.output(); |
brandin | 1:f9ed7e40eccf | 156 | mixBus.write(memory[addr]); |
brandin | 1:f9ed7e40eccf | 157 | halfcycle(); |
brandin | 1:f9ed7e40eccf | 158 | } else { |
brandin | 1:f9ed7e40eccf | 159 | halfcycle(); |
brandin | 1:f9ed7e40eccf | 160 | memory[addr] = mixBus.read(); |
brandin | 1:f9ed7e40eccf | 161 | } |
brandin | 1:f9ed7e40eccf | 162 | busDisplay(addr, memory[addr], _rw); //wait_ms(125); |
brandin | 1:f9ed7e40eccf | 163 | } |
brandin | 1:f9ed7e40eccf | 164 | } |