diff --git a/Makefile b/Makefile index 9fa6203..73e6c67 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ windows: bin/c2d.exe bin/text2page.exe bin/page2text.exe dist: all windows -c2d.h: c2d.h.0 asm/loader.s makeheader +c2d.h: c2d.h.0 asm/loader.s asm/bar.s makeheader ./makeheader bin/c2d: c2d.c c2d.h holes.h @@ -42,6 +42,28 @@ gameserverclient.text: Makefile text="CASSETTE PORT FTW! ---- ASCIIEXPRESS.NET"; printf "%*s\n" $$((($${#text}+40)/2)) "$$text"; \ ) | tail -24 >$@ +barloader.text: Makefile + ( \ + echo; \ + figlet -c -w 40 -f poison "c2d"; \ + echo; \ + text="C2D (CODE TO DISK) BUILT-IN LOADER"; printf "%*s\n" $$((($${#text}+40)/2)) "$$text"; \ + echo; \ + text="LOADING GAME SERVER CLIENT ..."; printf "%*s\n" $$((($${#text}+40)/2)) "$$text"; \ + echo; \ + text="________________________________________"; printf "%*s\n" $$((($${#text}+40)/2)) "$$text"; \ + text="________________________________________"; printf "%*s\n" $$((($${#text}+40)/2)) "$$text"; \ + echo; \ + echo; \ + text="HTTPS://GITHUB.COM/DATAJERK/C2D/"; printf "%*s\n" $$((($${#text}+40)/2)) "$$text"; \ + ) | tail -24 >$@ + +barloader.textpage: barloader.text bin/text2page + bin/text2page <$< >$@ + +gameserverclientbar.dsk: barloader.textpage gameserverclient bin/c2d + bin/c2d -b -t $< gameserverclient,800 $@ + fulltest: gameserverclient gameserverclient.mon gameserverclient.text dist EMU=1 WIN=1 ./test.sh diff --git a/README.md b/README.md index 8c27036..0393ffa 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Windows/MinGW: ``` usage: c2d [-vh?] - c2d [-mu] [-t filename] [-s start address override] input[.mon],[load_address] output.dsk + c2d [-bum] [-t filename] [-s start address override] input[.mon],[load_address] output.dsk -h|? this help -m jump to monitor after booting @@ -59,6 +59,7 @@ usage: c2d [-vh?] -t filename, where filename is a 1K $400-$7FF text page splash screen The splash screen will display while the binary is loading -u do not patch screen holes + -b animated loading bar (experimental) -v print version number and exit Input without a .mon extension is assumed to be a binary with a 4 byte header. @@ -104,7 +105,7 @@ Yes. No input checking. Big Endian untested. ### The Ugly Stuff -c2d, Code to Disk, Version 0.53 +c2d, Code to Disk, Version 0.54 (c) 2012,2017 All Rights Reserved, Egan Ford (egan@sense.net) diff --git a/asm/bar.s b/asm/bar.s new file mode 100644 index 0000000..fde56c7 --- /dev/null +++ b/asm/bar.s @@ -0,0 +1,167 @@ +;bar.s +; +; moves itself to another page memory, +; then reads binary from disk using params at end, +; then jumps to binary +; + +; apple params/vectors + +warm = $FF69 ; back to monitor +bell = $FBDD ; ding +preg = $48 ; mon p reg +ch = $24 ; cursor horizontal +movecur = $FB5B ; move cursor to ch,a +cout = $FDED ; character out sub + +; dos params/vectors + +rwtsprm = $B7E8 ; looked at dos 3.3 disk, not using $3E3 to find +rwts = $B7B5 ; rwts jsr + +; vars + +stage1 = $800 +stage2 = $300 ; $300 looks open +invsp = $20 ; inverse space for draw +;;;run time +trkcnt = $00 ; track counter +segcnt = $01 ; loop var +buffer = $02 ; MSB of RWTS buffer +secnum = $03 ; loop var +trknum = $04 ; loop var +barcnt = $05 ; bar counter +barptr = $06 ; bar pointer + + + .org stage1 +init: + lda #0 ; reset pointer and counter + sta barcnt + sta barptr + + lda #1 ; read(1)/write(2) command + ldy #$0C ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + + lda #0 ; buffer LSB + ldy #8 ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + + lda #2 + sta trknum ; start with track 2 + +start: + ldx #0 ; move code to stage2 +move: + lda moved,x + sta loader,x + inx + cpx #$D0 + bne move ; move 208 bytes + jmp loader + +moved: + .org stage2 + +loader: + lda loadpage ; where to dump the tracks + sta buffer + + ldx lasttrack + dex ; because data starts at track 2 + dex + stx trkcnt ; number of complete and partial tracks + +;;;begin track loop +trkloop: + lda trknum ; track number + ldy #4 ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + +;;;begin sector loop (16), backwards is faster, much faster + lda trkcnt ; check if last track + bne fulltrack ; if not then full track + lda lastsector ; if so, get last sector number + bpl subtrack +fulltrack: + lda #$F +subtrack: + sta secnum +secloop: + lda secnum ; sector number + ldy #5 ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + + lda buffer ; buffer MSB + clc + adc secnum ; compute page load address + ldy #9 ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + + ldy #rwtsprm + jsr rwts ; do it! + bcs diskerror + lda #0 + sta preg ; fix p reg so mon is happy + +;;;draw code + inc barcnt ; sectors read + ldx barptr ; get current pointer value + lda bar,x + cmp barcnt ; is bar,x = barcnt? + bne nodraw ; if bar,x = barcnt draw bar + lda barptr ; get position + ;clc + ;adc #5 ; intend + sta ch + lda #19 ; row 19 + jsr movecur + lda #invsp + jsr cout + inc barptr ; move pointer to next bar position +nodraw: +;;;end draw code + + dec secnum + bpl secloop +;;;end sector loop + + lda buffer ; buffer += $10 + clc + adc #$10 + sta buffer + + inc trknum ; next track + dec trkcnt ; + bpl trkloop ; 0, all done with tracks +;;;end track loop + +done: + jmp (nextjump) ; down with load, run it + +diskerror: + jmp warm + +lasttrack: + .org *+1 +lastsector: + .org *+1 +loadpage: + .org *+1 +nextjump: + .org *+2 +bar: + .org *+40 +;;; used for debug +;trkcnt: +; .org *+1 +;segcnt: +; .org *+1 +;buffer: +; .org *+1 +;secnum: +; .org *+1 +;trknum: +; .org *+1 diff --git a/bin/c2d b/bin/c2d index 3517130..8e9a04b 100755 Binary files a/bin/c2d and b/bin/c2d differ diff --git a/bin/c2d.exe b/bin/c2d.exe index 833721b..c33d2c3 100755 Binary files a/bin/c2d.exe and b/bin/c2d.exe differ diff --git a/bin/page2text.exe b/bin/page2text.exe index 77bd009..e5c0926 100755 Binary files a/bin/page2text.exe and b/bin/page2text.exe differ diff --git a/bin/text2page.exe b/bin/text2page.exe index 7b2781d..f53779a 100755 Binary files a/bin/text2page.exe and b/bin/text2page.exe differ diff --git a/c2d.c b/c2d.c index e9a8f60..76e203e 100644 --- a/c2d.c +++ b/c2d.c @@ -1,6 +1,6 @@ /* -c2d, Code to Disk, Version 0.53 +c2d, Code to Disk, Version 0.54 (c) 2012,2017 All Rights Reserved, Egan Ford (egan@sense.net) @@ -43,7 +43,7 @@ Based on work by: #include "c2d.h" #include "holes.h" -#define VERSION "Version 0.53" +#define VERSION "Version 0.54" #define INFILE argv[argc-2] #define OUTFILE argv[argc-1] #define BINARY 0 @@ -57,13 +57,13 @@ int main(int argc, char **argv) { FILE *ifp, *ofp; int c, i, j, k, start = 0, loadaddress, inputtype, warm = 0, filesize = 0, unpatch = 0; - int loaderstart, loader = 0, loadersize = 0, textpagesize = 0; + int loaderstart, loader = 0, loadersize = 0, loaderbasesize = 0, textpagesize = 0, bar = 0; struct stat st; char *filetypes[] = { "BINARY", "MONITOR" }; char *ext, filename[256], load_address[10], *textpage = NULL; opterr = 1; - while ((c = getopt(argc, argv, "t:vmh?s:u")) != -1) + while ((c = getopt(argc, argv, "t:vmh?s:ub")) != -1) switch (c) { case 't': // load a splash page while loading binary loader = 1; @@ -83,6 +83,9 @@ int main(int argc, char **argv) case 'u': unpatch = 1; break; + case 'b': + bar = 1; + break; case 'h': // help case '?': usage(); @@ -218,8 +221,7 @@ int main(int argc, char **argv) fclose(ifp); // patch holes - if(!unpatch) - { + if(!unpatch) { uint64_t *p = (uint64_t *)&blank.track[1].sector[0].byte[0]; // set to start of splash page uint64_t *h = (uint64_t *)&holes; // holes are 64-bits int i; @@ -232,13 +234,26 @@ int main(int argc, char **argv) } } - if ((loadersize = sizeof(loadercode)) > 256) { - fprintf(stderr, "Loader code size %d > 256\n\n", loadersize); - return 1; + if(!bar) { + loaderbasesize = sizeof(loadercode); + if ((loadersize = sizeof(loadercode)) > 256) { + fprintf(stderr, "Loader code size %d > 256\n\n", loadersize); + return 1; + } + + for (i = 0; i < loadersize; i++) + blank.track[1].sector[4].byte[i] = loadercode[i]; } + else { + loaderbasesize = sizeof(barcode); + if ((loadersize = sizeof(barcode)) > 256) { + fprintf(stderr, "Loader code size %d > 256\n\n", loadersize); + return 1; + } - for (i = 0; i < loadersize; i++) - blank.track[1].sector[4].byte[i] = loadercode[i]; + for (i = 0; i < loadersize; i++) + blank.track[1].sector[4].byte[i] = barcode[i]; + } // loader args // lasttrack @@ -252,6 +267,16 @@ int main(int argc, char **argv) // program start MSB blank.track[1].sector[4].byte[loadersize + 4] = start >> 8; + //bar code, pre compute status bar table + if(bar) { + int num_sectors = (int) ceil((filesize + (loadaddress & 0xFF)) / 256.0); + int bar_length = 40; + int i; + + for(i = 1; i <= bar_length; i++) + blank.track[1].sector[4].byte[loadersize + 4 + i] = i * num_sectors / bar_length; + } + loaderstart = 0x400; // temp hack to effect the sound of the drive, i.e. to make consistent @@ -278,7 +303,7 @@ int main(int argc, char **argv) fprintf(stderr, "After boot, jump to: $%04X\n", loaderstart); fprintf(stderr, "\n"); - fprintf(stderr, "Writing %s to T:02/S:00 - T:%02d/S:%02d on %s\n\n", filename, blank.track[1].sector[4].byte[sizeof(loadercode)], blank.track[1].sector[4].byte[sizeof(loadercode) + 1], OUTFILE); + fprintf(stderr, "Writing %s to T:02/S:00 - T:%02d/S:%02d on %s\n\n", filename, blank.track[1].sector[4].byte[sizeof(loadercode)], blank.track[1].sector[4].byte[loaderbasesize + 1], OUTFILE); } if ((ofp = fopen(OUTFILE, "wb")) == NULL) { diff --git a/c2d.h b/c2d.h index 631728c..93cb1a4 100644 --- a/c2d.h +++ b/c2d.h @@ -13,7 +13,7 @@ typedef struct d { const char *usagetext="\n\ usage: c2d [-vh?]\n\ - c2d [-mu] [-t filename] [-s start address override] input[.mon],[load_address] output.dsk\n\ + c2d [-bum] [-t filename] [-s start address override] input[.mon],[load_address] output.dsk\n\ \n\ -h|? this help\n\ -m jump to monitor after booting\n\ @@ -21,6 +21,7 @@ usage: c2d [-vh?]\n\ -t filename, where filename is a 1K $400-$7FF text page splash screen\n\ The splash screen will display while the binary is loading\n\ -u do not patch screen holes\n\ + -b animated loading bar (experimental)\n\ -v print version number and exit\n\ \n\ Input without a .mon extension is assumed to be a binary with a 4 byte header.\n\ @@ -9165,3 +9166,194 @@ unsigned char loadercode[] = { 0x02,0xE6,0x04,0xC6,0x00,0x10,0xBD,0x6C, 0x6A,0x03,0x4C,0x69,0xFF }; +/* +;bar.s +; +; moves itself to another page memory, +; then reads binary from disk using params at end, +; then jumps to binary +; + +; apple params/vectors + +warm = $FF69 ; back to monitor +bell = $FBDD ; ding +preg = $48 ; mon p reg +ch = $24 ; cursor horizontal +movecur = $FB5B ; move cursor to ch,a +cout = $FDED ; character out sub + +; dos params/vectors + +rwtsprm = $B7E8 ; looked at dos 3.3 disk, not using $3E3 to find +rwts = $B7B5 ; rwts jsr + +; vars + +stage1 = $800 +stage2 = $300 ; $300 looks open +invsp = $20 ; inverse space for draw +;;;run time +trkcnt = $00 ; track counter +segcnt = $01 ; loop var +buffer = $02 ; MSB of RWTS buffer +secnum = $03 ; loop var +trknum = $04 ; loop var +barcnt = $05 ; bar counter +barptr = $06 ; bar pointer + + + .org stage1 +init: + lda #0 ; reset pointer and counter + sta barcnt + sta barptr + + lda #1 ; read(1)/write(2) command + ldy #$0C ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + + lda #0 ; buffer LSB + ldy #8 ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + + lda #2 + sta trknum ; start with track 2 + +start: + ldx #0 ; move code to stage2 +move: + lda moved,x + sta loader,x + inx + cpx #$D0 + bne move ; move 208 bytes + jmp loader + +moved: + .org stage2 + +loader: + lda loadpage ; where to dump the tracks + sta buffer + + ldx lasttrack + dex ; because data starts at track 2 + dex + stx trkcnt ; number of complete and partial tracks + +;;;begin track loop +trkloop: + lda trknum ; track number + ldy #4 ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + +;;;begin sector loop (16), backwards is faster, much faster + lda trkcnt ; check if last track + bne fulltrack ; if not then full track + lda lastsector ; if so, get last sector number + bpl subtrack +fulltrack: + lda #$F +subtrack: + sta secnum +secloop: + lda secnum ; sector number + ldy #5 ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + + lda buffer ; buffer MSB + clc + adc secnum ; compute page load address + ldy #9 ; offset in RWTS + sta rwtsprm,y ; write it to RWTS + + ldy #rwtsprm + jsr rwts ; do it! + bcs diskerror + lda #0 + sta preg ; fix p reg so mon is happy + +;;;draw code + inc barcnt ; sectors read + ldx barptr ; get current pointer value + lda bar,x + cmp barcnt ; is bar,x = barcnt? + bne nodraw ; if bar,x = barcnt draw bar + lda barptr ; get position + ;clc + ;adc #5 ; intend + sta ch + lda #19 ; row 19 + jsr movecur + lda #invsp + jsr cout + inc barptr ; move pointer to next bar position +nodraw: +;;;end draw code + + dec secnum + bpl secloop +;;;end sector loop + + lda buffer ; buffer += $10 + clc + adc #$10 + sta buffer + + inc trknum ; next track + dec trkcnt ; + bpl trkloop ; 0, all done with tracks +;;;end track loop + +done: + jmp (nextjump) ; down with load, run it + +diskerror: + jmp warm + +lasttrack: + .org *+1 +lastsector: + .org *+1 +loadpage: + .org *+1 +nextjump: + .org *+2 +bar: + .org *+40 +;;; used for debug +;trkcnt: +; .org *+1 +;segcnt: +; .org *+1 +;buffer: +; .org *+1 +;secnum: +; .org *+1 +;trknum: +; .org *+1 +*/ +unsigned char barcode[] = { + 0xA9,0x00,0x85,0x05,0x85,0x06,0xA9,0x01, + 0xA0,0x0C,0x99,0xE8,0xB7,0xA9,0x00,0xA0, + 0x08,0x99,0xE8,0xB7,0xA9,0x02,0x85,0x04, + 0xA2,0x00,0xBD,0x28,0x08,0x9D,0x00,0x03, + 0xE8,0xE0,0xD0,0xD0,0xF5,0x4C,0x00,0x03, + 0xAD,0x72,0x03,0x85,0x02,0xAE,0x70,0x03, + 0xCA,0xCA,0x86,0x00,0xA5,0x04,0xA0,0x04, + 0x99,0xE8,0xB7,0xA5,0x00,0xD0,0x05,0xAD, + 0x71,0x03,0x10,0x02,0xA9,0x0F,0x85,0x03, + 0xA5,0x03,0xA0,0x05,0x99,0xE8,0xB7,0xA5, + 0x02,0x18,0x65,0x03,0xA0,0x09,0x99,0xE8, + 0xB7,0xA0,0xE8,0xA9,0xB7,0x20,0xB5,0xB7, + 0xB0,0x33,0xA9,0x00,0x85,0x48,0xE6,0x05, + 0xA6,0x06,0xBD,0x75,0x03,0xC5,0x05,0xD0, + 0x10,0xA5,0x06,0x85,0x24,0xA9,0x13,0x20, + 0x5B,0xFB,0xA9,0x20,0x20,0xED,0xFD,0xE6, + 0x06,0xC6,0x03,0x10,0xC3,0xA5,0x02,0x18, + 0x69,0x10,0x85,0x02,0xE6,0x04,0xC6,0x00, + 0x10,0xA2,0x6C,0x73,0x03,0x4C,0x69,0xFF + +}; diff --git a/c2d.h.0 b/c2d.h.0 index bd3c82a..1ba0e6c 100644 --- a/c2d.h.0 +++ b/c2d.h.0 @@ -13,7 +13,7 @@ typedef struct d { const char *usagetext="\n\ usage: c2d [-vh?]\n\ - c2d [-mu] [-t filename] [-s start address override] input[.mon],[load_address] output.dsk\n\ + c2d [-bum] [-t filename] [-s start address override] input[.mon],[load_address] output.dsk\n\ \n\ -h|? this help\n\ -m jump to monitor after booting\n\ @@ -21,6 +21,7 @@ usage: c2d [-vh?]\n\ -t filename, where filename is a 1K $400-$7FF text page splash screen\n\ The splash screen will display while the binary is loading\n\ -u do not patch screen holes\n\ + -b animated loading bar (experimental)\n\ -v print version number and exit\n\ \n\ Input without a .mon extension is assumed to be a binary with a 4 byte header.\n\ diff --git a/makeheader b/makeheader index 3c3d029..5cc45c8 100755 --- a/makeheader +++ b/makeheader @@ -38,6 +38,7 @@ make ( header loader loadercode 8 +header bar barcode 8 ) > ../c2d.h.1 cd ..