2021-12-22 14:11:55 +00:00
|
|
|
#ifndef APPLE1_H
|
|
|
|
#define APPLE1_H
|
|
|
|
|
2022-01-14 11:28:28 +00:00
|
|
|
#pragma encoding(ascii) // encode strings in plain ascii
|
|
|
|
|
2022-01-06 17:56:04 +00:00
|
|
|
#ifdef APPLE1_USE_WOZ_MONITOR
|
|
|
|
#pragma zp_reserve(0x24) // XAML Last "opened" location Low
|
|
|
|
#pragma zp_reserve(0x25) // XAMH Last "opened" location High
|
|
|
|
#pragma zp_reserve(0x26) // STL Store address Low
|
|
|
|
#pragma zp_reserve(0x27) // STH Store address High
|
|
|
|
#pragma zp_reserve(0x28) // L Hex value parsing Low
|
|
|
|
#pragma zp_reserve(0x29) // H Hex value parsing High
|
|
|
|
#pragma zp_reserve(0x2A) // YSAV Used to see if hex value is given
|
|
|
|
#pragma zp_reserve(0x2B) // MODE $00=XAM, $7F=STOR, $AE=BLOCK XAM
|
|
|
|
#endif
|
|
|
|
|
2022-02-07 08:26:32 +00:00
|
|
|
// APPLE1
|
|
|
|
const word WOZMON = 0xFF1F; // enters monitor
|
|
|
|
const word ECHO = 0xFFEF; // output ascii character in A (A not destroyed)
|
|
|
|
const word PRBYTE = 0xFFDC; // print hex byte in A (A destroyed)
|
|
|
|
const word KEY_DATA = 0xd010; // read key
|
|
|
|
const word KEY_CTRL = 0xd011; // control port
|
|
|
|
const word TERM_DATA = 0xd012; // write ascii
|
|
|
|
const word TERM_CTRL = 0xd013; // control port
|
|
|
|
const word INBUFFER = 0x0200; // woz monitor input buffer
|
|
|
|
const word INBUFSIZE = 0x80; // woz monitor input buffer size
|
2021-12-08 11:53:13 +00:00
|
|
|
|
|
|
|
// prints a hex byte using the WOZMON routine
|
2021-12-15 13:38:52 +00:00
|
|
|
void woz_print_hex(byte c) {
|
2022-02-07 08:26:32 +00:00
|
|
|
asm {
|
|
|
|
lda c
|
|
|
|
jsr PRBYTE
|
|
|
|
};
|
2021-12-08 11:53:13 +00:00
|
|
|
}
|
|
|
|
|
2022-01-31 10:03:57 +00:00
|
|
|
// print hex word
|
|
|
|
void woz_print_hexword(word w) {
|
|
|
|
woz_print_hex(*((byte *)&w+1));
|
|
|
|
woz_print_hex(*((byte *)&w));
|
|
|
|
}
|
|
|
|
|
2021-12-08 11:53:13 +00:00
|
|
|
// puts a character on the apple1 screen using the WOZMON routine
|
|
|
|
void woz_putc(byte c) {
|
|
|
|
asm {
|
|
|
|
lda c
|
|
|
|
jsr ECHO
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// puts a 0-terminated string on the apple1 screen
|
|
|
|
void woz_puts(byte *s) {
|
|
|
|
byte c;
|
|
|
|
while(c=*s++) woz_putc(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
// returns to WOZMON prompt
|
|
|
|
void woz_mon() {
|
2022-02-07 08:26:32 +00:00
|
|
|
asm {
|
|
|
|
jmp WOZMON
|
|
|
|
}
|
2021-12-08 11:53:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// returns nonzero if a key has been pressed
|
2022-02-07 08:26:32 +00:00
|
|
|
inline byte apple1_iskeypressed() {
|
|
|
|
return PEEK(KEY_CTRL) & 0x80;
|
2021-12-08 11:53:13 +00:00
|
|
|
}
|
|
|
|
|
2021-12-15 13:38:52 +00:00
|
|
|
// blocking keyboard read
|
2021-12-08 11:53:13 +00:00
|
|
|
// reads a key from the apple-1 keyboard
|
2021-12-15 13:38:52 +00:00
|
|
|
byte apple1_getkey() {
|
2022-02-07 08:26:32 +00:00
|
|
|
asm {
|
|
|
|
__wait:
|
|
|
|
lda KEY_CTRL
|
|
|
|
bpl __wait
|
|
|
|
}
|
|
|
|
return PEEK(KEY_DATA) & 0x7f;
|
2021-12-08 11:53:13 +00:00
|
|
|
}
|
2021-12-14 17:40:01 +00:00
|
|
|
|
|
|
|
// non blocking keyboard read
|
|
|
|
// reads a key and return 0 if no key is pressed
|
2021-12-15 13:38:52 +00:00
|
|
|
byte apple1_readkey() {
|
2022-02-07 08:26:32 +00:00
|
|
|
if((PEEK(KEY_CTRL) & 0x80)==0) return 0;
|
|
|
|
else return PEEK(KEY_DATA) & 0x7f;
|
2021-12-14 17:40:01 +00:00
|
|
|
}
|
2021-12-15 13:38:52 +00:00
|
|
|
|
2022-01-18 14:15:48 +00:00
|
|
|
void apple1_input_line(byte *buffer, byte max) {
|
|
|
|
byte x=0;
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
byte c = apple1_getkey();
|
|
|
|
buffer[x] = c;
|
|
|
|
if(c==13) {
|
|
|
|
// RETURN ends input
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if(c==27) {
|
|
|
|
// ESC clears the string
|
|
|
|
x=0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if(c==8 || c=='_') {
|
|
|
|
// BACKSPACE
|
|
|
|
if(x != 0) {
|
|
|
|
woz_putc('_');
|
|
|
|
x--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// character input
|
|
|
|
if(x<max) {
|
|
|
|
woz_putc(c);
|
|
|
|
x++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buffer[x]=0;
|
|
|
|
}
|
|
|
|
|
2022-02-15 16:44:37 +00:00
|
|
|
#ifndef INPUT_LINE_PROMPT_CHAR
|
|
|
|
#define INPUT_LINE_PROMPT_CHAR '>'
|
|
|
|
#endif
|
2022-02-13 17:49:15 +00:00
|
|
|
|
|
|
|
void apple1_input_line_prompt(byte *buffer, byte max) {
|
|
|
|
byte x=0;
|
|
|
|
|
2022-02-15 16:44:37 +00:00
|
|
|
woz_putc(INPUT_LINE_PROMPT_CHAR);
|
2022-02-13 17:49:15 +00:00
|
|
|
|
|
|
|
while(1) {
|
|
|
|
byte c = apple1_getkey();
|
|
|
|
buffer[x] = c;
|
|
|
|
if(c==13) {
|
|
|
|
// RETURN ends input
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if(c==27) {
|
|
|
|
// ESC clears the string
|
|
|
|
x=0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if(c==8 || c=='_') {
|
|
|
|
// BACKSPACE
|
|
|
|
if(x != 0) {
|
|
|
|
x--;
|
|
|
|
buffer[x] = 0;
|
|
|
|
woz_putc('\r');
|
2022-02-15 16:44:37 +00:00
|
|
|
woz_putc(INPUT_LINE_PROMPT_CHAR);
|
2022-02-13 17:49:15 +00:00
|
|
|
woz_puts(buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// character input
|
|
|
|
if(x<max) {
|
|
|
|
woz_putc(c);
|
|
|
|
x++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buffer[x]=0;
|
|
|
|
}
|
|
|
|
|
2021-12-15 13:38:52 +00:00
|
|
|
#include <stdlib.h> // for memcpy
|
|
|
|
|
|
|
|
#define LOWRAM_START 0x280
|
|
|
|
#define LOWRAM_END 0x7FF
|
|
|
|
#define LOWRAM_SIZE (LOWRAM_END - LOWRAM_START + 1)
|
|
|
|
#define DATAINCODE (0x8000 - LOWRAM_SIZE)
|
|
|
|
|
|
|
|
inline void apple1_eprom_init() {
|
|
|
|
// copy the initializaton data from ROM to lowram where "Data" segment is allocated
|
2021-12-23 13:28:59 +00:00
|
|
|
memcpy((byte *)LOWRAM_START, (byte *)DATAINCODE, LOWRAM_SIZE);
|
2021-12-15 13:38:52 +00:00
|
|
|
}
|
2021-12-22 14:11:55 +00:00
|
|
|
|
2022-02-07 08:26:32 +00:00
|
|
|
#endif
|