I\'ve ported my library x86Lib to mbed. It fully emulates the 8086 processor, but a few things I\'m still working on. Notable missing things are interrupts. Previously I used exceptions for interrupts, but exceptions aren\'t supported with the mbed compiler. It is also quite slow
device_manager.cpp@0:217a7931b41f, 2012-03-04 (annotated)
- Committer:
- earlz
- Date:
- Sun Mar 04 08:15:47 2012 +0000
- Revision:
- 0:217a7931b41f
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
earlz | 0:217a7931b41f | 1 | /** |
earlz | 0:217a7931b41f | 2 | Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls <http://www.Earlz.biz.tm> |
earlz | 0:217a7931b41f | 3 | All rights reserved. |
earlz | 0:217a7931b41f | 4 | |
earlz | 0:217a7931b41f | 5 | Redistribution and use in source and binary forms, with or without |
earlz | 0:217a7931b41f | 6 | modification, are permitted provided that the following conditions |
earlz | 0:217a7931b41f | 7 | are met: |
earlz | 0:217a7931b41f | 8 | |
earlz | 0:217a7931b41f | 9 | 1. Redistributions of source code must retain the above copyright |
earlz | 0:217a7931b41f | 10 | notice, this list of conditions and the following disclaimer. |
earlz | 0:217a7931b41f | 11 | 2. Redistributions in binary form must reproduce the above copyright |
earlz | 0:217a7931b41f | 12 | notice, this list of conditions and the following disclaimer in the |
earlz | 0:217a7931b41f | 13 | documentation and/or other materials provided with the distribution. |
earlz | 0:217a7931b41f | 14 | 3. The name of the author may not be used to endorse or promote products |
earlz | 0:217a7931b41f | 15 | derived from this software without specific prior written permission. |
earlz | 0:217a7931b41f | 16 | |
earlz | 0:217a7931b41f | 17 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, |
earlz | 0:217a7931b41f | 18 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
earlz | 0:217a7931b41f | 19 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL |
earlz | 0:217a7931b41f | 20 | THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
earlz | 0:217a7931b41f | 21 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
earlz | 0:217a7931b41f | 22 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
earlz | 0:217a7931b41f | 23 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
earlz | 0:217a7931b41f | 24 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
earlz | 0:217a7931b41f | 25 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
earlz | 0:217a7931b41f | 26 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
earlz | 0:217a7931b41f | 27 | |
earlz | 0:217a7931b41f | 28 | This file is part of the x86Lib project. |
earlz | 0:217a7931b41f | 29 | **/ |
earlz | 0:217a7931b41f | 30 | #define X86LIB_BUILD |
earlz | 0:217a7931b41f | 31 | #include <iostream> |
earlz | 0:217a7931b41f | 32 | #include <list> |
earlz | 0:217a7931b41f | 33 | #include <stdlib.h> |
earlz | 0:217a7931b41f | 34 | #include <stdio.h> |
earlz | 0:217a7931b41f | 35 | #include <cstring> |
earlz | 0:217a7931b41f | 36 | #include <x86Lib.h> |
earlz | 0:217a7931b41f | 37 | |
earlz | 0:217a7931b41f | 38 | |
earlz | 0:217a7931b41f | 39 | namespace x86Lib{ |
earlz | 0:217a7931b41f | 40 | //The lack of indentation for namespaces is intentional... |
earlz | 0:217a7931b41f | 41 | using namespace std; |
earlz | 0:217a7931b41f | 42 | |
earlz | 0:217a7931b41f | 43 | MemorySystem::MemorySystem() |
earlz | 0:217a7931b41f | 44 | { |
earlz | 0:217a7931b41f | 45 | locked=0; |
earlz | 0:217a7931b41f | 46 | } |
earlz | 0:217a7931b41f | 47 | /**Because we must resize the list with realloc, we use malloc through out this for safety.**/ |
earlz | 0:217a7931b41f | 48 | void MemorySystem::Add(uint32_t low,uint32_t high,MemoryDevice *memdev){ |
earlz | 0:217a7931b41f | 49 | DeviceRange_t device; |
earlz | 0:217a7931b41f | 50 | |
earlz | 0:217a7931b41f | 51 | /* Check For Overlapping Addresses */ |
earlz | 0:217a7931b41f | 52 | Serial pc(USBTX, USBRX); // tx, rx |
earlz | 0:217a7931b41f | 53 | pc.printf("memorysystem add\n"); |
earlz | 0:217a7931b41f | 54 | for(unsigned int i = 0; i < memorySystemVector.size(); i++) |
earlz | 0:217a7931b41f | 55 | { |
earlz | 0:217a7931b41f | 56 | device = memorySystemVector[i]; |
earlz | 0:217a7931b41f | 57 | |
earlz | 0:217a7931b41f | 58 | if( device.high <= high && |
earlz | 0:217a7931b41f | 59 | device.low >= low ) |
earlz | 0:217a7931b41f | 60 | { |
earlz | 0:217a7931b41f | 61 | pc.printf("System_excp\n"); |
earlz | 0:217a7931b41f | 62 | exit(1); |
earlz | 0:217a7931b41f | 63 | } |
earlz | 0:217a7931b41f | 64 | } |
earlz | 0:217a7931b41f | 65 | pc.printf("high: 0x%x low: 0x%x\n",high,low); |
earlz | 0:217a7931b41f | 66 | device.high = high; |
earlz | 0:217a7931b41f | 67 | device.low = low; |
earlz | 0:217a7931b41f | 68 | device.memdev = memdev; |
earlz | 0:217a7931b41f | 69 | |
earlz | 0:217a7931b41f | 70 | /* Place Device in Memory System Vector */ |
earlz | 0:217a7931b41f | 71 | memorySystemVector.push_back( device ); |
earlz | 0:217a7931b41f | 72 | } |
earlz | 0:217a7931b41f | 73 | |
earlz | 0:217a7931b41f | 74 | void MemorySystem::Remove(uint32_t low,uint32_t high) |
earlz | 0:217a7931b41f | 75 | { |
earlz | 0:217a7931b41f | 76 | |
earlz | 0:217a7931b41f | 77 | } |
earlz | 0:217a7931b41f | 78 | |
earlz | 0:217a7931b41f | 79 | void MemorySystem::Remove(MemoryDevice *memdev) |
earlz | 0:217a7931b41f | 80 | { |
earlz | 0:217a7931b41f | 81 | } |
earlz | 0:217a7931b41f | 82 | void MemorySystem::Read(uint32_t address,int size,void *b) |
earlz | 0:217a7931b41f | 83 | { |
earlz | 0:217a7931b41f | 84 | uint32_t* buffer=(uint32_t*)b; |
earlz | 0:217a7931b41f | 85 | DeviceRange_t device; |
earlz | 0:217a7931b41f | 86 | |
earlz | 0:217a7931b41f | 87 | if(size == 0) |
earlz | 0:217a7931b41f | 88 | { |
earlz | 0:217a7931b41f | 89 | return; |
earlz | 0:217a7931b41f | 90 | } |
earlz | 0:217a7931b41f | 91 | |
earlz | 0:217a7931b41f | 92 | size--; |
earlz | 0:217a7931b41f | 93 | |
earlz | 0:217a7931b41f | 94 | for(unsigned int i = 0; i < memorySystemVector.size(); i++) |
earlz | 0:217a7931b41f | 95 | { |
earlz | 0:217a7931b41f | 96 | device = memorySystemVector[i]; |
earlz | 0:217a7931b41f | 97 | if(device.low <= address && |
earlz | 0:217a7931b41f | 98 | device.high >= address) |
earlz | 0:217a7931b41f | 99 | { |
earlz | 0:217a7931b41f | 100 | //we found a region matching. |
earlz | 0:217a7931b41f | 101 | if( (address + size) > device.high ) |
earlz | 0:217a7931b41f | 102 | { |
earlz | 0:217a7931b41f | 103 | //One device range will not cover the whole request. |
earlz | 0:217a7931b41f | 104 | device.memdev->Read(address, device.high - address + 1, buffer); |
earlz | 0:217a7931b41f | 105 | size -= device.high - address; |
earlz | 0:217a7931b41f | 106 | |
earlz | 0:217a7931b41f | 107 | buffer += device.high - address + 1; //bug? |
earlz | 0:217a7931b41f | 108 | |
earlz | 0:217a7931b41f | 109 | address += device.high - address + 1; |
earlz | 0:217a7931b41f | 110 | Read( address, size+1 , buffer ); |
earlz | 0:217a7931b41f | 111 | } |
earlz | 0:217a7931b41f | 112 | else |
earlz | 0:217a7931b41f | 113 | { |
earlz | 0:217a7931b41f | 114 | //correct absolute address to a relative one |
earlz | 0:217a7931b41f | 115 | address-=device.low; |
earlz | 0:217a7931b41f | 116 | device.memdev->Read(address, size + 1, buffer); |
earlz | 0:217a7931b41f | 117 | } |
earlz | 0:217a7931b41f | 118 | return; |
earlz | 0:217a7931b41f | 119 | } |
earlz | 0:217a7931b41f | 120 | } |
earlz | 0:217a7931b41f | 121 | Onx86LibError(); |
earlz | 0:217a7931b41f | 122 | //throw Mem_excp(address); |
earlz | 0:217a7931b41f | 123 | } |
earlz | 0:217a7931b41f | 124 | |
earlz | 0:217a7931b41f | 125 | |
earlz | 0:217a7931b41f | 126 | |
earlz | 0:217a7931b41f | 127 | void MemorySystem::Write(uint32_t address,int size,void *b) |
earlz | 0:217a7931b41f | 128 | { |
earlz | 0:217a7931b41f | 129 | uint32_t *buffer=(uint32_t*)b; |
earlz | 0:217a7931b41f | 130 | DeviceRange_t device; |
earlz | 0:217a7931b41f | 131 | |
earlz | 0:217a7931b41f | 132 | if( size==0 ) |
earlz | 0:217a7931b41f | 133 | { |
earlz | 0:217a7931b41f | 134 | return; |
earlz | 0:217a7931b41f | 135 | } |
earlz | 0:217a7931b41f | 136 | |
earlz | 0:217a7931b41f | 137 | size--; |
earlz | 0:217a7931b41f | 138 | |
earlz | 0:217a7931b41f | 139 | for( unsigned int i = 0; i < memorySystemVector.size(); i++ ) |
earlz | 0:217a7931b41f | 140 | { |
earlz | 0:217a7931b41f | 141 | device = memorySystemVector[i]; |
earlz | 0:217a7931b41f | 142 | |
earlz | 0:217a7931b41f | 143 | if(device.low <= address && |
earlz | 0:217a7931b41f | 144 | device.high >= address) |
earlz | 0:217a7931b41f | 145 | { |
earlz | 0:217a7931b41f | 146 | //we found a region matching. |
earlz | 0:217a7931b41f | 147 | if( (address + size) > device.high) |
earlz | 0:217a7931b41f | 148 | { |
earlz | 0:217a7931b41f | 149 | //One device range will not cover the whole request. |
earlz | 0:217a7931b41f | 150 | device.memdev->Write(address, device.high - address + 1, buffer); |
earlz | 0:217a7931b41f | 151 | |
earlz | 0:217a7931b41f | 152 | size -= device.high - address; |
earlz | 0:217a7931b41f | 153 | |
earlz | 0:217a7931b41f | 154 | buffer += device.high - address; |
earlz | 0:217a7931b41f | 155 | |
earlz | 0:217a7931b41f | 156 | address += device.high - address + 1; |
earlz | 0:217a7931b41f | 157 | |
earlz | 0:217a7931b41f | 158 | Write(address , size + 1, buffer); |
earlz | 0:217a7931b41f | 159 | } |
earlz | 0:217a7931b41f | 160 | else |
earlz | 0:217a7931b41f | 161 | { |
earlz | 0:217a7931b41f | 162 | //correct absolute address to a relative one |
earlz | 0:217a7931b41f | 163 | address-=device.low; |
earlz | 0:217a7931b41f | 164 | device.memdev->Write(address,size+1,buffer); |
earlz | 0:217a7931b41f | 165 | } |
earlz | 0:217a7931b41f | 166 | return; |
earlz | 0:217a7931b41f | 167 | } |
earlz | 0:217a7931b41f | 168 | } |
earlz | 0:217a7931b41f | 169 | Onx86LibError(); |
earlz | 0:217a7931b41f | 170 | //throw Mem_excp(address); |
earlz | 0:217a7931b41f | 171 | } |
earlz | 0:217a7931b41f | 172 | |
earlz | 0:217a7931b41f | 173 | int MemorySystem::RangeFree(uint32_t low,uint32_t high) |
earlz | 0:217a7931b41f | 174 | { |
earlz | 0:217a7931b41f | 175 | return 1; |
earlz | 0:217a7931b41f | 176 | } |
earlz | 0:217a7931b41f | 177 | |
earlz | 0:217a7931b41f | 178 | |
earlz | 0:217a7931b41f | 179 | |
earlz | 0:217a7931b41f | 180 | PortSystem::PortSystem(){ |
earlz | 0:217a7931b41f | 181 | count=0; |
earlz | 0:217a7931b41f | 182 | //list=NULL; |
earlz | 0:217a7931b41f | 183 | } |
earlz | 0:217a7931b41f | 184 | void PortSystem::Add(uint16_t low,uint16_t high,PortDevice *portdev){ |
earlz | 0:217a7931b41f | 185 | int i; |
earlz | 0:217a7931b41f | 186 | for(i=0;i<count;i++){ |
earlz | 0:217a7931b41f | 187 | if(list[i].high<=high && list[i].low>=low){ |
earlz | 0:217a7931b41f | 188 | Onx86LibError(); |
earlz | 0:217a7931b41f | 189 | //throw new System_excp(); |
earlz | 0:217a7931b41f | 190 | } |
earlz | 0:217a7931b41f | 191 | } |
earlz | 0:217a7931b41f | 192 | if(count==0){ |
earlz | 0:217a7931b41f | 193 | list=(DeviceRange_t*)malloc(sizeof(DeviceRange_t)*1); |
earlz | 0:217a7931b41f | 194 | //count++; |
earlz | 0:217a7931b41f | 195 | }else{ |
earlz | 0:217a7931b41f | 196 | void *t=list; |
earlz | 0:217a7931b41f | 197 | list=(DeviceRange_t*)realloc(list,sizeof(DeviceRange_t)*count+1); |
earlz | 0:217a7931b41f | 198 | if(list==NULL){ |
earlz | 0:217a7931b41f | 199 | list=(DeviceRange_t*)t; //restore old pointer so we can free it |
earlz | 0:217a7931b41f | 200 | Onx86LibError(); |
earlz | 0:217a7931b41f | 201 | //throw Default_excp(__FILE__,__FUNCTION__,__LINE__); |
earlz | 0:217a7931b41f | 202 | } |
earlz | 0:217a7931b41f | 203 | //count++; |
earlz | 0:217a7931b41f | 204 | } |
earlz | 0:217a7931b41f | 205 | list[count].high=high; |
earlz | 0:217a7931b41f | 206 | list[count].low=low; |
earlz | 0:217a7931b41f | 207 | list[count].portdev=portdev; |
earlz | 0:217a7931b41f | 208 | count++; |
earlz | 0:217a7931b41f | 209 | } |
earlz | 0:217a7931b41f | 210 | |
earlz | 0:217a7931b41f | 211 | |
earlz | 0:217a7931b41f | 212 | |
earlz | 0:217a7931b41f | 213 | void PortSystem::Read(uint16_t address,int size,void *buffer){ |
earlz | 0:217a7931b41f | 214 | int i; |
earlz | 0:217a7931b41f | 215 | if(size==0){return;} |
earlz | 0:217a7931b41f | 216 | size=size-1; |
earlz | 0:217a7931b41f | 217 | for(i=0;i<count;i++){ |
earlz | 0:217a7931b41f | 218 | if(list[i].low<=address && list[i].high>=address){ |
earlz | 0:217a7931b41f | 219 | //we found a region matching. |
earlz | 0:217a7931b41f | 220 | list[i].portdev->Read(address,size+1,buffer); |
earlz | 0:217a7931b41f | 221 | return; |
earlz | 0:217a7931b41f | 222 | } |
earlz | 0:217a7931b41f | 223 | } |
earlz | 0:217a7931b41f | 224 | Onx86LibError(); |
earlz | 0:217a7931b41f | 225 | //throw Mem_excp(address); |
earlz | 0:217a7931b41f | 226 | } |
earlz | 0:217a7931b41f | 227 | |
earlz | 0:217a7931b41f | 228 | |
earlz | 0:217a7931b41f | 229 | |
earlz | 0:217a7931b41f | 230 | void PortSystem::Write(uint16_t address,int size,void *buffer){ |
earlz | 0:217a7931b41f | 231 | int i; |
earlz | 0:217a7931b41f | 232 | if(size==0){return;} |
earlz | 0:217a7931b41f | 233 | size=size-1; |
earlz | 0:217a7931b41f | 234 | for(i=0;i<count;i++){ |
earlz | 0:217a7931b41f | 235 | if(list[i].low<=address && list[i].high>=address){ |
earlz | 0:217a7931b41f | 236 | list[i].portdev->Write(address,size+1,buffer); |
earlz | 0:217a7931b41f | 237 | return; |
earlz | 0:217a7931b41f | 238 | } |
earlz | 0:217a7931b41f | 239 | } |
earlz | 0:217a7931b41f | 240 | Onx86LibError(); |
earlz | 0:217a7931b41f | 241 | //throw Mem_excp(address); |
earlz | 0:217a7931b41f | 242 | } |
earlz | 0:217a7931b41f | 243 | |
earlz | 0:217a7931b41f | 244 | void Remove(uint16_t low,uint16_t high){} |
earlz | 0:217a7931b41f | 245 | void Remove(PortDevice *portdev){} |
earlz | 0:217a7931b41f | 246 | int RangeFree(uint32_t low,uint32_t high){return 1;} |
earlz | 0:217a7931b41f | 247 | |
earlz | 0:217a7931b41f | 248 | |
earlz | 0:217a7931b41f | 249 | |
earlz | 0:217a7931b41f | 250 | |
earlz | 0:217a7931b41f | 251 | }; |
earlz | 0:217a7931b41f | 252 |