mirror of
https://github.com/ArthurFerreira2/reinette-II.git
synced 2024-12-22 05:29:27 +00:00
Update reinette-II.c
This commit is contained in:
parent
a0c32d6c40
commit
daf04c9130
@ -25,10 +25,6 @@
|
|||||||
|
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
|
|
||||||
#define ROMSTART 0xD000
|
|
||||||
#define ROMSIZE 0x3000 // 12KB
|
|
||||||
#define RAMSIZE 0xC000 // 48KB
|
|
||||||
|
|
||||||
#define CARRY 0x01
|
#define CARRY 0x01
|
||||||
#define ZERO 0x02
|
#define ZERO 0x02
|
||||||
#define INTERRUPT 0x04
|
#define INTERRUPT 0x04
|
||||||
@ -38,6 +34,10 @@
|
|||||||
#define OVERFLOW 0x40
|
#define OVERFLOW 0x40
|
||||||
#define SIGN 0x80
|
#define SIGN 0x80
|
||||||
|
|
||||||
|
#define ROMSTART 0xD000
|
||||||
|
#define ROMSIZE 0x3000 // 12KB
|
||||||
|
#define RAMSIZE 0xC000 // 48KB
|
||||||
|
|
||||||
uint8_t rom[ROMSIZE];
|
uint8_t rom[ROMSIZE];
|
||||||
uint8_t ram[RAMSIZE];
|
uint8_t ram[RAMSIZE];
|
||||||
|
|
||||||
@ -59,35 +59,23 @@ bool videoNeedsRefresh = true;
|
|||||||
|
|
||||||
static uint8_t readMem(uint16_t address){
|
static uint8_t readMem(uint16_t address){
|
||||||
if (address < RAMSIZE) return(ram[address]);
|
if (address < RAMSIZE) return(ram[address]);
|
||||||
else if (address >= ROMSTART) return(rom[address - ROMSTART]);
|
if (address >= ROMSTART) return(rom[address - ROMSTART]);
|
||||||
else if (address == 0xC000) return(key); // KBD
|
if (address == 0xC000) return(key); // KBD
|
||||||
else if (address == 0xC010){ // KBDSTRB
|
if (address == 0xC010){ // KBDSTRB
|
||||||
key &= 0x7F; // unset bit 7
|
key &= 0x7F; // unset bit 7
|
||||||
return(key);
|
return(key);
|
||||||
}
|
}
|
||||||
else return(0); // catch all
|
return(0); // catch all
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeMem(uint16_t address, uint8_t value){
|
static void writeMem(uint16_t address, uint8_t value){
|
||||||
if (address & 0x400) videoNeedsRefresh = true; // a change in text page 1
|
if (address & 0x400) videoNeedsRefresh = true; // a change in text page 1
|
||||||
if (address < RAMSIZE) ram[address] = value;
|
if (address < RAMSIZE) ram[address] = value;
|
||||||
else if (address == 0xC010) key &= 0x7F; // KBDSTRB, similar as in readMem
|
else if (address == 0xC010) key &= 0x7F; // KBDSTRB, as in readMem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// RESET
|
// STACK, FLAGS AND RESET ROUTINES
|
||||||
|
|
||||||
static void reset(){
|
|
||||||
reg.PC = readMem(0xFFFC) | (readMem(0xFFFD) << 8);
|
|
||||||
reg.SP = 0xFF;
|
|
||||||
reg.SR |= UNDEFINED;
|
|
||||||
ope.setAcc = false;
|
|
||||||
ope.value = 0;
|
|
||||||
ope.address = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// STACK, SIGN AND ZERO FLAGS ROUTINES
|
|
||||||
|
|
||||||
static void push(uint8_t value){
|
static void push(uint8_t value){
|
||||||
writeMem(0x100 + reg.SP--, value);
|
writeMem(0x100 + reg.SP--, value);
|
||||||
@ -104,6 +92,10 @@ static void setSZ(uint8_t value){ // update both the Sign & Zero FLAGS
|
|||||||
else reg.SR &= ~SIGN;
|
else reg.SR &= ~SIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reset(){ // the reset vector is in $FFFC
|
||||||
|
reg.PC = readMem(0xFFFC) | (readMem(0xFFFD) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ADDRESSING MODES
|
// ADDRESSING MODES
|
||||||
|
|
||||||
@ -437,7 +429,7 @@ static void ROR(){ // ROtate Right
|
|||||||
static void ADC(){ // ADd with Carry
|
static void ADC(){ // ADd with Carry
|
||||||
uint16_t result = reg.A + ope.value + (reg.SR & CARRY);
|
uint16_t result = reg.A + ope.value + (reg.SR & CARRY);
|
||||||
setSZ(result);
|
setSZ(result);
|
||||||
if (((result)^(reg.A ))&((result)^(ope.value))&0x0080) reg.SR |= OVERFLOW;
|
if (((result)^(reg.A )) & ((result)^(ope.value)) & 0x80) reg.SR |= OVERFLOW;
|
||||||
else reg.SR &= ~OVERFLOW;
|
else reg.SR &= ~OVERFLOW;
|
||||||
if (reg.SR&DECIMAL) result += ((((result+0x66)^reg.A^ope.value)>>3) & 0x22)*3;
|
if (reg.SR&DECIMAL) result += ((((result+0x66)^reg.A^ope.value)>>3) & 0x22)*3;
|
||||||
if (result & 0xFF00) reg.SR |= CARRY;
|
if (result & 0xFF00) reg.SR |= CARRY;
|
||||||
@ -445,12 +437,12 @@ static void ADC(){ // ADd with Carry
|
|||||||
reg.A = (result & 0xFF);
|
reg.A = (result & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SBC(){ // SuBtract with Carry
|
static void SBC(){ // SuBtract with Carry : forum.6502.org/viewtopic.php?t=475
|
||||||
ope.value ^= 0xFF;
|
ope.value ^= 0xFF;
|
||||||
if (reg.SR & DECIMAL) ope.value -= 0x0066;
|
if (reg.SR & DECIMAL) ope.value -= 0x66;
|
||||||
uint16_t result = reg.A + ope.value + (reg.SR & CARRY);
|
uint16_t result = reg.A + ope.value + (reg.SR & CARRY);
|
||||||
setSZ(result);
|
setSZ(result);
|
||||||
if (((result)^(reg.A ))&((result)^(ope.value))&0x0080) reg.SR |= OVERFLOW;
|
if (((result)^(reg.A )) & ((result)^(ope.value)) & 0x80) reg.SR |= OVERFLOW;
|
||||||
else reg.SR &= ~OVERFLOW;
|
else reg.SR &= ~OVERFLOW;
|
||||||
if (reg.SR&DECIMAL) result += ((((result+0x66)^reg.A^ope.value)>>3) & 0x22)*3;
|
if (reg.SR&DECIMAL) result += ((((result+0x66)^reg.A^ope.value)>>3) & 0x22)*3;
|
||||||
if (result & 0xFF00) reg.SR |= CARRY;
|
if (result & 0xFF00) reg.SR |= CARRY;
|
||||||
@ -507,7 +499,7 @@ static void (*addressing[])(void) = {
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
static uint16_t offsetsForRows[24] = { // helper for video generation
|
const uint16_t offsetsForRows[24] = { // helper for video generation
|
||||||
0x400, 0x480, 0x500, 0x580, 0x600, 0x680, 0x700, 0x780,
|
0x400, 0x480, 0x500, 0x580, 0x600, 0x680, 0x700, 0x780,
|
||||||
0x428, 0x4A8, 0x528, 0x5A8, 0x628, 0x6A8, 0x728, 0x7A8,
|
0x428, 0x4A8, 0x528, 0x5A8, 0x628, 0x6A8, 0x728, 0x7A8,
|
||||||
0x450, 0x4D0, 0x550, 0x5D0, 0x650, 0x6D0, 0x750, 0x7D0
|
0x450, 0x4D0, 0x550, 0x5D0, 0x650, 0x6D0, 0x750, 0x7D0
|
||||||
@ -523,7 +515,7 @@ int main(int argc, char *argv[]) {
|
|||||||
qiflush();
|
qiflush();
|
||||||
keypad (stdscr, TRUE);
|
keypad (stdscr, TRUE);
|
||||||
nodelay (stdscr, TRUE);
|
nodelay (stdscr, TRUE);
|
||||||
scrollok (stdscr, TRUE);
|
scrollok (stdscr, FALSE);
|
||||||
|
|
||||||
// load the original Apple][ ROM, including the Programmer's Aid at $D000
|
// load the original Apple][ ROM, including the Programmer's Aid at $D000
|
||||||
FILE *f=fopen("appleII.rom","rb");
|
FILE *f=fopen("appleII.rom","rb");
|
||||||
@ -542,17 +534,17 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// slow down emulation
|
// slow down emulation
|
||||||
napms(1);
|
napms(0.6);
|
||||||
|
|
||||||
// keyboard controller
|
// keyboard controller
|
||||||
if ((ch = getch()) != ERR){
|
if ((key < 0x80) && ((ch = getch()) != ERR)){
|
||||||
if (ch == KEY_F( 7)) reset(); // F7, processor reset
|
if (ch == KEY_F( 7)) reset(); // F7, processor reset
|
||||||
if (ch == KEY_F(12)) { endwin(); return(0); } // F12, exit program
|
if (ch == KEY_F(12)) { endwin(); return(0); } // F12, exit program
|
||||||
switch(key=(uint8_t)ch){ // key translations
|
switch(key=(uint8_t)ch){ // key translations
|
||||||
case 0x0A: key = 0x0D; break; // LF to CR
|
case 0x0A: key = 0x0D; break; // LF to CR
|
||||||
case 0x04: key = 0x08; break; // LEFT to BS
|
case 0x04: key = 0x08; break; // LEFT to BS
|
||||||
case 0x05: key = 0x15; break; // RIGHT to NAK
|
case 0x05: key = 0x15; break; // RIGHT to NAK
|
||||||
case 0x07: key = 0x08; break; // BELL to BS ?
|
case 0x07: key = 0x08; break; // BELL to BS (!?)
|
||||||
}
|
}
|
||||||
if ((key>0x60) && (key<0x7B)) key&=0xDF; // to upper case
|
if ((key>0x60) && (key<0x7B)) key&=0xDF; // to upper case
|
||||||
key |= 0x80; // set bit 7
|
key |= 0x80; // set bit 7
|
||||||
@ -560,22 +552,21 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
// video controller - page 1 text mode only
|
// video controller - page 1 text mode only
|
||||||
if (videoNeedsRefresh){ // if content changed
|
if (videoNeedsRefresh){ // if content changed
|
||||||
move(0, 0);
|
videoNeedsRefresh = false;
|
||||||
for (int row=0; row<24; row++){ // for each row
|
for (int row=0; row<24; row++){ // for each row
|
||||||
|
move(row,0);
|
||||||
for (int col=0; col<40; col++){ // for each column
|
for (int col=0; col<40; col++){ // for each column
|
||||||
glyph = ram[offsetsForRows[row] + col]; // read video memory
|
glyph = ram[offsetsForRows[row] + col]; // read video memory
|
||||||
if (glyph == '`') glyph = '_'; // change cursor shape
|
if (glyph == '`') glyph = '_'; // change cursor shape
|
||||||
if (glyph < 0x40) attrset(A_REVERSE); // is REVERSE ?
|
if (glyph < 0x40) attrset(A_REVERSE); // is REVERSE ?
|
||||||
else if (glyph > 0x7F) attrset(A_NORMAL); // is NORMAL ?
|
else if (glyph > 0x7F) attrset(A_NORMAL); // is NORMAL ?
|
||||||
else attrset(A_BLINK); // it's FLASHING !
|
else attrset(A_BLINK); // is FLASHING ?
|
||||||
glyph &= 0x7F; // unset bit 7
|
glyph &= 0x7F; // unset bit 7
|
||||||
if (glyph > 0x5F) glyph &= 0x3F; // shifts to match
|
if (glyph > 0x5F) glyph &= 0x3F; // shifts to match
|
||||||
if (glyph < 0x20) glyph |= 0x40; // the ASCII codes
|
if (glyph < 0x20) glyph |= 0x40; // the ASCII codes
|
||||||
addch(glyph); // print the glyph
|
addch(glyph); // print the glyph
|
||||||
}
|
}
|
||||||
addch(0x0A); // to next row
|
}
|
||||||
}
|
|
||||||
videoNeedsRefresh = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user