diff --git a/demos/sdcard/cmd_dump.h b/demos/sdcard/cmd_dump.h index 7c86d2b..6a5df21 100644 --- a/demos/sdcard/cmd_dump.h +++ b/demos/sdcard/cmd_dump.h @@ -1,4 +1,7 @@ -void comando_dump(char *filename, word start, word end) { +// global start_address +// global end_address + +void comando_dump() { // send command byte send_byte_to_MCU(CMD_READ); @@ -18,8 +21,8 @@ void comando_dump(char *filename, word start, word end) { return; } - // get file length - word len = receive_word_from_mcu(); + // get file length in tmpword + receive_word_from_mcu(); if(TIMEOUT) return; // 1234567890123456789012345678901234567890 @@ -27,11 +30,11 @@ void comando_dump(char *filename, word start, word end) { // get file bytes byte row = 0; - for(word t=0;t!=len;t++) { + for(word t=0;t!=tmpword;t++) { byte data = receive_byte_from_MCU(); if(TIMEOUT) return; - if(!(t>=start && t<=end)) continue; + if(!(t>=start_address && t<=end_address)) continue; if(row == 0) { woz_putc('\r'); diff --git a/demos/sdcard/cmd_load.h b/demos/sdcard/cmd_load.h index d260934..c4c892f 100644 --- a/demos/sdcard/cmd_load.h +++ b/demos/sdcard/cmd_load.h @@ -4,7 +4,9 @@ // PRODOS format: // "A","1", 510 bytes low memory, basic program -void comando_load(char *filename, byte cmd) { +// global cmd + +void comando_load() { // send command byte send_byte_to_MCU(CMD_READ); @@ -24,13 +26,13 @@ void comando_load(char *filename, byte cmd) { return; } - // get file length - word len = receive_word_from_mcu(); + // get file length in tmpword + receive_word_from_mcu(); if(TIMEOUT) return; // get file bytes - byte *dest = (byte *) 0; - for(word t=0;t!=len;t++) { + token_ptr = (byte *) 0; + for(word t=0;t!=tmpword;t++) { byte data = receive_byte_from_MCU(); if(TIMEOUT) return; @@ -43,32 +45,28 @@ void comando_load(char *filename, byte cmd) { } else if(t<0x0100) { // writes in the zone $4a-$ff (BASIC pointers) - *dest = data; + *token_ptr = data; } else if(t<0x1ff) { // skip zone $100-$1ff (stack) } else if(t==0x1ff) { // basic program chuck follows, move the pointer - dest = (byte *) ((*BASIC_LOMEM) -1); // compensate for the increment in the loop + token_ptr = *BASIC_LOMEM; + token_ptr--; // compensate for the increment in the loop } else { // writes in the BASIC program zone - *dest = data; + *token_ptr = data; } - - dest++; + + token_ptr++; + #ifdef LOADING_DOTS if(((byte)t) == 0) woz_putc('.'); + #endif } - // print feedback to user - woz_putc('\r'); - woz_puts(filename); - woz_puts(": LOMEM="); - woz_print_hexword(*BASIC_LOMEM); - woz_puts(" HIMEM="); - woz_print_hexword(*BASIC_HIMEM); - woz_puts("\rOK"); + bas_file_info(); // executes basic program $EFEC = RUN entry point if(cmd == CMD_RUN) { @@ -78,3 +76,19 @@ void comando_load(char *filename, byte cmd) { } } } + +void bas_file_info() { + // print feedback to user + woz_putc('\r'); + woz_puts(filename); + woz_puts(": "); + bas_info(); + woz_puts("\rOK"); +} + +void bas_info() { + woz_puts("LOMEM="); + woz_print_hexword((word) *BASIC_LOMEM); + woz_puts(" HIMEM="); + woz_print_hexword((word) *BASIC_HIMEM); +} diff --git a/demos/sdcard/cmd_read.h b/demos/sdcard/cmd_read.h index bd1af3d..3874101 100644 --- a/demos/sdcard/cmd_read.h +++ b/demos/sdcard/cmd_read.h @@ -3,7 +3,12 @@ // MCU sends $00 + 2 bytes file length (MSB first) + file data bytes (if OK) // MCU sends $FF + string error description (if error) // -void comando_read(char *filename, word start) { + +// global start_address +// global len +// global token_ptr + +void comando_read() { // send command byte send_byte_to_MCU(CMD_READ); @@ -23,28 +28,34 @@ void comando_read(char *filename, word start) { return; } - // get file length - word len = receive_word_from_mcu(); + // get file length in tmpword + receive_word_from_mcu(); if(TIMEOUT) return; // get file bytes - byte *dest = (byte *) start; - for(word t=0;t!=len;t++) { + token_ptr = (byte *) start_address; + for(word t=0;t!=tmpword;t++) { byte data = receive_byte_from_MCU(); if(TIMEOUT) return; - *dest++ = data; + *token_ptr++ = data; + + #ifdef LOADING_DOTS if(((byte)t) == 0) woz_putc('.'); + #endif } + // decrease by one for display result + token_ptr--; + // print feedback to user woz_putc('\r'); woz_puts(filename); woz_puts(": "); - woz_print_hexword(start); + woz_print_hexword(start_address); woz_putc('.'); - woz_print_hexword(start+len-1); + woz_print_hexword((word)token_ptr); woz_puts(" ("); - utoa(len, filename, 10); // use filename as string buffer + utoa(tmpword, filename, 10); // use filename as string buffer woz_puts(filename); woz_puts(" BYTES)\rOK"); } diff --git a/demos/sdcard/cmd_save.h b/demos/sdcard/cmd_save.h index 8c3994e..eca2b4b 100644 --- a/demos/sdcard/cmd_save.h +++ b/demos/sdcard/cmd_save.h @@ -1,4 +1,6 @@ -void comando_save(char *filename) { +// global len + +void comando_save() { // send command byte send_byte_to_MCU(CMD_WRITE); @@ -18,8 +20,21 @@ void comando_save(char *filename) { } // send file size - word len = ((word) *BASIC_HIMEM) - ((word)*BASIC_LOMEM) + 512; - send_word_to_mcu(len); + //tmpword = ((word) *BASIC_HIMEM) - ((word)*BASIC_LOMEM) + 512; + // in assembly: + asm { + sec + lda BASIC_HIMEM + sbc BASIC_LOMEM + sta tmpword + lda BASIC_HIMEM+1 + sbc BASIC_LOMEM+1 + sta tmpword+1 + inc tmpword+1 + inc tmpword+1 + } + + send_word_to_mcu(); if(TIMEOUT) return; // send actual bytes @@ -30,16 +45,20 @@ void comando_save(char *filename) { if(TIMEOUT) return; // lowmem + stack chuck - for(byte *ptr=(byte *)2; ptr<=(byte *)0x1ff; ptr++) { - send_byte_to_MCU(*ptr); + for(token_ptr=(byte *)2; token_ptr<=(byte *)0x1ff; token_ptr++) { + send_byte_to_MCU(*token_ptr); if(TIMEOUT) return; } // basic data - for(word ptr=*BASIC_LOMEM; ptr<*BASIC_HIMEM; ptr++) { - send_byte_to_MCU(*((byte *)ptr)); + tmpword = (word) *BASIC_HIMEM; + for(token_ptr=*BASIC_LOMEM; token_ptr<(byte *)tmpword; token_ptr++) { + send_byte_to_MCU(*token_ptr); if(TIMEOUT) return; - if(((byte)ptr) == 0) woz_putc('.'); + + #ifdef LOADING_DOTS + if(((byte)token_ptr) == 0) woz_putc('.'); + #endif } // get second response @@ -51,12 +70,5 @@ void comando_save(char *filename) { return; } - // print feedback to user - woz_putc('\r'); - woz_puts(filename); - woz_puts(": LOMEM="); - woz_print_hexword(*BASIC_LOMEM); - woz_puts(" HIMEM="); - woz_print_hexword(*BASIC_HIMEM); - woz_puts("\rOK"); + bas_file_info(); } diff --git a/demos/sdcard/cmd_type.h b/demos/sdcard/cmd_type.h index b082567..572c879 100644 --- a/demos/sdcard/cmd_type.h +++ b/demos/sdcard/cmd_type.h @@ -1,4 +1,4 @@ -void comando_type(char *filename) { +void comando_type() { // send command byte send_byte_to_MCU(CMD_READ); @@ -18,12 +18,12 @@ void comando_type(char *filename) { return; } - // get file length - word len = receive_word_from_mcu(); + // get file length in tmpword + receive_word_from_mcu(); if(TIMEOUT) return; // get file bytes - for(word t=0;t!=len;t++) { + for(word t=0;t!=tmpword;t++) { byte data = receive_byte_from_MCU(); if(TIMEOUT) return; woz_putc(data); diff --git a/demos/sdcard/cmd_write.h b/demos/sdcard/cmd_write.h index 5942693..0e14758 100644 --- a/demos/sdcard/cmd_write.h +++ b/demos/sdcard/cmd_write.h @@ -1,4 +1,8 @@ -void comando_write(char *filename, word start, word end) { +// gloabl start_address +// global end_address +// gloabl len + +void comando_write() { // send command byte send_byte_to_MCU(CMD_WRITE); @@ -18,16 +22,30 @@ void comando_write(char *filename, word start, word end) { } // send file size - word len = end-start + 1; - send_word_to_mcu(len); + //tmpword = (word) end_address - (word) start_address + 1; // KickC bug: (word) cast is needed + asm { + sec + lda end_address + sbc start_address + sta tmpword + lda end_address+1 + sbc start_address+1 + sta tmpword+1 + } + tmpword++; + + send_word_to_mcu(); if(TIMEOUT) return; // send actual bytes - byte *ptr = (byte *) start; - for(word t=0;t #include -word *const BASIC_LOMEM = (word *) 0x004a; // lomem pointer used by integer BASIC -word *const BASIC_HIMEM = (word *) 0x004c; // himem pointer used by integer BASIC -byte *const KEYBUF = (byte *) 0x0200; // use the same keyboard buffer as in WOZ monitor +byte **const BASIC_LOMEM = (byte **) 0x004a; // lomem pointer used by integer BASIC +byte **const BASIC_HIMEM = (byte **) 0x004c; // himem pointer used by integer BASIC +byte *const KEYBUF = (byte *) 0x0200; // use the same keyboard buffer as in WOZ monitor #define KEYBUFSTART (0x200) #define KEYBUFLEN (40) @@ -18,16 +18,18 @@ byte *const hex2 = (byte *) (KEYBUFSTART+KEYBUFLEN+6+33+5); // [5] stores a const byte ERR_RESPONSE = 0xFF; // command constants, which are also byte commands to send to the MCU -const byte CMD_READ = 0; -const byte CMD_WRITE = 1; -const byte CMD_DIR = 2; -const byte CMD_TIME = 3; -const byte CMD_LOAD = 4; -const byte CMD_RUN = 5; -const byte CMD_SAVE = 6; -const byte CMD_TYPE = 7; -const byte CMD_DUMP = 8; -const byte CMD_EXIT = 9; +const byte CMD_READ = 0; +const byte CMD_WRITE = 1; +const byte CMD_DIR = 2; +const byte CMD_TIME = 3; +const byte CMD_LOAD = 4; +const byte CMD_RUN = 5; +const byte CMD_SAVE = 6; +const byte CMD_TYPE = 7; +const byte CMD_DUMP = 8; +const byte CMD_JMP = 9; +const byte CMD_BAS = 10; +const byte CMD_EXIT = 11; // the list of recognized commands byte *DOS_COMMANDS[] = { @@ -40,6 +42,8 @@ byte *DOS_COMMANDS[] = { "SAVE", "TYPE", "DUMP", + "JMP", + "BAS", "EXIT" }; @@ -48,13 +52,14 @@ byte *DOS_COMMANDS[] = { // returns the number of character to advance the pointer // leading and trailing spaces are ignored // max is the (maximum) size of dest -byte get_token(byte *source, byte *dest, byte max) { + +void get_token(byte *dest, byte max) { byte i = 0; byte j = 0; byte first_char_found = 0; while(1) { - byte c = source[i]; + byte c = token_ptr[i]; if(c == 0) { break; } @@ -71,32 +76,38 @@ byte get_token(byte *source, byte *dest, byte max) { else break; } dest[j] = 0; - return i+1; + token_ptr += i+1; } -// returns the command code or 0xff if not recognized -byte find_command() { - for(byte cmd=0; cmd='0' && c<='9') res += (c-'0'); - else if(c>='A' && c<='F') res += (c-65)+0x0A; + tmpword = tmpword << 4; + if(c>='0' && c<='9') tmpword += (c-'0'); + else if(c>='A' && c<='F') tmpword += (c-65)+0x0A; else hex_to_word_ok = 0; } if(i>4 || i==0) hex_to_word_ok = 0; - return res; } #include "cmd_read.h" @@ -112,10 +123,10 @@ void console() { VIA_init(); // 1234567890123456789012345678901234567890 - woz_puts("\rREAD,WRITE,LOAD,RUN,SAVE,TYPE,DUMP,DIR\r" - "TIME,EXIT\r"); + //woz_puts("\rREAD,WRITE,LOAD,RUN,SAVE,TYPE,DUMP,DIR\r" + // "TIME,JMP,EXIT\r"); - woz_puts("\rSD CARD DOS 1.0\r"); + woz_puts("\r\r*** SD CARD OS 1.0\r"); // main loop while(1) { @@ -129,114 +140,133 @@ void console() { woz_putc('\r'); // decode command - byte *ptr = KEYBUF; - ptr += get_token(ptr, command, 5); - byte cmd = find_command(); + token_ptr = KEYBUF; + get_token(command, 5); + + find_command(); // put command in cmd if(cmd == CMD_READ) { - ptr += get_token(ptr, filename, 32); // parse filename + get_token(filename, 32); // parse filename if(filename[0] == 0) { woz_puts("?MISSING FILENAME"); continue; } - ptr += get_token(ptr, hex1, 4); // parse hex start address - word start = hex_to_word(hex1); + get_token(hex1, 4); // parse hex start address + hex_to_word(hex1); + start_address = tmpword; + if(!hex_to_word_ok) { woz_puts("?BAD ADDRESS"); continue; } - comando_read(filename, start); + comando_read(); } else if(cmd == CMD_WRITE) { // parse filename - ptr += get_token(ptr, filename, 32); + get_token(filename, 32); if(filename[0] == 0) { woz_puts("?MISSING FILENAME"); continue; } // parse hex start address - ptr += get_token(ptr, hex1, 4); - word start = hex_to_word(hex1); + get_token(hex1, 4); + hex_to_word(hex1); + start_address = tmpword; + if(!hex_to_word_ok) { woz_puts("?BAD ADDRESS"); continue; } // parse hex end address - ptr += get_token(ptr, hex2, 4); - word end = hex_to_word(hex2); + get_token(hex2, 4); + hex_to_word(hex2); + end_address = tmpword; if(!hex_to_word_ok) { woz_puts("?BAD ADDRESS"); continue; } - - comando_write(filename, start, end); + comando_write(); } else if(cmd == CMD_DIR) { comando_dir(); } else if(cmd == CMD_TIME) { - ptr += get_token(ptr, hex1, 4); // parse hex timeout value + get_token(hex1, 4); // parse hex timeout value if(strlen(hex1)!=0) { - TIMEOUT_MAX = hex_to_word(hex1); + hex_to_word(hex1); if(!hex_to_word_ok) { woz_puts("?BAD ARGUMENT"); continue; } + TIMEOUT_MAX = tmpword; } woz_puts("TIMEOUT_MAX: "); woz_print_hexword(TIMEOUT_MAX); } else if(cmd == CMD_LOAD || cmd == CMD_RUN) { - ptr += get_token(ptr, filename, 32); // parse filename + get_token(filename, 32); // parse filename if(filename[0] == 0) { woz_puts("?MISSING FILENAME"); continue; } - comando_load(filename, cmd); + comando_load(); } else if(cmd == CMD_SAVE) { - ptr += get_token(ptr, filename, 32); // parse filename + get_token(filename, 32); // parse filename if(filename[0] == 0) { woz_puts("?MISSING FILENAME"); continue; } - comando_save(filename); + comando_save(); } else if(cmd == CMD_TYPE) { - ptr += get_token(ptr, filename, 32); // parse filename + get_token(filename, 32); // parse filename if(filename[0] == 0) { woz_puts("?MISSING FILENAME"); continue; } - comando_type(filename); + comando_type(); } else if(cmd == CMD_DUMP) { - ptr += get_token(ptr, filename, 32); // parse filename + get_token(filename, 32); // parse filename if(filename[0] == 0) { woz_puts("?MISSING FILENAME"); continue; } - // parse hex start address - ptr += get_token(ptr, hex1, 4); - word start = hex_to_word(hex1); - if(!hex_to_word_ok) { - woz_puts("?BAD ADDRESS"); - continue; - } + start_address = 0; + end_address = 0xffff; - // parse hex end address - ptr += get_token(ptr, hex2, 4); - word end = hex_to_word(hex2); + // parse hex start address + get_token(hex1, 4); + hex_to_word(hex1); + + if(hex_to_word_ok) { + start_address = tmpword; + // parse hex end address + get_token(hex2, 4); + hex_to_word(hex2); + if(hex_to_word_ok) end_address = tmpword; + } + comando_dump(); + } + else if(cmd == CMD_JMP) { + get_token(hex1, 4); // parse hex + hex_to_word(hex1); if(!hex_to_word_ok) { - woz_puts("?BAD ADDRESS"); + woz_puts("?BAD ARGUMENT"); continue; } - if(end