thiagoauler-apple1/src/memory.c

114 lines
2.1 KiB
C
Raw Permalink Normal View History

2017-11-12 02:31:55 +00:00
#include "inc/types.h"
#include "inc/rom.h"
2017-11-26 22:30:04 +00:00
#include "inc/basic.h"
2017-11-12 02:31:55 +00:00
#include "inc/memory.h"
/*
2017-11-13 01:00:52 +00:00
memory model:
2017-11-12 02:31:55 +00:00
+ - - - - +
| 0000 |
| |
| |
| RAM |
| |
| |
2017-11-28 03:10:57 +00:00
| 7FFF |
2017-11-12 02:31:55 +00:00
+ - - - - +
| |
. . .
unused
. . .
| |
+ - - - - +
| FF00 |
| |
| ROM |
| |
| FFFF |
+ - - - - +
*/
2017-11-13 01:00:52 +00:00
2017-11-28 03:10:57 +00:00
db ram_memory[32 * 1024]; // total memory: 32KB
db keyboard_buffer; // 0xD010
db keyboard_control; // 0xD011
db display_buffer; // 0xD012
db display_control; // 0xD013
2017-11-12 02:31:55 +00:00
2017-11-13 03:02:14 +00:00
db read_byte(dw address)
2017-11-12 02:31:55 +00:00
{
2017-11-28 03:10:57 +00:00
if (address >= 0x0000 && address <= 0x7FFF)
2017-11-12 02:31:55 +00:00
{
2017-11-28 03:10:57 +00:00
// 32KB memory RAM
2017-11-13 01:00:52 +00:00
return ram_memory[address];
2017-11-12 02:31:55 +00:00
}
2017-11-28 11:36:42 +00:00
else if (address == 0xD010)
{
// when reading from keyboard buffer,
// its status control is disabled again
2017-11-21 17:02:06 +00:00
keyboard_control = 0x00;
return keyboard_buffer;
}
2017-11-28 11:36:42 +00:00
else if (address == 0xD011)
{
return keyboard_control;
}
2017-11-28 11:36:42 +00:00
else if (address == 0xD012)
{
return display_buffer;
}
2017-11-26 22:30:04 +00:00
else if (address >= 0xE000 && address <= 0xEFFF)
{
2017-11-28 11:36:42 +00:00
// BASIC
2017-11-26 22:30:04 +00:00
address = address & 0xFFF;
return basic_memory[address];
}
2017-11-13 01:00:52 +00:00
else if (address >= 0xFF00 && address <= 0xFFFF)
2017-11-12 02:31:55 +00:00
{
// wozmon ROM
2017-11-13 01:00:52 +00:00
address = address & 0x00FF;
return rom_memory[address];
2017-11-12 02:31:55 +00:00
}
else
{
2017-11-13 01:00:52 +00:00
// unused memory
return 0x00;
2017-11-12 02:31:55 +00:00
}
}
2017-11-13 03:02:14 +00:00
dw read_word(dw address)
{
dw word;
db low_byte;
db high_byte;
low_byte = read_byte(address);
high_byte = read_byte(address + 1);
word = high_byte << 8; // shifts high byte to its place
word = word | low_byte; // appends low byte to form the complete word
// the word is store in little-endian format on the memory
return word;
}
void write_mem(dw address, db data)
2017-11-12 02:31:55 +00:00
{
2017-11-28 03:10:57 +00:00
if (address >= 0x0000 && address <= 0x7FFF)
2017-11-12 02:31:55 +00:00
{
2017-11-28 03:10:57 +00:00
// 32KB memory RAM
2017-11-13 01:00:52 +00:00
ram_memory[address] = data;
2017-11-12 02:31:55 +00:00
}
2017-11-28 11:36:42 +00:00
else if (address == 0xD012)
2017-11-14 21:42:36 +00:00
{
display_buffer = data | 0x80;
2017-11-14 21:42:36 +00:00
}
2017-11-13 01:00:52 +00:00
// any other addressed memory will be ignored on write
2017-11-12 02:31:55 +00:00
}