From 1f1b3ada379b170f73872b91c6df73ea4af586ae Mon Sep 17 00:00:00 2001 From: gdr Date: Tue, 18 Nov 1997 05:31:00 +0000 Subject: [PATCH] Initial checkin of gsh v1.1 as provided by Tony Diaz. --- bin/gsh/M/alias.mac | 477 +++++++++ bin/gsh/M/bufpool.mac | 84 ++ bin/gsh/M/builtin.mac | 774 +++++++++++++++ bin/gsh/M/cmd.mac | 497 ++++++++++ bin/gsh/M/dir.mac | 474 +++++++++ bin/gsh/M/edit.mac | 551 +++++++++++ bin/gsh/M/expand.mac | 435 +++++++++ bin/gsh/M/hash.mac | 571 +++++++++++ bin/gsh/M/history.mac | 592 +++++++++++ bin/gsh/M/invoke.mac | 588 +++++++++++ bin/gsh/M/jobs.mac | 527 ++++++++++ bin/gsh/M/main.mac | 297 ++++++ bin/gsh/M/orca.mac | 304 ++++++ bin/gsh/M/prompt.mac | 374 +++++++ bin/gsh/M/shell.mac | 405 ++++++++ bin/gsh/M/shellutil.mac | 185 ++++ bin/gsh/M/shellvar.mac | 338 +++++++ bin/gsh/M/stdio.mac | 92 ++ bin/gsh/M/sv.mac | 355 +++++++ bin/gsh/M/term.mac | 264 +++++ bin/gsh/Makefile | 87 ++ bin/gsh/To.Do | 44 + bin/gsh/UpdateLog | 158 +++ bin/gsh/alias.asm | 798 +++++++++++++++ bin/gsh/bufpool.asm | 176 ++++ bin/gsh/builtin.asm | 2061 +++++++++++++++++++++++++++++++++++++++ bin/gsh/cmd.asm | 1166 ++++++++++++++++++++++ bin/gsh/dir.asm | 697 +++++++++++++ bin/gsh/edit.asm | 1955 +++++++++++++++++++++++++++++++++++++ bin/gsh/expand.asm | 580 +++++++++++ bin/gsh/hash.asm | 928 ++++++++++++++++++ bin/gsh/history.asm | 574 +++++++++++ bin/gsh/invoke.asm | 709 ++++++++++++++ bin/gsh/jobs.asm | 1721 ++++++++++++++++++++++++++++++++ bin/gsh/link.script | 22 + bin/gsh/m16.gno | 347 +++++++ bin/gsh/main.asm | 143 +++ bin/gsh/mdb.mac | 281 ++++++ bin/gsh/mmdebug.asm | 41 + bin/gsh/mods | 2 + bin/gsh/oldorca.asm | 175 ++++ bin/gsh/orca.asm | 286 ++++++ bin/gsh/prompt.asm | 415 ++++++++ bin/gsh/shell.asm | 401 ++++++++ bin/gsh/shellutil.asm | 744 ++++++++++++++ bin/gsh/shellvar.asm | 920 +++++++++++++++++ bin/gsh/stdio.asm | 441 +++++++++ bin/gsh/sv.asm | 535 ++++++++++ bin/gsh/term.asm | 485 +++++++++ bin/gsh/tests/history | 4 + bin/gsh/tests/test | 1 + bin/gsh/tests/testscr | 2 + 52 files changed, 25083 insertions(+) create mode 100644 bin/gsh/M/alias.mac create mode 100644 bin/gsh/M/bufpool.mac create mode 100644 bin/gsh/M/builtin.mac create mode 100644 bin/gsh/M/cmd.mac create mode 100644 bin/gsh/M/dir.mac create mode 100644 bin/gsh/M/edit.mac create mode 100644 bin/gsh/M/expand.mac create mode 100644 bin/gsh/M/hash.mac create mode 100644 bin/gsh/M/history.mac create mode 100644 bin/gsh/M/invoke.mac create mode 100644 bin/gsh/M/jobs.mac create mode 100644 bin/gsh/M/main.mac create mode 100644 bin/gsh/M/orca.mac create mode 100644 bin/gsh/M/prompt.mac create mode 100644 bin/gsh/M/shell.mac create mode 100644 bin/gsh/M/shellutil.mac create mode 100644 bin/gsh/M/shellvar.mac create mode 100644 bin/gsh/M/stdio.mac create mode 100644 bin/gsh/M/sv.mac create mode 100644 bin/gsh/M/term.mac create mode 100644 bin/gsh/Makefile create mode 100644 bin/gsh/To.Do create mode 100644 bin/gsh/UpdateLog create mode 100644 bin/gsh/alias.asm create mode 100644 bin/gsh/bufpool.asm create mode 100644 bin/gsh/builtin.asm create mode 100644 bin/gsh/cmd.asm create mode 100644 bin/gsh/dir.asm create mode 100644 bin/gsh/edit.asm create mode 100644 bin/gsh/expand.asm create mode 100644 bin/gsh/hash.asm create mode 100644 bin/gsh/history.asm create mode 100644 bin/gsh/invoke.asm create mode 100644 bin/gsh/jobs.asm create mode 100644 bin/gsh/link.script create mode 100644 bin/gsh/m16.gno create mode 100644 bin/gsh/main.asm create mode 100644 bin/gsh/mdb.mac create mode 100644 bin/gsh/mmdebug.asm create mode 100644 bin/gsh/mods create mode 100644 bin/gsh/oldorca.asm create mode 100644 bin/gsh/orca.asm create mode 100644 bin/gsh/prompt.asm create mode 100644 bin/gsh/shell.asm create mode 100644 bin/gsh/shellutil.asm create mode 100644 bin/gsh/shellvar.asm create mode 100644 bin/gsh/stdio.asm create mode 100644 bin/gsh/sv.asm create mode 100644 bin/gsh/term.asm create mode 100644 bin/gsh/tests/history create mode 100644 bin/gsh/tests/test create mode 100644 bin/gsh/tests/testscr diff --git a/bin/gsh/M/alias.mac b/bin/gsh/M/alias.mac new file mode 100644 index 0000000..bed42c4 --- /dev/null +++ b/bin/gsh/M/alias.mac @@ -0,0 +1,477 @@ + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab WriteCString &a1 +&lab ph4 &a1 + Tool $200c + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab dec2 &a +&lab dec &a + dec &a + mend + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab iny2 +&lab iny + iny + mend + MACRO +&lab ora2 &arg1,&arg2,&dest +&lab anop + lclc &char +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + ora &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab asl2 &a +&lab asl &a + asl &a + mend + MACRO +&lab UDivide &a1,&a2 +&lab pha + pha + ph2 &a1(1) + ph2 &a1(2) + Tool $0b0b + pl2 &a2(1) + pl2 &a2(2) + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend + MACRO +&lab inx2 +&lab inx + inx + mend + MACRO +&lab dey2 +&lab dey + dey + mend + macro +&lab ErrWriteCString &a1 +&lab ph4 &a1 + Tool $210c + mend diff --git a/bin/gsh/M/bufpool.mac b/bin/gsh/M/bufpool.mac new file mode 100644 index 0000000..01d0730 --- /dev/null +++ b/bin/gsh/M/bufpool.mac @@ -0,0 +1,84 @@ + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab unlock &a1 +&lab stz &a1 + MEND + MACRO +&lab key +&lab dc i2'0' + MEND + MACRO +&lab lock &a1 +&lab lda #1 + tsb &a1 + beq *+6 + cop $7F + bra *-7 + MEND + MACRO +&lab WriteCString &a1 +&lab ph4 &a1 + Tool $200c + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend diff --git a/bin/gsh/M/builtin.mac b/bin/gsh/M/builtin.mac new file mode 100644 index 0000000..001f1c1 --- /dev/null +++ b/bin/gsh/M/builtin.mac @@ -0,0 +1,774 @@ + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab sub2 &arg1,&arg2,&dest + lclc &char +&lab sec +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .sub +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .sub +.x1 + txa + ago .sub +.y1 + tya +.sub + sbc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab MV2 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + macro +&lab jcs &loc +&lab bcc *+5 + jmp &loc + mend + MACRO +&lab LD2 &val,&adr +&lab lcla &count + lda #&val +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab ora2 &arg1,&arg2,&dest +&lab anop + lclc &char +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + ora &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab READ_VARIABLE &a1 +&lab p16 $10B,&a1 + mend + MACRO +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab iny2 +&lab iny + iny + mend + MACRO +&lab Dec2Int &a1,&a2 +&lab pha + ph4 &a1(1) + ph2 &a1(2) + ph2 &a1(3) + Tool $280b + pl2 &a2 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend + MACRO +&lab Int2Dec &a1 +&lab ph2 &a1(1) + ph4 &a1(2) + ph2 &a1(3) + ph2 &a1(4) + Tool $260b + mend + MACRO +&lab GetPrefix &a1 +&lab gsos $200A,&a1 + mend + MACRO +&lab ERROR &a1 +&lab p16 $105,&a1 + mend + MACRO +&lab asl2 &a +&lab asl &a + asl &a + mend + MACRO +&lab LD4 &val,&adr +&lab lcla &count + lda #<&val +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda #+(&val)|-16 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + macro +&lab inc2 &a +&lab inc &a + inc &a + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab jne &loc +&lab beq *+5 + jmp &loc + mend + MACRO +&lab SetPrefix &a1 +&lab gsos $2009,&a1 + mend + MACRO +&lab GetFileInfo &a1 +&lab gsos $2006,&a1 + mend + MACRO +&lab dey2 +&lab dey + dey + mend + macro +&lab GetBootVol &a1 +&lab gsos $2028,&a1 + mend + macro +&lab Volume &a1 +&lab gsos $2008,&a1 + mend + macro +&lab DInfo &a1 +&lab gsos $202C,&a1 + mend + macro +&lab Long2Dec &a1 +&lab ph4 &a1(1) + ph4 &a1(2) + ph2 &a1(3) + ph2 &a1(4) + Tool $270b + mend + macro +&lab LongMul &a1,&a2 +&lab pha + pha + pha + pha + ph4 &a1(1) + ph4 &a1(2) + Tool $0c0b + pl4 &a2(1) + pl4 &a2(2) + mend + macro +&lab LongDivide &a1,&a2 +&lab pha + pha + pha + pha + ph4 &a1(1) + ph4 &a1(2) + Tool $0d0b + pl4 &a2(1) + pl4 &a2(2) + mend + macro +&lab pl4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"<>"{",.chk +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ldy #2 + pla + sta (&parm),y + ago .shorten +.chk + aif "&char"<>"[",.chk2 + pla + sta &parm + ldy #2 + pla + sta &parm,y + ago .shorten +.chk2 + aif "&char"<>"@",.absolute +&char1 amid &parm,2,1 +&char2 setc &char1 + pl&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + pl&char2 + ago .shorten +.absolute + pla + sta &parm + pla + sta &parm+2 +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab setdebug &a1 +&lab ph2 &a1 + case on + jsl setdebug + case off + MEND + MACRO +&lab kvm_open +&lab case on + jsl kvm_open + case off + MEND + MACRO +&lab kvm_close &a1 +&lab ph4 &a1 + case on + jsl kvm_close + case off + MEND + MACRO +&lab kvmnextproc &a1 +&lab ph4 &a1 + case on + jsl kvmnextproc + case off + MEND + macro +&lab Int2Hex &a1 +&lab ph2 &a1(1) + ph4 &a1(2) + ph2 &a1(3) + Tool $220b + mend + MACRO +&lab kvmgetproc &a1 +&lab ph2 &a1(2) + ph4 &a1(1) + case on + jsl kvmgetproc + case off + MEND + MACRO +&lab unlock &a1 +&lab stz &a1 + MEND + MACRO +&lab key +&lab dc i2'0' + MEND + MACRO +&lab lock &a1 +&lab lda #1 + tsb &a1 + beq *+6 + cop $7F + bra *-7 + MEND + MACRO +&lab jcc &loc +&lab bcs *+5 + jmp &loc + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab getuid +&lab case on + jsl getuid + case off + MEND + macro +&lab UDivide &a1,&a2 +&lab pha + pha + ph2 &a1(1) + ph2 &a1(2) + Tool $0b0b + pl2 &a2(1) + pl2 &a2(2) + mend diff --git a/bin/gsh/M/cmd.mac b/bin/gsh/M/cmd.mac new file mode 100644 index 0000000..dbb466b --- /dev/null +++ b/bin/gsh/M/cmd.mac @@ -0,0 +1,497 @@ + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab iny2 +&lab iny + iny + mend + MACRO +&lab Int2Dec &a1 +&lab ph2 &a1(1) + ph4 &a1(2) + ph2 &a1(3) + ph2 &a1(4) + Tool $260b + mend + MACRO +&lab ERROR &a1 +&lab p16 $105,&a1 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab LD2 &val,&adr +&lab lcla &count + lda #&val +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab and2 &arg1,&arg2,&dest +&lab anop + lclc &char +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + and &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab asl2 &a +&lab asl &a + asl &a + mend + MACRO +&lab LD4 &val,&adr +&lab lcla &count + lda #<&val +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda #+(&val)|-16 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab jcc &loc +&lab bcs *+5 + jmp &loc + mend + macro +&lab Set_Variable &a1 +&lab p16 $106,&a1 + mend + MACRO +&lab wait &a1 +&lab ph4 &a1 + case on + jsl wait + case off + MEND + MACRO +&lab pipe &a1 +&lab ph4 &a1 + case on + jsl pipe + case off + MEND + MACRO +&lab signal &a1 +&lab ph4 &a1(2) + ph2 &a1(1) + case on + jsl signal + case off + MEND + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + macro +&lab ErrWriteCString &a1 +&lab ph4 &a1 + Tool $210c + mend diff --git a/bin/gsh/M/dir.mac b/bin/gsh/M/dir.mac new file mode 100644 index 0000000..eade9bb --- /dev/null +++ b/bin/gsh/M/dir.mac @@ -0,0 +1,474 @@ + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab READ_VARIABLE &a1 +&lab p16 $10B,&a1 + mend + MACRO +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + macro +&lab inc2 &a +&lab inc &a + inc &a + mend + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab sub2 &arg1,&arg2,&dest + lclc &char +&lab sec +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .sub +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .sub +.x1 + txa + ago .sub +.y1 + tya +.sub + sbc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab WriteCString &a1 +&lab ph4 &a1 + Tool $200c + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab add4 &arg1,&arg2,&dest +&lab anop + lclc &ch +&ch amid &arg2,1,1 + clc + lda &arg1 + adc &arg2 + sta &dest + lda &arg1+2 + aif "&ch"="#",.a + adc &arg2+2 + ago .b +.a + adc &arg2|-16 +.b + sta &dest+2 + mend + MACRO +&lab GetPrefix &a1 +&lab gsos $200A,&a1 + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab unlock &a1 +&lab stz &a1 + MEND + MACRO +&lab key +&lab dc i2'0' + MEND + MACRO +&lab lock &a1 +&lab lda #1 + tsb &a1 + beq *+6 + cop $7F + bra *-7 + MEND + macro +&lab ErrWriteCString &a1 +&lab ph4 &a1 + Tool $210c + mend + MACRO +&lab GetFileInfo &a1 +&lab gsos $2006,&a1 + mend + MACRO +&lab ERROR &a1 +&lab p16 $105,&a1 + mend + MACRO +&lab SetPrefix &a1 +&lab gsos $2009,&a1 + mend + MACRO +&lab Dec2Int &a1,&a2 +&lab pha + ph4 &a1(1) + ph2 &a1(2) + ph2 &a1(3) + Tool $280b + pl2 &a2 + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + macro +&lab inx4 +&lab inx + inx + inx + inx + mend diff --git a/bin/gsh/M/edit.mac b/bin/gsh/M/edit.mac new file mode 100644 index 0000000..5af5913 --- /dev/null +++ b/bin/gsh/M/edit.mac @@ -0,0 +1,551 @@ + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab sub2 &arg1,&arg2,&dest + lclc &char +&lab sec +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .sub +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .sub +.x1 + txa + ago .sub +.y1 + tya +.sub + sbc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab eor2 &arg1,&arg2,&dest +&lab anop + lclc &char +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + eor &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab INIT_WILDCARD &a1 +&lab p16 $109,&a1 + mend + MACRO +&lab NEXT_WILDCARD &a1 +&lab p16 $10A,&a1 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab GetFileInfo &a1 +&lab gsos $2006,&a1 + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab ioctl &a1 +&lab ph4 &a1(3) + ph4 &a1(2) + ph2 &a1(1) + case on + jsl ioctl + case off + MEND + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab add4 &arg1,&arg2,&dest +&lab anop + lclc &ch +&ch amid &arg2,1,1 + clc + lda &arg1 + adc &arg2 + sta &dest + lda &arg1+2 + aif "&ch"="#",.a + adc &arg2+2 + ago .b +.a + adc &arg2|-16 +.b + sta &dest+2 + mend + MACRO +&lab LD4 &val,&adr +&lab lcla &count + lda #<&val +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda #+(&val)|-16 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab tputs &a1 +&lab ph4 &a1(3) + ph2 &a1(2) + ph4 &a1(1) + case on + jsl tputs + case off + MEND + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab jne &loc +&lab beq *+5 + jmp &loc + mend + MACRO +&lab LD2 &val,&adr +&lab lcla &count + lda #&val +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab READ_INDEXED &a1 +&lab p16 $108,&a1 + mend + MACRO +&lab jcc &loc +&lab bcs *+5 + jmp &loc + mend + MACRO +&lab READ_VARIABLE &a1 +&lab p16 $10B,&a1 + mend + MACRO +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend diff --git a/bin/gsh/M/expand.mac b/bin/gsh/M/expand.mac new file mode 100644 index 0000000..82f95b5 --- /dev/null +++ b/bin/gsh/M/expand.mac @@ -0,0 +1,435 @@ + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab WriteCString &a1 +&lab ph4 &a1 + Tool $200c + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab READ_VARIABLE &a1 +&lab p16 $10B,&a1 + mend + MACRO +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab INIT_WILDCARD &a1 +&lab p16 $109,&a1 + mend + MACRO +&lab NEXT_WILDCARD &a1 +&lab p16 $10A,&a1 + mend + MACRO +&lab sub2 &arg1,&arg2,&dest + lclc &char +&lab sec +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .sub +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .sub +.x1 + txa + ago .sub +.y1 + tya +.sub + sbc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab dec2 &a +&lab dec &a + dec &a + mend + macro +&lab ReadLine &a1,&a2 +&lab pha + ph4 &a1(1) + ph2 &a1(2) + ph2 &a1(3) + ph2 &a1(4) + Tool $240c + pl2 &a2 + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend diff --git a/bin/gsh/M/hash.mac b/bin/gsh/M/hash.mac new file mode 100644 index 0000000..8bb6776 --- /dev/null +++ b/bin/gsh/M/hash.mac @@ -0,0 +1,571 @@ + MACRO +&lab UDivide &a1,&a2 +&lab pha + pha + ph2 &a1(1) + ph2 &a1(2) + Tool $0b0b + pl2 &a2(1) + pl2 &a2(2) + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend + MACRO +&lab asl2 &a +&lab asl &a + asl &a + mend + MACRO +&lab asl3 &a +&lab asl &a + asl &a + asl &a + mend + MACRO +&lab asl4 &a +&lab asl &a + asl &a + asl &a + asl &a + mend + MACRO +&lab iny2 +&lab iny + iny + mend + MACRO +&lab MV2 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab Open &a1 +&lab gsos $2010,&a1 + mend + MACRO +&lab Close &a1 +&lab gsos $2014,&a1 + mend + MACRO +&lab GetDirEntry &a1 +&lab gsos $201C,&a1 + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab LD2 &val,&adr +&lab lcla &count + lda #&val +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab ora2 &arg1,&arg2,&dest +&lab anop + lclc &char +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + ora &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab jge &loc +&lab bcc *+5 + jmp &loc + mend + MACRO +&lab Int2Dec &a1 +&lab ph2 &a1(1) + ph4 &a1(2) + ph2 &a1(3) + ph2 &a1(4) + Tool $260b + mend + MACRO +&lab WriteCString &a1 +&lab ph4 &a1 + Tool $200c + mend + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab lsr2 &a +&lab lsr &a + lsr &a + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab jne &loc +&lab beq *+5 + jmp &loc + mend + MACRO +&lab iny4 +&lab iny + iny + iny + iny + mend + macro +&lab inc2 &a +&lab inc &a + inc &a + mend + macro +&lab READ_VARIABLE &a1 +&lab p16 $10B,&a1 + mend + macro +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + macro +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend + macro +&lab ExpandPath &a1 +&lab gsos $200E,&a1 + mend + macro +&lab ErrWriteLine &a1 +&lab ph4 &a1 + Tool $1b0c + mend diff --git a/bin/gsh/M/history.mac b/bin/gsh/M/history.mac new file mode 100644 index 0000000..11748c5 --- /dev/null +++ b/bin/gsh/M/history.mac @@ -0,0 +1,592 @@ + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab iny2 +&lab iny + iny + mend + MACRO +&lab ora2 &arg1,&arg2,&dest +&lab anop + lclc &char +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + ora &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab Dec2Int &a1,&a2 +&lab pha + ph4 &a1(1) + ph2 &a1(2) + ph2 &a1(3) + Tool $280b + pl2 &a2 + mend + MACRO +&lab READ_VARIABLE &a1 +&lab p16 $10B,&a1 + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend + MACRO +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend + MACRO +&lab Create &a1 +&lab gsos $2001,&a1 + mend + MACRO +&lab Open &a1 +&lab gsos $2010,&a1 + mend + MACRO +&lab Write &a1 +&lab gsos $2013,&a1 + mend + MACRO +&lab Close &a1 +&lab gsos $2014,&a1 + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab GSStr &string +&lab dc i2'L:&string' + dc c"&string" + mend + MACRO +&lab MV2 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab add4 &arg1,&arg2,&dest +&lab anop + lclc &ch +&ch amid &arg2,1,1 + clc + lda &arg1 + adc &arg2 + sta &dest + lda &arg1+2 + aif "&ch"="#",.a + adc &arg2+2 + ago .b +.a + adc &arg2|-16 +.b + sta &dest+2 + mend + MACRO +&lab Destroy &a1 +&lab gsos $2002,&a1 + mend + MACRO +&lab NewLine &a1 +&lab gsos $2011,&a1 + mend + MACRO +&lab Read &a1 +&lab gsos $2012,&a1 + mend + MACRO +&lab jcs &loc +&lab bcc *+5 + jmp &loc + mend + MACRO +&lab Int2Dec &a1 +&lab ph2 &a1(1) + ph4 &a1(2) + ph2 &a1(3) + ph2 &a1(4) + Tool $260b + mend + MACRO +&lab sub2 &arg1,&arg2,&dest + lclc &char +&lab sec +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .sub +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .sub +.x1 + txa + ago .sub +.y1 + tya +.sub + sbc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab tputs &a1 +&lab ph4 &a1(3) + ph2 &a1(2) + ph4 &a1(1) + case on + jsl tputs + case off + MEND diff --git a/bin/gsh/M/invoke.mac b/bin/gsh/M/invoke.mac new file mode 100644 index 0000000..dbd01aa --- /dev/null +++ b/bin/gsh/M/invoke.mac @@ -0,0 +1,588 @@ + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab SetInGlobals &a1 +&lab ph2 &a1(1) + ph2 &a1(2) + Tool $090c + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab GSStr &string +&lab dc i2'L:&string' + dc c"&string" + mend + MACRO +&lab MV2 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab Open &a1 +&lab gsos $2010,&a1 + mend + MACRO +&lab Close &a1 +&lab gsos $2014,&a1 + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + macro +&lab jcs &loc +&lab bcc *+5 + jmp &loc + mend + MACRO +&lab LD2 &val,&adr +&lab lcla &count + lda #&val +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab tcnewpgrp &a1 +&lab ph2 &a1 + case on + jsl tcnewpgrp + case off + MEND + MACRO +&lab settpgrp &a1 +&lab ph2 &a1 + case on + jsl settpgrp + case off + MEND + MACRO +&lab ora2 &arg1,&arg2,&dest +&lab anop + lclc &char +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + ora &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab jne &loc +&lab beq *+5 + jmp &loc + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab PopVariables &a1 +&lab p16 $117,&a1 + mend + MACRO +&lab PushVariables &a1 +&lab p16 $118,&a1 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab SetPrefix &a1 +&lab gsos $2009,&a1 + mend + MACRO +&lab GetFileInfo &a1 +&lab gsos $2006,&a1 + mend + MACRO +&lab unlock &a1 +&lab stz &a1 + MEND + MACRO +&lab key +&lab dc i2'0' + MEND + MACRO +&lab lock &a1 +&lab lda #1 + tsb &a1 + beq *+6 + cop $7F + bra *-7 + MEND + macro +&lab REDIRECT &a1 +&lab p16 $110,&a1 + mend + MACRO +&lab fork &a1 +&lab ph4 &a1 + case on + jsl fork + case off + MEND + macro +&lab SetInputDevice &a1 +&lab ph2 &a1(1) + ph4 &a1(2) + Tool $0f0c + mend + macro +&lab SetOutputDevice &a1 +&lab ph2 &a1(1) + ph4 &a1(2) + Tool $100c + mend + MACRO +&lab tctpgrp &a1 +&lab ph2 &a1(2) + ph2 &a1(1) + case on + jsl tctpgrp + case off + MEND + MACRO +&lab dup2 &a1 +&lab ph2 &a1(2) + ph2 &a1(1) + case on + jsl dup2 + case off + MEND + MACRO +&lab swait &a1 +&lab ph2 &a1 + case on + jsl swait + case off + MEND + MACRO +&lab ssignal &a1 +&lab ph2 &a1 + case on + jsl ssignal + case off + MEND + MACRO +&lab screate &a1 +&lab ph2 &a1 + case on + jsl screate + case off + MEND + MACRO +&lab sdelete &a1 +&lab ph2 &a1 + case on + jsl sdelete + case off + MEND + macro +&lab NewHandle &a1,&a2 +&lab pha + pha + ph4 &a1(1) + ph2 &a1(2) + ph2 &a1(3) + ph4 &a1(4) + tool $0902 + pl4 &a2 + mend + macro +&lab FindHandle &a1,&a2 +&lab pha + pha + ph4 &a1 + tool $1a02 + pl4 &a2 + mend + macro +&lab PtrToHand &a1 +&lab ph4 &a1(1) + ph4 &a1(2) + ph4 &a1(3) + tool $2802 + mend + macro +&lab pl4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"<>"{",.chk +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ldy #2 + pla + sta (&parm),y + ago .shorten +.chk + aif "&char"<>"[",.chk2 + pla + sta &parm + ldy #2 + pla + sta &parm,y + ago .shorten +.chk2 + aif "&char"<>"@",.absolute +&char1 amid &parm,2,1 +&char2 setc &char1 + pl&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + pl&char2 + ago .shorten +.absolute + pla + sta &parm + pla + sta &parm+2 +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab kill &a1 +&lab ph2 &a1(2) + ph2 &a1(1) + case on + jsl kill + case off + MEND + MACRO +&lab getpgrp &a1 +&lab ph2 &a1 + case on + jsl getpgrp + case off + MEND + MACRO +&lab sigpause &a1 +&lab ph4 &a1 + case on + jsl sigpause + case off + MEND + MACRO +&lab signal &a1 +&lab ph4 &a1(2) + ph2 &a1(1) + case on + jsl signal + case off + MEND diff --git a/bin/gsh/M/jobs.mac b/bin/gsh/M/jobs.mac new file mode 100644 index 0000000..66344cb --- /dev/null +++ b/bin/gsh/M/jobs.mac @@ -0,0 +1,527 @@ + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab MV2 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab LD2 &val,&adr +&lab lcla &count + lda #&val +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab getpid +&lab case on + jsl getpid + case off + MEND + MACRO +&lab ora2 &arg1,&arg2,&dest +&lab anop + lclc &char +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + ora &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab Dec2Int &a1,&a2 +&lab pha + ph4 &a1(1) + ph2 &a1(2) + ph2 &a1(3) + Tool $280b + pl2 &a2 + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend + MACRO +&lab Int2Dec &a1 +&lab ph2 &a1(1) + ph4 &a1(2) + ph2 &a1(3) + ph2 &a1(4) + Tool $260b + mend + MACRO +&lab LD4 &val,&adr +&lab lcla &count + lda #<&val +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda #+(&val)|-16 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + macro +&lab Set_Variable &a1 +&lab p16 $106,&a1 + mend + MACRO +&lab wait &a1 +&lab ph4 &a1 + case on + jsl wait + case off + MEND + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab jne &loc +&lab beq *+5 + jmp &loc + mend + MACRO +&lab dey2 +&lab dey + dey + mend + MACRO +&lab kill &a1 +&lab ph2 &a1(2) + ph2 &a1(1) + case on + jsl kill + case off + MEND + MACRO +&lab sigsetmask &a1 +&lab ph4 &a1 + case on + jsl sigsetmask + case off + MEND + MACRO +&lab sigblock &a1 +&lab ph4 &a1 + case on + jsl sigblock + case off + MEND + MACRO +&lab tctpgrp &a1 +&lab ph2 &a1(2) + ph2 &a1(1) + case on + jsl tctpgrp + case off + MEND + MACRO +&lab sigpause &a1 +&lab ph4 &a1 + case on + jsl sigpause + case off + MEND + MACRO +&lab getpgrp &a1 +&lab ph2 &a1 + case on + jsl getpgrp + case off + MEND + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + macro +&lab jcs &loc +&lab bcc *+5 + jmp &loc + mend + MACRO +&lab jcc &loc +&lab bcs *+5 + jmp &loc + mend diff --git a/bin/gsh/M/main.mac b/bin/gsh/M/main.mac new file mode 100644 index 0000000..d81c41e --- /dev/null +++ b/bin/gsh/M/main.mac @@ -0,0 +1,297 @@ + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + macro +&lab ErrWriteCString &a1 +&lab ph4 &a1 + Tool $210c + mend + MACRO +&lab kernStatus &a1 +&lab pha + ldx #$603 + jsl $E10008 + pl2 &a1 + MEND + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab MV2 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab add4 &arg1,&arg2,&dest +&lab anop + lclc &ch +&ch amid &arg2,1,1 + clc + lda &arg1 + adc &arg2 + sta &dest + lda &arg1+2 + aif "&ch"="#",.a + adc &arg2+2 + ago .b +.a + adc &arg2|-16 +.b + sta &dest+2 + mend diff --git a/bin/gsh/M/orca.mac b/bin/gsh/M/orca.mac new file mode 100644 index 0000000..2811ab7 --- /dev/null +++ b/bin/gsh/M/orca.mac @@ -0,0 +1,304 @@ + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend + MACRO +&lab iny2 +&lab iny + iny + mend + MACRO +&lab jcc &loc +&lab bcs *+5 + jmp &loc + mend + macro +&lab ExpandPath &a1 +&lab gsos $200E,&a1 + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + macro +&lab SET_LINFOGS &a1 +&lab p16 $142,&a1 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend diff --git a/bin/gsh/M/prompt.mac b/bin/gsh/M/prompt.mac new file mode 100644 index 0000000..d4f0dd3 --- /dev/null +++ b/bin/gsh/M/prompt.mac @@ -0,0 +1,374 @@ + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab WriteCString &a1 +&lab ph4 &a1 + Tool $200c + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab WriteChar &a1 +&lab ph2 &a1 + Tool $180c + mend + MACRO +&lab Int2Dec &a1 +&lab ph2 &a1(1) + ph4 &a1(2) + ph2 &a1(3) + ph2 &a1(4) + Tool $260b + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab ReadTimeHex &a1 +&lab pha + pha + pha + pha + tool $0d03 + pl2 &a1(1) + pl2 &a1(2) + pl2 &a1(3) + pl2 &a1(4) + mend + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend + MACRO +&lab sub2 &arg1,&arg2,&dest + lclc &char +&lab sec +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .sub +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .sub +.x1 + txa + ago .sub +.y1 + tya +.sub + sbc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab if2 &var,&rel,&val,&label +&lab ago .skip + ble + bgt +.skip + lclc &char1 + lclc &char2 +&char1 amid &var,1,1 +&char2 amid &var,2,1 + aif "&char1"="@",.index + lda &var +.cmp + cmp &val + ago .branch +.index + aif "&char2"="x",.x1 + aif "&char2"="X",.x1 + aif "&char2"="y",.y1 + aif "&char2"="Y",.y1 + ago ^cmp +.x1 + cpx &val + ago .branch +.y1 + cpy &val +.branch +&char1 amid &rel,1,1 + aif "&char1"="@",.done + b&rel &label +.done + mend + MACRO +&lab bgt &loc +&lab beq *+4 + bcs &loc + mend + MACRO +&lab ble &loc +&lab bcc &loc + beq &loc + mend + MACRO +&lab GetPrefix &a1 +&lab gsos $200A,&a1 + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab READ_VARIABLE &a1 +&lab p16 $10B,&a1 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend + MACRO +&lab WriteString &a1 +&lab ph4 &a1 + Tool $1c0c + mend diff --git a/bin/gsh/M/shell.mac b/bin/gsh/M/shell.mac new file mode 100644 index 0000000..7b5604e --- /dev/null +++ b/bin/gsh/M/shell.mac @@ -0,0 +1,405 @@ + MACRO +&lab Quit &a1 +&lab gsos $2029,&a1 + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab WriteCString &a1 +&lab ph4 &a1 + Tool $200c + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab GSStr &string +&lab dc i2'L:&string' + dc c"&string" + mend + MACRO +&lab MV2 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab Open &a1 +&lab gsos $2010,&a1 + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab signal &a1 +&lab ph4 &a1(2) + ph2 &a1(1) + case on + jsl signal + case off + MEND + MACRO +&lab setsystemvector &a1 +&lab ph4 &a1 + case on + jsl setsystemvector + case off + MEND + MACRO +&lab tcnewpgrp &a1 +&lab ph2 &a1 + case on + jsl tcnewpgrp + case off + MEND + MACRO +&lab settpgrp &a1 +&lab ph2 &a1 + case on + jsl settpgrp + case off + MEND + MACRO +&lab getpid +&lab case on + jsl getpid + case off + MEND + MACRO +&lab ora2 &arg1,&arg2,&dest +&lab anop + lclc &char +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + ora &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + macro +&lab ErrWriteCString &a1 +&lab ph4 &a1 + Tool $210c + mend + MACRO +&lab PopVariables &a1 +&lab p16 $117,&a1 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + macro +&l dosin &adr +&l dc i"l:~&sysname&syscnt" +~&sysname&syscnt dc c"&adr" + mend diff --git a/bin/gsh/M/shellutil.mac b/bin/gsh/M/shellutil.mac new file mode 100644 index 0000000..367f01f --- /dev/null +++ b/bin/gsh/M/shellutil.mac @@ -0,0 +1,185 @@ + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab READ_VARIABLE &a1 +&lab p16 $10B,&a1 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab unlock &a1 +&lab stz &a1 + MEND + MACRO +&lab key +&lab dc i2'0' + MEND + MACRO +&lab lock &a1 +&lab lda #1 + tsb &a1 + beq *+6 + cop $7F + bra *-7 + MEND diff --git a/bin/gsh/M/shellvar.mac b/bin/gsh/M/shellvar.mac new file mode 100644 index 0000000..27ae33b --- /dev/null +++ b/bin/gsh/M/shellvar.mac @@ -0,0 +1,338 @@ + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab LD2 &val,&adr +&lab lcla &count + lda #&val +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab PopVariables &a1 +&lab p16 $117,&a1 + mend + MACRO +&lab PushVariables &a1 +&lab p16 $118,&a1 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab jeq &loc +&lab bne *+5 + jmp &loc + mend + MACRO +&lab READ_VARIABLE &a1 +&lab p16 $10B,&a1 + mend + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab iny2 +&lab iny + iny + mend + MACRO +&lab ERROR &a1 +&lab p16 $105,&a1 + mend + macro +&lab Set_Variable &a1 +&lab p16 $106,&a1 + mend + MACRO +&lab READ_INDEXED &a1 +&lab p16 $108,&a1 + mend + macro +&lab UnsetVariable &a1 +&lab p16 $115,&a1 + mend + macro +&lab EXPORT &a1 +&lab p16 $116,&a1 + mend diff --git a/bin/gsh/M/stdio.mac b/bin/gsh/M/stdio.mac new file mode 100644 index 0000000..10e6ba8 --- /dev/null +++ b/bin/gsh/M/stdio.mac @@ -0,0 +1,92 @@ + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab Write &a1 +&lab gsos $2013,&a1 + mend + MACRO +&lab gsos &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + MACRO +&lab unlock &a1 +&lab stz &a1 + MEND + MACRO +&lab lock &a1 +&lab lda #1 + tsb &a1 + beq *+6 + cop $7F + bra *-7 + MEND + MACRO +&lab key +&lab dc i2'0' + MEND + macro +&lab Read &a1 +&lab gsos $2012,&a1 + mend + macro +&lab Flush &a1 +&lab gsos $2015,&a1 + mend diff --git a/bin/gsh/M/sv.mac b/bin/gsh/M/sv.mac new file mode 100644 index 0000000..877d350 --- /dev/null +++ b/bin/gsh/M/sv.mac @@ -0,0 +1,355 @@ + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab add4 &arg1,&arg2,&dest +&lab anop + lclc &ch +&ch amid &arg2,1,1 + clc + lda &arg1 + adc &arg2 + sta &dest + lda &arg1+2 + aif "&ch"="#",.a + adc &arg2+2 + ago .b +.a + adc &arg2|-16 +.b + sta &dest+2 + mend + macro +&lab sub4 &arg1,&arg2,&dest +&lab anop + lclc &ch +&ch amid &arg2,1,1 + sec + lda &arg1 + sbc &arg2 + sta &dest + lda &arg1+2 + aif "&ch"="#",.a + sbc &arg2+2 + ago .b +.a + sbc &arg2|-16 +.b + sta &dest+2 + mend + MACRO +&lab add2 &arg1,&arg2,&dest + lclc &char +&lab clc +&char amid &arg1,1,1 + aif "&char"="@",.at1 + lda &arg1 + ago .add +.at1 +&char amid &arg1,2,1 + aif "&char"="x",.x1 + aif "&char"="X",.x1 + aif "&char"="y",.y1 + aif "&char"="Y",.y1 + ago .add +.x1 + txa + ago .add +.y1 + tya +.add + adc &arg2 +&char amid &dest,1,1 + aif "&char"="@",.at2 + sta &dest + ago .b +.at2 +&char amid &dest,2,1 + aif "&char"="x",.x2 + aif "&char"="X",.x2 + aif "&char"="y",.y2 + aif "&char"="Y",.y2 + ago .b +.x2 + tax + ago .b +.y2 + tay +.b + mend + MACRO +&lab UDivide &a1,&a2 +&lab pha + pha + ph2 &a1(1) + ph2 &a1(2) + Tool $0b0b + pl2 &a2(1) + pl2 &a2(2) + mend + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab pl2 &parm + lclc &char +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"="@",.at + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ago .shorten +.absolute + pla + sta &parm + ago .shorten +.at +&char amid &parm,2,1 + pl&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing Closing '}'",16 + mend + MACRO +&lab long &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi on +&t seta &t+16 + ago ^c +.m + longa on +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + rep #&t +.d + mend + MACRO +&lab short &stat +&lab anop + lcla &t + lcla &len + lclc &ch +&t seta 0 +&len seta l:&stat +.a + aif &len=0,.b +&ch amid &stat,&len,1 + aif ("&ch"="x").or.("&ch"="y").or.("&ch"="i"),.i + aif ("&ch"="a").or.("&ch"="m"),.m +.c +&len seta &len-1 + ago ^a +.i + longi off +&t seta &t+16 + ago ^c +.m + longa off +&t seta &t+32 + ago ^c +.b + aif &t=0,.d + sep #&t +.d + mend + MACRO +&lab MV2 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop +.done + mend + macro +&lab jmi &loc +&lab bpl *+5 + jmp &loc + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab jcc &loc +&lab bcs *+5 + jmp &loc + mend diff --git a/bin/gsh/M/term.mac b/bin/gsh/M/term.mac new file mode 100644 index 0000000..5c564f3 --- /dev/null +++ b/bin/gsh/M/term.mac @@ -0,0 +1,264 @@ + MACRO +&lab tgetent &a1 +&lab ph4 &a1(2) + ph4 &a1(1) + case on + jsl tgetent + case off + MEND + MACRO +&lab tgetstr &a1 +&lab ph4 &a1(2) + ph4 &a1(1) + case on + jsl tgetstr + case off + MEND + MACRO +&lab tputs &a1 +&lab ph4 &a1(3) + ph2 &a1(2) + ph4 &a1(1) + case on + jsl tputs + case off + MEND + MACRO +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + macro +&lab MV4 &src,&adr +&lab lcla &count + lda &src +&count seta 1 +.loop1 + sta &adr(&count) +&count seta &count+1 + aif &count>c:&adr,.part2 + ago ^loop1 +.part2 + lda &src+2 +&count seta 1 +.loop2 + sta &adr(&count)+2 +&count seta &count+1 + aif &count>c:&adr,.done + ago ^loop2 +.done + mend + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab Str &string +&lab dc i1'L:&string' + dc c"&string" + mend + macro +&lab Set_Variable &a1 +&lab p16 $106,&a1 + mend + MACRO +&lab p16 &a1,&a2 +&lab jsl $E100A8 + dc i2'&a1' + dc i4'&a2' + mend + macro +&lab EXPORT &a1 +&lab p16 $116,&a1 + mend + MACRO +&lab ioctl &a1 +&lab ph4 &a1(3) + ph4 &a1(2) + ph2 &a1(1) + case on + jsl ioctl + case off + MEND diff --git a/bin/gsh/Makefile b/bin/gsh/Makefile new file mode 100644 index 0000000..7ce4a6e --- /dev/null +++ b/bin/gsh/Makefile @@ -0,0 +1,87 @@ +# +# GNO Shell Makefile +# by T Meekins +# + +o/main.root: main.asm + purge ; compile main.asm keep=o/main + +o/shell.root: shell.asm m/shell.mac + purge ; compile shell.asm keep=o/shell + +o/history.root: history.asm m/history.mac + purge ; compile history.asm keep=o/history + +o/prompt.root: prompt.asm m/prompt.mac + purge ; compile prompt.asm keep=o/prompt + +o/cmd.root: cmd.asm m/cmd.mac + purge ; compile cmd.asm keep=o/cmd + +o/expand.root: expand.asm m/expand.mac + purge ; compile expand.asm keep=o/expand + +o/invoke.root: invoke.asm m/invoke.mac + purge ; compile invoke.asm keep=o/invoke + +o/shellutil.root: shellutil.asm m/shellutil.mac + purge ; compile shellutil.asm keep=o/shellutil + +o/builtin.root: builtin.asm m/builtin.mac + purge ; compile builtin.asm keep=o/builtin + +o/hash.root: hash.asm m/hash.mac + purge ; compile hash.asm keep=o/hash + +o/alias.root: alias.asm m/alias.mac + purge ; compile alias.asm keep=o/alias + +o/dir.root: dir.asm m/dir.mac + purge ; compile dir.asm keep=o/dir + +o/shellvar.root: shellvar.asm m/shellvar.mac + purge ; compile shellvar.asm keep=o/shellvar + +o/jobs.root: jobs.asm m/jobs.mac + purge ; compile jobs.asm keep=o/jobs + +o/sv.root: sv.asm m/sv.mac + purge ; compile sv.asm keep=o/sv + +o/stdio.root: stdio.asm m/stdio.mac + purge ; compile stdio.asm keep=o/stdio + +o/orca.root: orca.asm m/orca.mac + purge ; compile orca.asm keep=o/orca + +o/edit.root: edit.asm m/edit.mac + purge ; compile edit.asm keep=o/edit + +o/term.root: term.asm m/term.mac + purge ; compile term.asm keep=o/term + +o/bufpool.root: bufpool.asm m/bufpool.mac + purge ; compile bufpool.asm keep=o/bufpool + +shell: o/main.root \ + o/shell.root \ + o/history.root \ + o/prompt.root \ + o/cmd.root \ + o/expand.root \ + o/invoke.root \ + o/shellutil.root \ + o/builtin.root \ + o/hash.root \ + o/alias.root \ + o/shellvar.root \ + o/jobs.root \ + o/dir.root \ + o/sv.root \ + o/stdio.root \ + o/orca.root \ + o/edit.root \ + o/term.root \ + o/bufpool.root \ + direct.root + pwd ; purge ; compile link.script keep=gsh diff --git a/bin/gsh/To.Do b/bin/gsh/To.Do new file mode 100644 index 0000000..9ee7860 --- /dev/null +++ b/bin/gsh/To.Do @@ -0,0 +1,44 @@ +Need to modify Tim's mutex code to be: + +t lda #1 + tsb mutex + beq go + cop $7F + bra t +go ; execute code here +------------------------------------ + +coolish handling of setdebug by editor. + +When building the EXE hash table, duplicate entries oughta should be ignored. + +When a background process finishes and there's text in the input buffer, +the next keypress correctly reprints the edit line but the key itself does +not get put in the buffer. + +running a process in the background from inside a script (not 'source', +but executing the script as a command) causes the shell to wait for that +background process to end - not exactly what we want. + +recursive aliases. + +multiple files for 'edit'. + +'df' lists a bunch appleshare shit. + +change updatevars to do a read_variable for better performance (and +for correctness!) + +-a in ps (and any other redeemable switches) + +job control monitor for defunct processes when waiting. + +usage for alias and hash + +job control needs to save tty information. + +echo should use octal and hex \12 is dec, \012 is octal, \x12 is hex. + +write new memory management. + +write history expansion. diff --git a/bin/gsh/UpdateLog b/bin/gsh/UpdateLog new file mode 100644 index 0000000..b8547ef --- /dev/null +++ b/bin/gsh/UpdateLog @@ -0,0 +1,158 @@ +GSH 1.1 UPDATES... + + 2/25/92 d01 - fixed a problem with the command-line aborting after certain + built-ins are run. + 4/03/92 d02 - .ttya and .ttyb are displayed as 'ta' and 'tb' respectively in + 'ps'. + - "USER" field has been renamed to "MMID" in 'ps'. + d03 - removed all the extra newlines around 'There are stopped jobs' + message. + - 'exit' in a shell script aborts the script, instead of quitting + gsh itself. + - when getting a 'There are stopped jobs' message, a second + attempt to exit the shell will result in all jobs being killed + and the shell will exit. No commands may appear between the + two attempts to exit. This is basically just like csh behaviour. + d04 - motd pathname has been changed to '31:etc:motd' where 31 is the + location of GNO, not the user directory. eventually motd will + be removed from gsh and will be handled by login or something + similar. + 4/07/92 d05 - ^D and TAB expansion now properly works on */ boot prefix. + 4/13/92 d06 - started work on new string vector library. + - started new builtin - 'hash' to display all hashed files. + Extremely preliminary. + 4/14/92 d07 - 'hash' now uses string vectors to build the hash list for + displaying + - fixed a problem if no files were hashed. + - sv_alloc now makes sure there is an extra null at the end + of the allocated string vector. + 4/20/92 d08 - 'which' puts the filename after the path for commands in + the current directory. + d09 - wrote a string vector function for printing the string + vectors in columns like 'ls'. 'hash' now calls this. + 4/21/92 d10 - wrote routine for sorting string vectors...'hash' now sorts the + list... + 4/23/92 d11 - full directory stack support!! pushd, popd, and dirs!! + d12 - 'ps' displays 'nu' for the .null driver under TT field. + 4/25/92 d13 - Added '-l' option to 'kill'. + 6/22/92 d14 - Began writing custom stdio for the shell using GS/OS output. + 6/23/92 - minor optimization to alias hashing. + - finished stdout and stderr for gsh. + d15 - history file is no longer deleted on gsh start-up + - fixed '~' printer used in 'dirs'. /usr2/ was displayed as + ~2 if $home was /usr. Looked real dumb :) and was incorrect. + - optimizations to job control + d16 - echo flushes the stdio when finished. + 6/24/92 - fixed bug in system() call vector..make should work better now :) + - added a newline after 'pwd'. + - wrote 'edit' built-in. + 6/26/92 d17 - began work on stdin for gsh. Uses GS/OS, ioctl(), etc... + - began rewriting editor. Now uses key translation tables and + command jump tables. + - editor now accepts multiple character commands. + 6/27/92 - further work on editor + - started work on termcap support in gsh. most command-line + editing uses termcap now. + 6/28/92 - continued work on editor and termcap + - 'clear' and 'echo' builtins now use termcap. + - prompt now uses termcap. + - hacked up a quick 'tset' builtin. + - wrote keybinding function, termcap arrow keys now bound! + - beta test release sent out + 6/29/92 d18 - if alias 'precmd' is defined, it is executed before drawing + each prompt. + - if $pushdsilent is set, then directory stack not displayed + after 'pushd' and 'popd'. + - termcap optimizations for history mechanism in editor. + - termcap optimizations for kill-line and kill-end-of-line. + - fixed bug in overwrite mode of editor...required too many + returns to end line -> rts's weren't being pulled off the + stack :) + 6/30/92 - fixed a bug in the 'which' command when displaying files in cwd. + - the cursor is now left on when running applications. + - added '-c' option to gsh command-line + - wrote 'source' built-in + 7/04/92 - fixed two bugs in prompt display code. + 7/17/92 - fixed puts to not choke on NULL strings. + 7/21/92 - Temporarily added Push/PopVariables to the code + - ospeed is now set so that padding can be done by termcap. + This fixed the dropped characters on my Xerox terminal when + doing screen clears. + - fixed a bug in 'tset'. Was doing a jsr instead of jsl. oops. + - set term can be in gshrc w/o manually doing a tset now. + - 'ps' now scans job list to find names of 'forked' processes. + - 'ps' nows displays tty numbers, since the ttyname is set + in 31/etc/ttys and not necessarily second-guessed by gsh. + 7/25/92 - fixed cursor off problems. + 8/26/92 d19 - larger number of builtins can be redirected or piped. + - Open-Apple is now mapped to meta (ESC). + - The editor tells gnocon to translate arrows into VT100 codes. + - fixed editor bug clearing entire line. + - wrote 'bindkey' built-in. + 8/27/92 d20 - faster built-in searching. + - wrote 'setenv' builtin. + 8/28/92 - termcap optimizations to word completion + - word completion now matches variables if word starts with '$'. + 8/29/92 - only executuables are expanded if the word is a command. All + files are expanded for arguments. + 8/30/92 - words to complete no longer need to be separated with spaces, + ';','|', and '&' are now also recognized. + 9/01/92 - 'cd' no longer reports bad pathname syntax if $home not set. + - 'pid' parsing now does syntax checking :) + - kill won't allow killing process 0 + - changed 'jobs' invocation from method 0 to method 1. + - word completion will not occur if the word contains an '=', + single quote or double quote. + 9/03/92 - fixed memory trashing problem in 'source' + 9/04/92 - 'ps' only displays processes with the users uid. Be sure to + use login, or you'll be the kernel's uid and get to see all + of the kernel's processes as your own. + 9/10/92 - forgot to 'clc' when alias not found in 'alias foo'. + 9/20/92 - fixed open-apple mapping + - changed keyboard mapping + - tab expands directories as the command + - set problem with '-f' fixed + 9/21/92 - fixed 'cd' with no arguments. + - fixed 'set foo' and 'setenv foo'. + - fixed bug again in 'cd'. + - 'set' and 'setenv' list exported variable names in upper case + - fixed a probelm in puts when passed a null pointer. + - fixed pointer bug in '~' compactor + - wrote 256 byte buffer pool + 9/22/92 - fixed parsing bug when parsing two or more command-lines + simultaneously. + - wrote 1024 byte buffer pool. + - word completion now matches built-ins + - wordmatching ignores matches if the suffix is contained in + the $fignore variable. +10/31/92 d21 - fixed bug in piping mechanism. +11/04/92 - fixed hashing problems. +11/17/92 - new builtin 'commands' lists all built-in commands. Try aliasing + help to this for beginning users. +01/17/93 b01 - fixed prefix not printing correctly if zero length prefix. + - word completion will expand to proper case. +01/20/93 b02 - removed motd printing from gsh +02/08/93 - fixed job control setting of terminal when background job + completes. +02/09/93 - ^C & ^Z printing removed from the shell. The kernel will do + this now. +02/17/93 b03 - gshrc is now read as '@:gshrc' +03/02/93 - 'set' automatically detects changing $term and auto-peforms a + tset. manually typing 'tset' is no longer required though it is + still included. + - prompts can now contain \n,\r,\t,\b. +03/10/93 - updated automatic variable setting code. works faster now. + - optimized low-level string routines +03/25/93 - fixed NULL commands aborting entire command-lines. +04/04/93 - history commands can now be greater than 256 characters, though + when being read, they are clipped to 1024. + - the history file location has been moved to '@:history' + - if $ignoreeof is set, then EOF (^D) will not quit the shell. + - %U and %u will start and end underlining in prompts. +04/22/93 b04 - 'df' displays device numbers + - gsh now takes commands as command-line input. ie., + 'gsh echo hello, world' will start gsh then gsh will run echo. + - fixed a nasty shell script bug that basically rendered it useless. + - fixed memory trashing in shell scripts. + - fixed memory trashing in histories. +04/26/94 b05 - which no longers displays the command-name first. diff --git a/bin/gsh/alias.asm b/bin/gsh/alias.asm new file mode 100644 index 0000000..d9cc80a --- /dev/null +++ b/bin/gsh/alias.asm @@ -0,0 +1,798 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* ALIAS.ASM +* By Tim Meekins +* +************************************************************************** + + keep o/alias + mcopy m/alias.mac + +VTABSIZE gequ 17 + +************************************************************************** +* +* ALIAS: builtin command +* syntax: alias [name [def]] +* +* set aliases +* +************************************************************************** + +alias START + +arg equ 1 +space equ arg+4 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + lda argc + dec a + beq showall + dec a + beq showone + jmp setalias + +showall jsl startalias +showloop jsl nextalias + sta arg + stx arg+2 + ora arg+2 + beq noshow + ldy #6 + lda [arg],y + tax + ldy #4 + lda [arg],y + jsr puts + lda #':' + jsr putchar + lda #' ' + jsr putchar + ldy #10 + lda [arg],y + tax + ldy #8 + lda [arg],y + jsr puts + jsr newline + bra showloop + +noshow jmp exit + +showone ldy #4+2 + lda [argv],y + tax + pha ;for findalias + ldy #4 + lda [argv],y + pha + jsr puts + lda #':' + jsr putchar + lda #' ' + jsr putchar + jsl findalias + sta arg + stx arg+2 + ora arg+2 + beq notthere + lda arg + jsr puts + jsr newline + jmp exit +notthere ldx #^noalias + lda #noalias + jsr puts + jmp exit + +setalias ldy #4+2 ;put alias name on stack + lda [argv],y + pha + ldy #4 + lda [argv],y + pha + + ph4 #2 + jsl ~NEW + sta arg + stx arg+2 + lda #0 + sta [arg] + + add2 argv,#8,argv + + dec2 argc + +buildalias lda argc + beq setit + + pei (arg+2) + pei (arg) + pei (arg+2) + pei (arg) + ldy #2 + lda [argv],y + pha + lda [argv] + pha + jsr catcstr + stx arg+2 + sta arg + jsl nullfree + + pei (arg+2) + pei (arg) + pei (arg+2) + pei (arg) + ph4 #spacestr + jsr catcstr + stx arg+2 + sta arg + jsl nullfree + + dec argc + add2 argv,#4,argv + bra buildalias + +setit pei (arg+2) + pei (arg) + jsl addalias + pei (arg+2) + pei (arg) + jsl nullfree + +exit lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +noalias dc c'Alias not defined',h'0d00' +spacestr dc c' ',h'00' + + END + +************************************************************************** +* +* UNALIAS: builtin command +* syntax: unalias [var ...] +* +* removes each alias listed +* +************************************************************************** + +unalias START + +space equ 1 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + phd + tcd + + lda argc + dec a + bne loop + + ldx #^Usage + lda #USage + jsr errputs + bra done + +loop add2 argv,#4,argv + dec argc + beq done + + ldy #2 + lda [argv],y + pha + lda [argv] + pha + jsl removealias + + bra loop + +done lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +Usage dc c'Usage: unalias name ...',h'0d00' + + END + +;========================================================================= +; +; Init alias table +; +;========================================================================= + +initalias START + + using AliasData + + lda #0 + ldy #VTABSIZE + tax #0 +yahaha sta AliasTable,x + inx2 + sta AliasTable,x + inx2 + dey + bne yahaha + + rts + + END + +;========================================================================= +; +; Expand alias +; +;========================================================================= + +expandalias START + +outbuf equ 0 +sub equ outbuf+4 +word equ sub+4 +buf equ word+4 +space equ buf+4 + + subroutine (4:cmd),space + + ph4 #1024 + jsl ~NEW + stx buf+2 + sta buf + stx outbuf+2 + sta outbuf + jsl alloc1024 + stx word+2 + sta word + lda #0 + sta [buf] ;In case we're called with empty string +; +; eat leading spaces +; +eatleader lda [cmd] + and #$FF + jeq done + cmp #' ' + bne getword + inc cmd + sta [outbuf] + inc outbuf + bra eatleader +; +; find the leading word +; +getword short a + ldy #0 +makeword lda [cmd],y + if2 @a,eq,#0,gotword + if2 @a,eq,#' ',gotword + if2 @a,eq,#';',gotword + if2 @a,eq,#'&',gotword + if2 @a,eq,#'|',gotword + if2 @a,eq,#'>',gotword + if2 @a,eq,#'<',gotword + if2 @a,eq,#13,gotword + if2 @a,eq,#9,gotword + if2 @a,eq,#10,gotword + sta [word],y + iny + bra makeword +; +; we got a word, now check if it's an alias +; +gotword lda #0 + sta [word],y + long a + add2 @y,cmd,cmd + phy + pei (word+2) + pei (word) + jsl findalias + sta sub + stx sub+2 + ora sub+2 + beq noalias +; +; expand it, if you hadn't figured it out for yourself by now. +; + pla + ldy #0 +putalias lda [sub],y + and #$FF + beq next + sta [outbuf] + inc outbuf + iny + bra putalias +; +; no alias, so just copy the original string +; +noalias plx + beq next + ldy #0 +noalias2 lda [word],y + sta [outbuf] + inc outbuf + iny + dex + bne noalias2 +; +; the alias is expanded, now copy until we reach the next command +; +next lda [cmd] + inc cmd + sta [outbuf] + inc outbuf + and #$FF + beq done + if2 @a,eq,#13,nextalias + if2 @a,eq,#';',nextalias + if2 @a,eq,#'&',nextalias + if2 @a,eq,#'|',nextalias + if2 @a,eq,#'\',backstabber + if2 @a,eq,#"'",singquoter + if2 @a,eq,#'"',doubquoter + bra next +backstabber lda [cmd] + inc cmd + sta [outbuf] + inc outbuf + and #$FF + beq done + bra next +singquoter lda [cmd] + inc cmd + sta [outbuf] + inc outbuf + and #$FF + beq done + if2 @a,ne,#"'",singquoter + bra next +doubquoter lda [cmd] + inc cmd + sta [outbuf] + inc outbuf + and #$FF + beq done + if2 @a,ne,#"'",singquoter + bra next + +nextalias jmp eatleader + +done ldx word+2 + lda word + jsl free1024 + + return 4:buf + + END + +;========================================================================= +; +; Add alias to table +; +;========================================================================= + +addalias START + + using AliasData + +tmp equ 0 +ptr equ tmp+4 +hashval equ ptr+4 +space equ hashval+4 + + subroutine (4:aliasname,4:aliasval),space + + pei (aliasname+2) + pei (aliasname) + jsl hashalias + sta hashval + + tax + lda AliasTable,x + sta ptr + lda AliasTable+2,x + sta ptr+2 + +search lda ptr + ora ptr + beq notfound + ldy #4 + lda [ptr],y + tax + ldy #4+2 + lda [ptr],y + pha + phx + pei (aliasname+2) + pei (aliasname) + jsr cmpcstr + jeq replace + ldy #2 + lda [ptr] + tax + lda [ptr],y + sta ptr+2 + stx ptr + bra search + +replace ldy #8+2 + lda [ptr],y + pha + ldy #8 + lda [ptr],y + pha + jsl nullfree + pei (aliasval+2) + pei (aliasval) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + sta tmp + stx tmp+2 + ldy #8 + sta [ptr],y + ldy #8+2 + txa + sta [ptr],y + pei (aliasval+2) + pei (aliasval) + pei (tmp+2) + pei (tmp) + jsr copycstr + bra done + +notfound ph4 #4*3 + jsl ~NEW + sta ptr + stx ptr+2 + ldy #2 + ldx hashval + lda AliasTable,x + sta [ptr] + lda AliasTable+2,x + sta [ptr],y + pei (aliasname+2) + pei (aliasname) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + sta tmp + stx tmp+2 + ldy #4 + sta [ptr],y + ldy #4+2 + txa + sta [ptr],y + pei (aliasname+2) + pei (aliasname) + pei (tmp+2) + pei (tmp) + jsr copycstr + pei (aliasval+2) + pei (aliasval) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + sta tmp + stx tmp+2 + ldy #8 + sta [ptr],y + ldy #8+2 + txa + sta [ptr],y + pei (aliasval+2) + pei (aliasval) + pei (tmp+2) + pei (tmp) + jsr copycstr + ldx hashval + lda ptr + sta AliasTable,x + lda ptr+2 + sta AliasTable+2,x + +done return + + END + +;========================================================================= +; +; Remove an alias +; +;========================================================================= + +removealias START + + using AliasData + +oldptr equ 0 +ptr equ oldptr+4 +space equ ptr+4 + + subroutine (4:aliasname),space + + pei (aliasname+2) + pei (aliasname) + jsl hashalias + tax + lda AliasTable,x + sta ptr + lda AliasTable+2,x + sta ptr+2 + lda #^Aliastable + sta oldptr+2 + clc + txa + adc #AliasTable + sta oldptr + +searchloop ora2 ptr,ptr+2,@a + beq done + + ldy #4+2 + lda [ptr],y + pha + ldy #4 + lda [ptr],y + pha + pei (aliasname+2) + pei (aliasname) + jsr cmpcstr + beq foundit + mv4 ptr,oldptr + ldy #2 + lda [ptr],y + tax + lda [ptr] + sta ptr + stx ptr+2 + bra searchloop + +foundit ldy #2 + lda [ptr],y + sta [oldptr],y + lda [ptr] + sta [oldptr] + ldy #4+2 + lda [ptr],y + pha + ldy #4 + lda [ptr],y + pha + jsl nullfree + ldy #8+2 + lda [ptr],y + pha + ldy #8 + lda [ptr],y + pha + jsl nullfree + pei (ptr+2) + pei (ptr) + jsl nullfree + +done return + + END + +;========================================================================= +; +; Find an alias +; +;========================================================================= + +findalias START + + using AliasData + +ptr equ 0 +value equ ptr+4 +space equ value+4 + + subroutine (4:aliasname),space + + stz value + stz value+2 + + pei (aliasname+2) + pei (aliasname) + jsl hashalias + tax + lda AliasTable,x + sta ptr + lda AliasTable+2,x + sta ptr+2 + +searchloop ora2 ptr,ptr+2,@a + beq done + + ldy #4+2 + lda [ptr],y + pha + ldy #4 + lda [ptr],y + pha + pei (aliasname+2) + pei (aliasname) + jsr cmpcstr + beq foundit + ldy #2 + lda [ptr],y + tax + lda [ptr] + sta ptr + stx ptr+2 + bra searchloop + +foundit ldy #8 + lda [ptr],y + sta value + ldy #8+2 + lda [ptr],y + sta value+2 + +done return 4:value + + END + +;========================================================================= +; +; Start alias +; +;========================================================================= + +startalias START + + using AliasData + + stz AliasNum + mv4 AliasTable,AliasPtr + rtl + + END + +;========================================================================= +; +; Next alias +; +;========================================================================= + +nextalias START + + using AliasData + +value equ 0 +space equ value+4 + + subroutine (0:fubar),space + + stz value + stz value+2 +puke if2 AliasNum,cs,#VTABSIZE,done + + ora2 AliasPtr,AliasPtr+2,@a + bne flush + inc AliasNum + lda AliasNum + asl2 a + tax + lda AliasTable,x + sta AliasPtr + lda AliasTable+2,x + sta AliasPtr+2 + bra puke + +flush mv4 AliasPtr,value + ldy #2 + lda [value] + sta AliasPtr + lda [value],y + sta AliasPtr+2 + +done return 4:value + + END + +;========================================================================= +; +; Hash an alias +; +;========================================================================= + +hashalias PRIVATE + +hashval equ 0 +space equ hashval+2 + + subroutine (4:p),space + + lda #11 + sta hashval + + ldy #0 +loop asl hashval + lda [p],y + and #$FF + beq done + clc + adc hashval + sta hashval + iny + bra loop +done UDivide (hashval,#VTABSIZE),(@a,@a) + + asl2 a ;Make it an index. + sta hashval + + return 2:hashval + + END + +;========================================================================= +; +; Alias data +; +;========================================================================= + +AliasData DATA + +AliasNum dc i2'0' +AliasPtr dc i4'0' + +AliasTable ds VTABSIZE*4 + + END diff --git a/bin/gsh/bufpool.asm b/bin/gsh/bufpool.asm new file mode 100644 index 0000000..0cc9ea0 --- /dev/null +++ b/bin/gsh/bufpool.asm @@ -0,0 +1,176 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* BUFPOOL +* By Tim Meekins +* +* This is the buffer pool +* +************************************************************************** + + keep o/bufpool + mcopy m/bufpool.mac + +************************************************************************** +* +* get a buffer of size 256 +* +************************************************************************** + +alloc256 START + + using bufpool + + lock pool256mutex + + lda pool256 + ora pool256+2 + beq allocbuf + + phd + ph4 pool256 + tsc + tcd + lda [1] + sta pool256 + ldy #2 + lda [1],y + sta pool256+2 + unlock pool256mutex + pla + plx + pld + rtl + +allocbuf unlock pool256mutex + ph4 #256 + jsl ~NEW + rtl + + END + +************************************************************************** +* +* free a buffer of size 256 +* +************************************************************************** + +free256 START + + using bufpool + + phd + phx + pha + tsc + tcd + lock pool256mutex + lda pool256 + sta [1] + ldy #2 + lda pool256+2 + sta [1],y + lda 1 + sta pool256 + lda 3 + sta pool256+2 + unlock pool256mutex + pla + plx + pld + rtl + + END + +************************************************************************** +* +* get a buffer of size 1024 +* +************************************************************************** + +alloc1024 START + + using bufpool + + lock pool1024mutex + + lda pool1024 + ora pool1024+2 + beq allocbuf + + phd + ph4 pool1024 + tsc + tcd + lda [1] + sta pool1024 + ldy #2 + lda [1],y + sta pool1024+2 + unlock pool1024mutex + pla + plx + pld + rtl + +allocbuf unlock pool1024mutex + ph4 #1024 + jsl ~NEW + rtl + + END + +************************************************************************** +* +* free a buffer of size 1024 +* +************************************************************************** + +free1024 START + + using bufpool + + phd + phx + pha + tsc + tcd + lock pool1024mutex + lda pool1024 + sta [1] + ldy #2 + lda pool1024+2 + sta [1],y + lda 1 + sta pool1024 + lda 3 + sta pool1024+2 + unlock pool1024mutex + pla + plx + pld + rtl + + END + +************************************************************************** +* +* buffer pool data +* +************************************************************************** + +bufpool DATA + +pool256 dc i4'0' +pool256mutex key +pool1024 dc i4'0' +pool1024mutex key + + END diff --git a/bin/gsh/builtin.asm b/bin/gsh/builtin.asm new file mode 100644 index 0000000..49f547e --- /dev/null +++ b/bin/gsh/builtin.asm @@ -0,0 +1,2061 @@ +************************************************************************ +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* BUILTIN.ASM +* By Tim Meekins +* +* Builtin command searching and execution. +* +************************************************************************** + + keep o/builtin + mcopy m/builtin.mac + +p_next gequ 0 ;next in global proclist +p_friends gequ p_next+4 ;next in job list +p_flags gequ p_friends+4 ;various job status flags +p_reason gequ p_flags+2 ;reason for entering this state +p_index gequ p_reason+2 ;job index +p_pid gequ p_index+2 ;process id +p_jobid gequ p_pid+2 ;process id of job leader +p_command gequ p_jobid+2 ;command (how job invoked) +p_space gequ p_command+4 ;space for structure + +************************************************************************** +* +* Find a builtin command +* +************************************************************************** + +builtin START + + using BuiltinData + +val equ 1 +file equ val+2 +tbl equ file+4 +space equ tbl+4 +argv equ space+3 +argc equ argv+4 +end equ argc+2 + +; subroutine (2:argc,4:argv),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + ldy #2 + lda [argv] + sta file + lda [argv],y + sta file+2 + ld4 builtintbl,tbl + ld2 -1,val + lda argc + jeq done + +loop ldy #2 + lda [tbl] + ora [tbl],y + beq done + lda [tbl],y + pha + lda [tbl] + pha + pei (file+2) + pei (file) + jsr cmpcstr + beq foundit + bpl done + add2 tbl,#10,tbl + bra loop + +foundit ldy #4 + lda [tbl],y + sta ourproc+1 + iny + lda [tbl],y + sta ourproc+2 + + pei (argv+2) + pei (argv) + pei (argc) +ourproc jsl >$FFFFFF ;might want to mutex this!!!!!! + sta val + + pei (argc) + pei (argv+2) + pei (argv) + jsl argfree + +done ldy val + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + tya + rtl + + END + +************************************************************************** +* +* Is it a built-in? +* +************************************************************************** + +IsBuiltin START + + using BuiltinData + +tbl equ 0 +space equ tbl+4 + + subroutine (4:name),space + + ld4 builtintbl,tbl +builtinloop ldy #2 + lda [tbl] + ora [tbl],y + beq nofile + lda [tbl],y + pha + lda [tbl] + pha + pei (name+2) + pei (name) + jsr cmpcstr + beq foundit + bpl nofile + add2 tbl,#10,tbl + bra builtinloop +foundit ldy #8 + lda [tbl],y + bra foundbuiltin + +nofile lda #-1 +foundbuiltin sta tbl + + return 2:tbl + + END + +************************************************************************** +* +* Builtin data +* +************************************************************************** + +BuiltinData DATA +; +; First address is a pointer to the name, the second is a pointer to the +; command. MUST BE SORTED. +; +builtintbl dc a4'aliasname,alias',i2'0' + dc a4'bgname,bg',i2'1' + dc a4'bindkeyname,bindkey',i2'0' + dc a4'cdname,cd',i2'1' + dc a4'chdirname,chdir',i2'1' + dc a4'clearname,clear',i2'0' + dc a4'cmdname,cmdbi',i2'0' + dc a4'dfname,df',i2'0' + dc a4'dirsname,dirs',i2'0' + dc a4'echoname,echo',i2'0' + dc a4'editname,edit',i2'1' + dc a4'exitname,exit',i2'1' + dc a4'exportname,export',i2'1' + dc a4'fgname,fg',i2'1' + dc a4'hashname,hashbi',i2'0' + dc a4'hname,PrintHistory',i2'0' + dc a4'jobsname,jobs',i2'1' + dc a4'killname,kill',i2'1' + dc a4'popdname,popd',i2'1' + dc a4'pfxname,prefix',i2'1' + dc a4'psname,psbi',i2'0' + dc a4'pushdname,pushd',i2'1' + dc a4'pwdname,pwd',i2'1' + dc a4'rehashname,rehash',i2'1' + dc a4'setname,set',i2'0' + dc a4'setbugname,setdebug',i2'0' + dc a4'setenvname,setenv',i2'0' + dc a4'sourcename,source',i2'0' + dc a4'stopname,stop',i2'1' + dc a4'tsetname,tset',i2'1' + dc a4'unaliasname,unalias',i2'1' + dc a4'unhashname,unhash',i2'1' + dc a4'unsetname,unset',i2'1' + dc a4'whichname,which',i2'0' + dc i4'0,0' + +aliasname dc c'alias',h'00' +bgname dc c'bg',h'00' +bindkeyname dc c'bindkey',h'00' +chdirname dc c'chdir',h'00' +cdname dc c'cd',h'00' +clearname dc c'clear',h'00' +cmdname dc c'commands',h'00' +dirsname dc c'dirs',h'00' +dfname dc c'df',h'00' +echoname dc c'echo',h'00' +editname dc c'edit',h'00' +exitname dc c'exit',h'00' +exportname dc c'export',h'00' +fgname dc c'fg',h'00' +hashname dc c'hash',h'00' +hname dc c'history',h'00' +jobsname dc c'jobs',h'00' +killname dc c'kill',h'00' +pfxname dc c'prefix',h'00' +popdname dc c'popd',h'00' +psname dc c'ps',h'00' +pushdname dc c'pushd',h'00' +pwdname dc c'pwd',h'00' +rehashname dc c'rehash',h'00' +setbugname dc c'setdebug',h'00' +setname dc c'set',h'00' +setenvname dc c'setenv',h'00' +sourcename dc c'source',h'00' +stopname dc c'stop',h'00' +tsetname dc c'tset',h'00' +unaliasname dc c'unalias',h'00' +unhashname dc c'unhash',h'00' +unsetname dc c'unset',h'00' +whichname dc c'which',h'00' + + END + +************************************************************************** +* +* CD: builtin command +* syntax: cd [pathname] +* +* Changes the current prefix to pathname. If no pathname then set to $HOME +* +************************************************************************** + +cd START +chdir ENTRY + +dir equ 1 +space equ dir+4 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + lock cdmutex + + lda argc + dec a + beq cdhome + dec a + jeq normalcd + +showusage lda [argv] + tax + ldy #2 + lda [argv],y + stx argv + sta argv+2 + lda [argv],y + and #$FF + beq cdusage + ldx #^Usage2 + lda #Usage2 + jsr errputs + jmp exit +cdusage ldx #^Usage + lda #Usage + jsr errputs + jmp exit +; +; set prefix to home +; +cdhome jsl alloc256 + sta dir + stx dir+2 + sta ReadName + stx ReadName+2 + ora ReadName+2 + bne madeit + lda #$201 + jmp ohshit +madeit Read_Variable ReadVar + lda [dir] + and #$FF + beq nohome + ph4 ReadName + jsr p2cstr + sta dir + stx dir+2 + ph4 @xa + lda ReadName + ldx ReadName+2 + jsl free256 + pl4 ReadName + bra setprefix + +nohome ldx dir+2 + lda dir + jsl free256 + jmp exit +; +; set prefix to specified path +; +normalcd stz ReadName + stz ReadName+2 + + ldy #4 + lda [argv],y + sta dir + iny2 + lda [argv],y + sta dir+2 + + lda [dir] + and #$FF + if2 @a,ne,#'-',setprefix + jmp showusage + +setprefix pei (dir+2) + pei (dir) + jsr c2gsstr + sta PRecPath + sta GRecPath + stx PRecPath+2 + stx GRecPath+2 + + GetFileInfo GRec + bcc ok +ohshit sta Err + Error Err + bra done + +ok if2 GRecFT,eq,#$F,ok2 + ldx dir+2 + lda dir + jsr errputs + ldx #^direrr + lda #direrr + jsr errputs + bra done + +ok2 SetPrefix PRec + bcs ohshit +done ph4 PRecPath + jsl nullfree + ora2 ReadName,ReadName+2,@a + beq whoaboy + ph4 ReadName + jsl nullfree +whoaboy anop + +exit unlock cdmutex + + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +cdmutex key + +PRec dc i'2' +PRecNum dc i'0' +PRecPath ds 4 + +GRec dc i'3' +GRecPath ds 4 +GRecAcc ds 2 +GRecFT ds 2 + +ReadVar dc a4'home' +ReadName ds 4 +home str 'home' + +Err ds 2 + +Usage dc c'Usage: cd [pathname]',h'0d00' +Usage2 dc c'Usage: chdir [pathname]',h'0d00' +dirErr dc c': Not a directory',h'0d00' + + END + +************************************************************************** +* +* CLEAR: builtin command +* syntax: clear +* +* clears the screen +* +************************************************************************** + +clear START + +space equ 1 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + phd + tcd + + lda argc + dec a + beq clearit + + ldx #^Usage + lda #Usage + jsr errputs + bra exit + +clearit jsr clearscrn + jsr flush + +exit lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +Usage dc c'Usage: clear',h'0d00' + + END + +************************************************************************** +* +* ECHO: builtin command +* syntax: echo [-n] [text][...] +* +* Echo displays to stdout what is on the command (except -n). +* +* If '-n' specified then don't print newline. +* +************************************************************************** + +echo START + +val equ 1 +nl equ val+2 +ptr equ nl+2 +space equ ptr+4 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + stz nl + if2 argc,lt,#2,loop + ldy #4 + lda [argv],y + sta ptr + iny2 + lda [argv],y + sta ptr+2 + ldy #1 + lda [ptr] + and #$FF + if2 @a,ne,#'-',loop + lda [ptr],y + and #$FF + if2 @a,ne,#'n',showusage + iny + lda [ptr],y + and #$FF + bne showusage + inc nl + add2 argv,#4,argv + dec argc + bra loop + +showusage ldx #^Usage + lda #Usage + jsr errputs + jmp exit + +loop add2 argv,#4,argv + dec argc + jeq done + ldy #2 + lda [argv],y + sta ptr+2 + lda [argv] + sta ptr +putloop lda [ptr] + and #$FF + cmp #0 + jeq doneput + cmp #'\' + jne putit + inc ptr + lda [ptr] + and #$FF + jeq doneput + if2 @a,ne,#'b',esc02 + ldx #1 + jsr moveleft + bra didit +esc02 if2 @a,ne,#'f',esc03 + jsr clearscrn + bra didit +esc03 if2 @a,ne,#'n',esc04 + lda #13 + bra putit +esc04 if2 @a,ne,#'r',esc05 + lda #13 + bra putit +esc05 if2 @a,ne,#'t',esc06 + lda #9 + bra putit +esc06 if2 @a,ne,#'0',putit + stz val + ldy #1 +escloop lda [ptr],y + and #$FF + beq putval + if2 @a,cc,#'0',putval + if2 @a,cs,#'9'+1,putval + sub2 @a,#'0',@a + pha + lda val + asl2 a + adc val + asl a + adc 1,s + sta val + pla + inc ptr + bra escloop +putval lda val +putit jsr putchar +didit inc ptr + jmp putloop +doneput lda #' ' + jsr putchar + jmp loop + +done lda nl + bne exit + jsr newline + +exit jsr flush + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +Usage dc c'Usage: echo [-n] [strings...]',h'0d00' + + END + +************************************************************************** +* +* PWD: builtin command +* syntax: pwd +* +* print the working directory. +* +************************************************************************** + +pwd START + +ptr equ 1 +space equ ptr+4 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + lda argc + dec a + beq wait + + ldx #^Usage + lda #Usage + jsr errputs + bra exit + +wait lock pwdmutex + + jsl alloc256 + sta gpptr + stx gpptr+2 + sta ptr + stx ptr+2 + + lda #256 + sta [ptr] + + GetPrefix gpparm + bcc ok + +awshit sta err + Error err + bra done + +ok ldy #2 + lda [ptr],y + xba + sta [ptr],y + + ldx ptr+2 + lda ptr + clc + adc #3 + jsr putp + jsr newline + +done ldx ptr+2 + lda ptr + jsl free256 + + unlock pwdmutex + +exit lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +pwdmutex key + +gpparm dc i'2' + dc i'0' +gpptr ds 4 + +err ds 2 + +Usage dc c'Usage: pwd',h'0d00' + + END + +************************************************************************** +* +* WHICH: builtin command +* syntax: which [command ...] +* +* displays the location of command +* +************************************************************************** + +which START + + using hashdata + +ptr equ 1 +file equ ptr+4 +space equ file+4 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd +; +; display usage if no arguments given +; + if2 argc,ge,#2,loop + ldx #^whicherr + lda #whicherr + jsr errputs + jmp exit +; +; loop through each argument +; +loop add2 argv,#4,argv + dec argc + jeq exit + + lda [argv] + sta file + ldy #2 + lda [argv],y + sta file+2 + +; +; see if it's an alias +; + pei (file+2) + pei (file) + jsl findalias + sta ptr + stx ptr+2 + ora ptr+2 + beq chkbuiltin + ldx #^aliasstr + lda #aliasstr + jsr puts + ldx ptr+2 + lda ptr + jsr puts + jmp nextarg +; +; was it a built-in? +; +chkbuiltin pei (file+2) + pei (file) + jsl IsBuiltin + cmp #-1 + beq tryhash +foundbuiltin ldx #^builtstr + lda #builtstr + jsr puts + jmp nextarg +; +; See if it was hashed +; +tryhash pei (file+2) + pei (file) + ph4 hash_table + ph4 #hash_paths + jsl search + cmp #0 + bne foundhash + cpx #0 + beq thispfx +; +; It was hashed, so say so. +; +foundhash jsr puts + jmp nextarg +; +; It must be in the current prefix, so check it out. +; +thispfx lock pwdmutex +; +; check for existence of file +; + pei (file+2) + pei (file) + jsr c2gsstr + sta GRecPath + stx GRecPath+2 + sta ptr + stx ptr+2 + + GetFileInfo GRec + bcs nofile +; +; we found the file, so display the cwd +; +showcwd pei (ptr+2) + pei (ptr) + jsl nullfree + jsl alloc256 + sta ptr + stx ptr+2 + sta gpptr + stx gpptr+2 + lda #256 + sta [ptr] + GetPrefix gpparm + ldy #2 + lda [ptr],y + xba + sta [ptr],y + + ldx ptr+2 + add2 ptr,#3,@a + jsr putp + ldx file+2 + lda file + jsr puts + ldx ptr+2 + lda ptr + jsl free256 + stz ptr + stz ptr+2 + bra donecwd +; +; No such command +; +nofile ldx #^cantdoit + lda #cantdoit + jsr puts +donecwd unlock pwdmutex + pei (ptr+2) + pei (ptr) + jsl nullfree +; +; Go try the next file. +; +nextarg jsr newline + jmp loop + +exit lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +whicherr dc c'Usage: which [file ...]',h'0d00' +builtstr dc c'Shell Built-in Command',h'00' +cantdoit dc c'Command Not Found',h'00' +aliasstr dc c'Aliased as ',h'00' + +pwdmutex key + +gpparm dc i'2' + dc i'0' +gpptr ds 4 + +GRec dc i'4' +GRecPath ds 4 + ds 2 +GRecFileType ds 2 +GRecAuxType ds 4 + + END + +************************************************************************** +* +* PREFIX: builtin command +* syntax: prefix [num [prefix]] +* +* sets prefix number num to prefix +* +************************************************************************** + +prefix START + +dir equ 1 +numstr equ dir+4 +space equ numstr+4 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + lock mutex + + lda argc + dec a + beq showall + dec a + jeq showone + dec a + jeq setprefix + + ldx #^usage + lda #usage + jsr errputs + jmp done + +showall jsl alloc256 + sta PRecPath + stx PRecPath+2 + sta dir + stx dir+2 + lda #254 + sta [dir] + + ld2 1,PRecNum + GetBootVol PRecNum + jcs awshit + ldx #^bootstr + lda #bootstr + jsr puts + ldy #2 + lda [dir],y + xba + sta [dir],y + ldx dir+2 + lda dir + inc2 a + inc a + jsr putp + jsr newline + + stz PRecNum +allloop GetPrefix PRec + jcs awshit + ldy #2 + lda [dir],y + beq nextall + xba + sta [dir],y + Int2Dec (PRecNum,#pfxstr,#2,#0) + ldx #^pfxstr + lda #pfxstr + jsr puts + ldx dir+2 + lda dir + inc2 a + inc a + jsr putp + jsr newline + +nextall inc PRecNum + if2 PRecNum,cc,#32,allloop + jmp finish + +showone ldy #6 + lda [argv],y + sta numstr+2 + pha + dey2 + lda [argv],y + sta numstr + pha + jsr cstrlen + tax + + Dec2Int (numstr,@x,#0),PRecNum + + jsl alloc256 + sta PRecPath + stx PRecPath+2 + sta dir + stx dir+2 + lda #254 + sta [dir] + GetPrefix PRec + bcs awshit + ldy #2 + lda [dir],y + xba + sta [dir],y + ldx dir+2 + lda dir + inc2 a + inc a + jsr putp + jsr newline + lda PRecPath + ldx PRecPath+2 + jsl free256 + + bra done + +setprefix ldy #6 + lda [argv],y + sta numstr+2 + pha + dey2 + lda [argv],y + sta numstr + pha + jsr cstrlen + tax + + Dec2Int (numstr,@x,#0),PRecNum + + ldy #2*4+2 + lda [argv],y + pha + dey2 + lda [argv],y + pha + jsr c2gsstr + sta PRecPath + sta GRecPath + stx PRecPath+2 + stx GRecPath+2 + + GetFileInfo GRec + bcc okay +awshit ldx #^errorstr + lda #errorstr + jsr errputs + bra finish + +okay SetPrefix PRec + bcs awshit + +finish ph4 PRecPath + jsl nullfree + +done unlock mutex + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +mutex key + +errorstr dc c'prefix: could not set prefix, pathname may not exist.' + dc h'0d00' +usage dc c'Usage: prefix prefixnum prefixname',h'0d00' +bootstr dc c' *: ',h'00' +pfxstr dc c'00: ',h'00' + +PRec dc i'2' +PRecNum dc i'0' +PRecPath ds 4 + +GRec dc i'2' +GRecPath ds 4 +GRecAcc ds 2 + + END + +************************************************************************** +* +* REHASH: builtin command +* syntax: rehash +* +* rehashes the path +* +************************************************************************** +* +* UNHASH: builtin command +* syntax: unhash +* +* turns off command hashing +* +************************************************************************** + +rehash START +unhash ENTRY + +space equ 1 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + + tsc + phd + tcd + + lda argc + dec a + beq doit + + ldx #^Usage + lda #Usage + jsr errputs + ldy #2 + lda [argv],y + tax + lda [argv] + jsr errputs + lda #13 + jsr errputchar + bra exit + +doit jsr dispose_hash ;remove old table + lda [argv] + tax + ldy #2 + lda [argv],y + sta argv+2 + stx argv + lda [argv] + and #$FF + jsr tolower + if2 @a,eq,#'u',exit ;if 'rehash' do the hashing. + jsl hashpath ;hash the path + +exit lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +Usage dc c'Usage: ',h'00' + + END + +************************************************************************** +* +* DF: builtin command +* syntax: df +* +* displays volumes and free space +* +************************************************************************** + +df START + + using FSTData + +space equ 1 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + + tsc + phd + tcd + + lock mutex + + lda argc + dec a + beq showall + + ldx #^Usage + lda #Usage + jsr errputs + bra exit + +showall ldx #^hdr + lda #hdr + jsr puts + ld2 1,DIDevNum +allloop DInfo DIParm + bcs exit + jsr showdev + inc DIDevNum + bra allloop + +exit unlock mutex + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +showdev lda #'.' + jsr putchar + lda #'d' + jsr putchar + lda DIdevnum + cmp #10 + bcs dev10 + clc + adc #'0' + jsr putchar + lda #' ' + jsr putchar + bra endnum +dev10 UDivide (DIdevnum,#10),(@a,@x) + phx + clc + adc #'0' + jsr putchar + pla + clc + adc #'0' + jsr putchar +endnum lda #' ' + jsr putchar + + Volume VolParm + jcc okdev + lda DIid + cmp #$20 + bcc okdid + lda #0 +okdid asl2 a + tay + ldx idtbl+2,y + lda idtbl,y + jsr puts + short a + ldy devname + lda #' ' +dev5 cpy #17 + bcs dev6 + sta devname+2,y + iny + bra dev5 +dev6 lda #16 + sta devname+1 + long a + ldx #^devname+1 + lda #devname+1 + jsr putp + lda #' ' + jsr putchar + + jmp newline + +okdev ldy volname + short a + lda #' ' +dev1 cpy #17 + bcs dev2 + sta volname+2,y + iny + bra dev1 +dev2 lda #16 + sta volname+1 + ldy devname + lda #' ' +dev3 cpy #17 + bcs dev4 + sta devname+2,y + iny + bra dev3 +dev4 lda #16 + sta devname+1 + long a + + ldx #^volname+1 + lda #volname+1 + jsr putp + lda #' ' + jsr putchar + ldx #^devname+1 + lda #devname+1 + jsr putp + lda #' ' + jsr putchar + Long2Dec (VolFree,#numbuf,#7,#0) + ldx #^numbuf + lda #numbuf + jsr puts + Long2Dec (VolTot,#numbuf,#7,#0) + ldx #^numbuf + lda #numbuf + jsr puts +; +; [(total - free) * 100] / total +; + lda VolFree + ora VolFree+2 + beq put100 + clc ;why clc, need to investigate :) + lda VolTot + sbc VolFree + tax + lda VolTot+2 + sbc VolFree+2 + LongMul (@ax,#100),(@ax,@y) + LongDivide (@xa,VolTot),(@ax,@y) + Long2Dec (@xa,#capbuf+3,#3,#0) + ldx #^capbuf + lda #capbuf + jsr puts + bra putsys + +put100 ldx #^cap100buf + lda #cap100buf + jsr puts + +putsys lda VolSysID + cmp #$E + bcc oksys + lda #0 +oksys asl2 a + tay + ldx FSTtable+2,y + lda FSTtable,y + jsr puts + jmp newline + +hdr dc c'.d## Volume Device Free Total Capacity System',h'0d' + dc c'---- ---------------- ---------------- ------- ------- -------- -----------',h'0d00' + +Usage dc c'Usage: df',h'0d00' +numbuf dc c' ',h'00' +capbuf dc c' % ',h'00' +cap100buf dc c' 100% ',h'00' + +mutex key + +DIParm dc i2'8' +DIDevNum ds 2 + dc a4'devbuf' + dc i2'0' + dc i4'0' + dc i2'0' + dc i2'0' + dc i2'0' +DIid dc i2'0' + +VolParm dc i2'5' + dc a4'devname' + dc a4'volbuf' +VolTot ds 4 +VolFree ds 4 +VolSysID ds 2 + +devbuf dc i'35' +devname ds 33 +volbuf dc i'260' +volname ds 258 + +idtbl dc a4'id00,id01,id02,id03,id04,id05,id06,id07,id08' + dc a4'id09,id0a,id0b,id0c,id0d,id0e,id0f,id10,idff' + dc a4'id12,id13,id14,id15,id16,id17,id18,id19,id1a' + dc a4'id1b,id1c,id1d,id1e,id1f' + dc a4'idff' + +idff dc c' ',h'00' +id00 dc c'Apple 5.25 Drive ',h'00' +id01 dc c'Profile 5MB ',h'00' +id02 dc c'Profile 10MB ',h'00' +id03 dc c'Apple 3.5 Drive ',h'00' +id04 dc c'SCSI ',h'00' +id05 dc c'SCSI Hard Drive ',h'00' +id06 dc c'SCSI Tape Drive ',h'00' +id07 dc c'SCSI CD-ROM ',h'00' +id08 dc c'SCSI Printer ',h'00' +id09 dc c'Serial Modem ',h'00' +id0a dc c'Console Driver ',h'00' +id0b dc c'Serial Printer ',h'00' +id0c dc c'Serial LaserWrit ',h'00' +id0d dc c'AppleTalk LaserW ',h'00' +id0e dc c'RAM Disk ',h'00' +id0f dc c'ROM Disk ',h'00' +id10 dc c'File Server ',h'00' +id12 dc c'Apple Desktop Bu ',h'00' +id13 dc c'Hard Drive ',h'00' +id14 dc c'Floppy Drive ',h'00' +id15 dc c'Tape Drive ',h'00' +id16 dc c'Character dev dr ',h'00' +id17 dc c'MFM-encoded ',h'00' +id18 dc c'AppleTalk net ',h'00' +id19 dc c'Sequential dev ',h'00' +id1a dc c'SCSI Scanner ',h'00' +id1b dc c'Scanner ',h'00' +id1c dc c'LaserWriter SC ',h'00' +id1d dc c'AppleTalk Main ',h'00' +id1e dc c'AppleTalk fsd ',h'00' +id1f dc c'AppleTalk RPM ',h'00' + + END + +************************************************************************** +* +* FST descriptions +* +************************************************************************** + +FSTData DATA + +FSTtable dc a4'fst0,fst1,fst2,fst3,fst4,fst5,fst6,fst7,fst8' + dc a4'fst0,fsta,fstb,fstc,fstd' + +fst0 dc c'[Unknown]',h'00' +fst1 dc c'ProDOS',h'00' +fst2 dc c'DOS 3.3',h'00' +fst3 dc c'DOS 3.2',h'00' +fst4 dc c'Pascal',h'00' +fst5 dc c'MFS',h'00' +fst6 dc c'HFS',h'00' +fst7 dc c'Lisa (get real)',h'00' +fst8 dc c'CP/M',h'00' +fsta dc c'MS-DOS',h'00' +fstb dc c'High Sierra',h'00' +fstc dc c'ISO 9660',h'00' +fstd dc c'AppleShare',h'00' + + END + +************************************************************************** +* +* EXIT: builtin command +* syntax: exit +* +* exit gsh +* +************************************************************************** + +exit START + + using global + +space equ 0 + + subroutine (4:argv,2:argc),space + + inc exitamundo + + return + + END + +************************************************************************** +* +* SETDEBUG: builtin command +* syntax: setdebug (val | [+|-]flag) +* +* sets debugging in kernel +* +************************************************************************** + +setdebug START + +arg equ 0 +newdebug equ arg+4 +mode equ newdebug+2 +space equ mode+2 + + subroutine (4:argv,2:argc),space + + lda argc + dec a + bne ok +showusage ldx #^usage + lda #usage + jsr errputs + jmp return + +ok stz mode + mv2 globaldebug,newdebug + dec argc + add2 argv,#4,argv +loop lda [argv] + sta arg + ldy #2 + lda [argv],y + sta arg+2 + lda [arg] + and #$FF + if2 @a,eq,#'-',turnoff + if2 @a,eq,#'+',turnon + ldx mode + bne showusage + ldx argc + dex + bne showusage + if2 @a,cc,#'0',showusage + if2 @a,cs,#'9'+1,showusage + pei (arg+2) + pei (arg) + jsr cstrlen + tax + Dec2Int (arg,@x,#0),@a + sta newdebug + jmp done + +turnoff jsr findflag + eor #$FFFF + and newdebug + bra turnnext +turnon jsr findflag + ora newdebug +turnnext sta newdebug + ld2 1,mode + add2 argv,#4,argv + dec argc + beq done + jmp loop + +done setdebug newdebug + mv2 newdebug,globaldebug +return return + +findflag inc arg + ldy #0 +findloop phy + lda nametbl,y + ora nametbl+2,y + beq nofind + lda nametbl+2,y + pha + lda nametbl,y + pha + pei (arg+2) + pei (arg) + jsr cmpcstr + beq foundit + pla + add2 @a,#4,@y + bra findloop + +foundit pla + lsr a + tax + lda bittbl,x + rts + +nofind pla + ldx arg+2 + lda arg + jsr errputs + ldx #^errstr + lda #errstr + jsr errputs + lda #-1 + pla ;rts address + jmp showusage + +usage dc c'Usage: setdebug (value | [+|-]flag ... )',h'0d0d' + dc c'Flags: gsostrace - Trace GS/OS calls',h'0d' + dc c' gsosblocks - Trace GS/OS parameter blocks',h'0d' + dc c' gsoserrors - Trace GS/OS errors',h'0d' + dc c' pathtrace - Trace GS/OS pathnames',h'0d' + dc c' sigtrace - Trace signals',h'0d' + dc c' systrace - Trace system calls',h'0d' + dc h'00' + +errstr dc c': Unknown flag',h'0d0d00' + +nametbl dc a4'str01,str02,str03,str04,str05,str06,0' +str01 dc c'gsostrace',h'00' +str02 dc c'pathtrace',h'00' +str03 dc c'gsoserrors',h'00' +str04 dc c'sigtrace',h'00' +str05 dc c'systrace',h'00' +str06 dc c'gsosblocks',h'00' + +bittbl dc i2'%000001' + dc i2'%000010' + dc i2'%000100' + dc i2'%001000' + dc i2'%010000' + dc i2'%100000' + +globaldebug dc i2'0' + + END + +************************************************************************** +* +* PS: builtin command +* syntax: ps +* +* display process status +* +************************************************************************** + +psbi START + + using pdata + +myuid equ 0 +t equ myuid+2 +ps2 equ t+4 +pr2 equ ps2+4 +pr equ pr2+4 +ps equ pr+4 +space equ ps+4 + + subroutine (4:argv,2:argc),space + + lda argc + dec a + beq ok +showusage ldx #^usage + lda #usage + jsr errputs + jmp return + +ok getuid + sta myuid + kvm_open + sta ps + stx ps+2 + ora2 @a,ps+2,@a + bne ok2 + ldx #^kvmerrstr + lda #kvmerrstr + jsr errputs + jmp done + +ok2 ldx #^header + lda #header + jsr puts + +loop kvmnextproc ps + sta pr + stx pr+2 + ora2 @a,pr+2,@a + jeq done + + ldy #94 ;ps->p_uid + lda [pr],y + cmp myuid + jne skip + + ldy #2 + lda [ps],y ;ps->pid + Int2Dec (@a,#pidstr,#4,#0) + ldx #^pidstr + lda #pidstr + jsr puts + + ldy #2 + lda [pr],y ;pr->processState + cmp #9 + bcc okstate + lda #9 +okstate asl a + asl a + asl a + tax + ldy #8 +putstate lda statetbl,x + phx + phy + jsr putchar + ply + plx + inx + dey + bne putstate + + ldy #6 + lda [pr],y ;pr->ttyID + beq ttnul + cmp #3 + bne ttnum + lda #'c' + jsr putchar + lda #'o' + bra showuser +ttnul lda #'n' + jsr putchar + lda #'u' + bra showuser +ttnum ldy #0 +ttnumlup cmp #10 + bcc ttnum0 + sec + sbc #10 + iny + bra ttnumlup +ttnum0 pha + tya + clc + adc #'0' + jsr putchar + pla + clc + adc #'0' +showuser jsr putchar + + ldy #4 + lda [pr],y ;pr->userID + Int2Hex (@a,#userstr+1,#4) + ldx #^userstr + lda #userstr + jsr puts + + ldy #94 + lda [pr],y ;pr->puid + Int2Hex (@a,#puidstr,#4) + ldx #^puidstr + lda #puidstr + jsr puts + + ldy #50 + lda [pr],y ;pr->ticks + tax + iny2 + lda [pr],y + LongDivide (@ax,#60),(@ax,@yy) + LongDivide (@xa,#60),(t,@ax) + Long2Dec (@xa,#timestr+4,#2,#0) + Long2Dec (t,#timestr,#3,#0) + lda timestr+4 + and #$FF + cmp #' ' + bne time0 + short a + lda #'0' + sta timestr+4 + long a +time0 ldx #^timestr + lda #timestr + jsr puts + + ldy #34 + lda [pr],y ;pr->args + tax + iny2 + lda [pr],y + jne goodcmd + cpx #0 + jne goodcmd + + lda pjoblist ;check for name in job list + ldx pjoblist+2 + +jobloop sta pr2 + stx pr2+2 + + ora pr2+2 + beq childof + ldy #p_pid + lda [pr2],y + ldy #2 + cmp [ps],y ;ps->pid + bne loop2 + + ldy #p_command+2 + lda [pr2],y + tax + ldy #p_command + lda [pr2],y + jsr puts + bra next + +loop2 ldy #p_next+2 + lda [pr2],y + tax + ldy #p_next + lda [pr2],y + bra jobloop + +childof ldx #^forkstr + lda #forkstr + jsr puts + kvm_open + sta ps2 + stx ps2+2 + lda [pr] + tay + kvmgetproc (ps2,@y) + sta pr2 + stx pr2+2 + kvm_close ps2 + ldy #34 + lda [pr2],y ;pr2->args + tax + iny2 + lda [pr2],y + bne goodcmd + cpx #0 + bne goodcmd + + ldx #^forkstr2 + lda #forkstr2 + jsr puts + bra next + +goodcmd tay + txa + tyx + clc + adc #8 + jsr puts + +next jsr newline +skip jmp loop + +done kvm_close ps + +return return + +usage dc c'Usage: ps',h'0d00' +kvmerrstr dc c'ps: error in kvm_open()',h'0d00' +header dc c' ID STATE TT MMID UID TIME COMMAND',h'0d00' +pidstr dc c'0000 ',h'00' +userstr dc c' 0000 ',h'00' +puidstr dc c'0000 ',h'00' +timestr dc c'000:00 ',h'00' +forkstr dc c'forked child of ',h'00' +forkstr2 dc c'an unknown process',h'00' + +test1 dc c'getuid = $' +test1a dc c'0000',h'0d00' + +statetbl dc c'defunct ' + dc c'running ' + dc c'ready ' + dc c'blocked ' + dc c'ready ' + dc c'suspend ' + dc c'waiting ' + dc c'waiting ' + dc c'paused ' + dc c'unknown ' + + END + +************************************************************************** +* +* HASH: builtin command +* syntax: hash +* +* display hashed commands +* +************************************************************************** + +hashbi START + + using hashdata + +sv equ 0 +q equ sv+4 +p equ q+4 +space equ p+4 + + subroutine (4:argv,2:argc),space + + ph2 t_size + jsl sv_alloc + sta sv + stx sv+2 + + lda hash_table + ora hash_table+2 + beq exit + mv4 hash_table,p + lda hash_numexe + beq doneadd + ldy #0 + ldx t_size + beq doneadd +; +; loop through every hashed file and add it the string vector +; +addloop lda [p],y + sta q + iny + iny + lda [p],y + sta q+2 + iny + iny + ora q + beq skip + phy + phx + pei (sv+2) + pei (sv) + pei (q+2) + lda q + inc a + inc a + pha + pea 1 + jsl sv_add + plx + ply +skip dex + bne addloop +doneadd anop + +doneprint pei (sv+2) + pei (sv) + jsl sv_sort + pei (sv+2) + pei (sv) + jsl sv_colprint + + pei (sv+2) + pei (sv) + jsl sv_dispose + +exit return + + END + +************************************************************************** +* +* SOURCE: builtin command +* syntax: source file [arguments...] +* +* executes a shell file w/o pushing environment +* +************************************************************************** + +source START + +retval equ 0 +space equ retval+2 + + subroutine (4:argv,2:argc),space + + stz retval + + dec argc + bne ok + + ldx #^usage + lda #usage + jsr errputs + lda #1 + sta retval + bra exit + +ok add2 argv,#4,argv + + ldy #2 + lda [argv],y + pha + lda [argv] + pha + pei (argc) + pei (argv+2) + pei (argv) + pea 0 + jsl ShellExec + sta retval + +exit return 2:retval + +usage dc c'usage: source file [arguments...]',h'0d00' + + END + +************************************************************************** +* +* COMMANDS: builtin command +* syntax: hash +* +* display builtin commands +* +************************************************************************** + +cmdbi START + + using BuiltinData + +sv equ 0 +space equ sv+4 + + subroutine (4:argv,2:argc),space + + ph2 #50 + jsl sv_alloc + + sta sv + stx sv+2 + + ldx #0 +; +; loop through every hashed file and add it the string vector +; +addloop lda builtintbl,x + ora builtintbl+2,x + beq doneadd + phx + pei (sv+2) + pei (sv) + lda builtintbl+2,x + pha + lda builtintbl,x + pha + pea 1 + jsl sv_add + pla + clc + adc #10 + tax + bra addloop +doneadd anop + +doneprint pei (sv+2) + pei (sv) + jsl sv_sort + pei (sv+2) + pei (sv) + jsl sv_colprint + + pei (sv+2) + pei (sv) + jsl sv_dispose + +exit return + + END diff --git a/bin/gsh/cmd.asm b/bin/gsh/cmd.asm new file mode 100644 index 0000000..85545e7 --- /dev/null +++ b/bin/gsh/cmd.asm @@ -0,0 +1,1166 @@ +*********************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* CMD.ASM +* By Tim Meekins +* +* Command line parsing routines. +* +************************************************************************** + + mcopy m/cmd.mac + keep o/cmd.mac + +SIGINT gequ 2 +SIGSTOP gequ 17 +; +; TOKENS used by the parser +; +T_WORD gequ 1 +T_BAR gequ 2 +T_AMP gequ 3 +T_SEMI gequ 4 +T_GT gequ 5 +T_GTGT gequ 6 +T_GTAMP gequ 7 +T_GTGTAMP gequ 8 +T_LT gequ 9 +T_NL gequ 10 +T_EOF gequ 11 +T_ERROR gequ 12 +T_NULL gequ 13 + +MAXARG gequ 256 +BADFD gequ -2 + +************************************************************************** +* +* Read a token from the buffer. +* +* Input: word points to a buffer to place a word is parsed. +* +* Ouput: the token is placed in the accumulator +* +************************************************************************** + +gettoken START + +buf equ 1 +state equ buf+4 +ch equ state+2 +space equ ch+2 +stream equ space+3 +word equ stream+4 +end equ word+4 + +; subroutine (4:word,4:stream),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd +; +; What state are we in +; +NEUTRAL equ 0 ;a neutral state, get anything +GTGT equ 1 ;looking for a second '>' +INQUOTE equ 2 ;parsing a quoted string +INWORD equ 3 ;parsing a word +SINGQUOTE equ 4 ;single quote string +; +; start in the neutral state +; + ld2 NEUTRAL,state + lda [stream] + sta buf + ldy #2 + lda [stream],y + sta buf+2 +; +; the main loop +; +loop lda [buf] + inc buf + and2 @a,#$FF,ch + bne switch + + if2 state,ne,#INWORD,loop2 + jmp endword + +loop2 if2 @a,ne,#GTGT,loop3 + dec buf + lda #T_GT + jmp done + +loop3 if2 @a,eq,#INQUOTE,error1 + if2 @a,eq,#SINGQUOTE,error2 + lda #T_EOF + jmp done + +error1 ldx #^errstr1 + lda #errstr1 + bra error0 +error2 ldx #^errstr2 + lda #errstr2 +error0 jsr errputs + lda #T_ERROR + jmp done +; +; jump to the current state +; +switch lda state + asl a + tax + jmp (statetbl,x) +statetbl dc a2'case_neutral' + dc a2'case_gtgt' + dc a2'case_inquote' + dc a2'case_inword' + dc a2'case_single' +; +; CASE NEUTRAL +; +case_neutral if2 ch,ne,#';',neut1 + lda #T_SEMI + jmp done +neut1 if2 @a,ne,#'&',neut2 + lda #T_AMP + jmp done +neut2 if2 @a,ne,#'|',neut3 + lda #T_BAR + jmp done +neut3 if2 @a,ne,#'<',neut4 + lda #T_LT + jmp done +neut5 cmp #' ' ;space + jeq loop + cmp #9 ;tab + jeq loop + if2 @a,ne,#'>',neut6 + lda #GTGT + bra neut10 +neut4 if2 @a,ne,#13,neut4a ;return + lda #T_NL + jmp done +neut4a if2 @a,ne,#0,neut4b ;EOF + lda #T_EOF + jmp done +neut4b if2 @a,ne,#'#',neut5 ;comment +neut4c lda [buf] + and #$7F + beq neut4d + inc buf + if2 @a,eq,#13,neut4d + if2 @a,eq,#10,neut4d + bra neut4c +neut4d jmp loop +neut6 if2 @a,ne,#'"',neut7 +startquote lda #INQUOTE + bra neut10 +neut7 if2 @a,ne,#"'",neut8 +startsingle lda #SINGQUOTE + bra neut10 +neut8 if2 @a,ne,#'\',neut9 + lda [buf] + and #$FF + inc buf + if2 @a,eq,#13,neut10a +neut9 sta [word] ;default + inc word + lda #INWORD +neut10 sta state +neut10a jmp loop +; +; CASE GTGT +; +case_gtgt if2 ch,eq,#'>',gtgt2 + if2 @a,eq,#'&',gtgt1 + dec buf + lda #T_GT + jmp done +gtgt1 lda #T_GTAMP + jmp done +gtgt2 lda [buf] + and #$FF + if2 @a,eq,#'&',gtgt3 + lda #T_GTGT + jmp done +gtgt3 inc buf + lda #T_GTGTAMP + jmp done +; +; CASE INQUOTE +; +case_inquote if2 ch,ne,#'\',quote2 ;is it a quoted character? + lda [buf] + inc buf +putword sta [word] + inc word + jmp loop +quote2 if2 @a,ne,#'"',putword + ld2 INWORD,state + jmp loop + +; +; CASE SINGLEQUOTE +; +case_single anop + if2 ch,ne,#"'",putword + ld2 INWORD,state + jmp loop +; +; CASE INWORD +; +case_inword if2 ch,eq,#000,endword + if2 @a,eq,#';',endword + if2 @a,eq,#'&',endword + if2 @a,eq,#'|',endword + if2 @a,eq,#'>',endword + if2 @a,eq,#'<',endword + if2 @a,eq,#' ',endword + if2 @a,eq,#009,endword + if2 @a,eq,#013,endword + cmp #'"' + jeq startquote + cmp #"'" + jeq startsingle + if2 @a,ne,#'\',putword + lda [buf] + inc buf + and #$FF + if2 @a,eq,#13,word2 + bra putword +word2 jmp loop +endword dec buf +finiword lda #0 + sta [word] + lda #T_WORD + +done tax + lda buf + sta [stream] + lda buf+2 + ldy #2 + sta [stream],y + + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + txa + rtl + +errstr1 dc c'gsh: Missing ending ".',h'0d00' +errstr2 dc c"gsh: Missing ending '.",h'0d00' + + END + +************************************************************************** +* +* Parse a single command +* +************************************************************************** + +command START + +pipefds equ 1 +errappend equ pipefds+2 +errfile equ errappend+2 +srcfile equ errfile+4 +dstfile equ srcfile+4 +count equ dstfile+4 +argv equ count+2 +word equ argv+4 +cmdline equ word+4 +pid equ cmdline+4 +append equ pid+2 +temp equ append+2 +argc equ temp+4 +token equ argc+2 +space equ token+2 +stream equ space+3 +pipesem equ stream+4 +inpipe2 equ pipesem+4 +jobflag equ inpipe2+2 +inpipe equ jobflag+2 +waitpid equ inpipe+2 +end equ waitpid+4 + +; subroutine (4:waitpid,2:inpipe,2:jobflag,2:inpipe2,4:pipesem,4:stream),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + ph4 #1024 + jsl ~NEW + sta cmdline + stx cmdline+2 + lda #0 + sta [cmdline] + + jsl alloc1024 + sta word + stx word+2 + + ph4 #MAXARG*4 + jsl ~NEW + sta argv + stx argv+2 + + stz srcfile + stz srcfile+2 + stz dstfile + stz dstfile+2 + stz errfile + stz errfile+2 + stz argc + stz pipefds + stz pipefds+2 + lda #-3 + sta [waitpid] + +loop pei (word+2) + pei (word) + pei (stream+2) + pei (stream) + jsl gettoken + sta token + asl a + tax + jmp (toktbl,x) +toktbl dc a2'loop' + dc a2'tok_word' + dc a2'tok_bar' + dc a2'tok_amp' + dc a2'tok_semi' + dc a2'tok_gt' + dc a2'tok_gtgt' + dc a2'tok_gtamp' + dc a2'tok_gtgtamp' + dc a2'tok_lt' + dc a2'tok_nl' + dc a2'tok_eof' + dc a2'tok_error' +; +; Parse a word token +; +tok_word if2 argc,ne,#MAXARG,word1 + lda #err00 ;Too many arguments + jmp error +word1 pei (word+2) + pei (word) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + sta temp + stx temp+2 + ora temp+2 + bne word2 + lda #err01 ;Out of memory for arguments + jmp error +word2 lda argc ;Copy word to argv[argc] + asl2 a + tay + lda temp + sta [argv],y + lda temp+2 + iny2 + sta [argv],y + pei (word+2) + pei (word) + pei (temp+2) + pei (temp) + jsr copycstr + + stz count ;count illegal characters in word + ldy #0 +illword lda [word],y + and #$FF + beq appword + if2 @a,eq,#' ',incword + if2 @a,eq,#'&',incword + if2 @a,eq,#'|',incword + if2 @a,eq,#'<',incword + if2 @a,eq,#'>',incword + if2 @a,eq,#';',incword + bra nextword +incword inc count +nextword iny + bra illword + +appword pei (word+2) ;append word to current command line + pei (word) + pei (cmdline+2) + pei (cmdline) + jsr cstrlen + tay + ldx argc + beq nospace + lda #' ' + sta [cmdline],y + iny +nospace lda count + beq noquote + lda [word] + and #$FF + cmp #'"' + bne doquote + stz count + bra noquote +doquote lda #'"' + sta [cmdline],y + iny + inc count +noquote pei (cmdline+2) + add2 @y,cmdline,@a + pha + jsr copycstr + lda count + beq noquote2 + pei (cmdline+2) + pei (cmdline) + jsr cstrlen + tay + lda #'"' + sta [cmdline],y + iny + lda #0 + sta [cmdline],y +noquote2 inc argc ;increment argument count +goloop jmp loop +; +; Parse a '<' token +; +tok_lt lda srcfile + ora srcfile+2 + beq lt1 + lda #err02 ;Extra < encountered + jmp error +lt1 lda inpipe + beq lt2 + lda #err09 ;< conflicts with | + jmp error +lt2 jsl alloc1024 + stx srcfile+2 + sta srcfile + phx + pha + pei (stream+2) + pei (stream) + jsl gettoken + if2 @a,eq,#T_WORD,goloop + lda #err03 ;Illegal < specified + jmp error +; +; Parse a '>' or '>>' +; +tok_gt anop +tok_gtgt lda dstfile + ora dstfile+2 + beq gt1 + lda #err04 ;Extra > or >> encountered + jmp error +gt1 jsl alloc1024 + stx dstfile+2 + sta dstfile + phx + pha + pei (stream+2) + pei (stream) + jsl gettoken + if2 @a,eq,#T_WORD,gt2 + lda #err05 ;Illegal > or >> specified + jmp error +gt2 stz append + if2 token,ne,#T_GTGT,gt3 + inc append +gt3 jmp loop +; +; Parse a '>&' or '>>&' +; +tok_gtamp anop +tok_gtgtamp lda errfile + ora errfile+2 + beq ga1 + lda #err06 ;Extra >& or >>& encountered + jmp error +ga1 jsl alloc1024 + stx errfile+2 + sta errfile + phx + pha + pei (stream+2) + pei (stream) + jsl gettoken + if2 @a,eq,#T_WORD,ga2 + lda #err07 ;Illegal >& or >>& specified + jmp error +ga2 stz errappend + if2 token,ne,#T_GTGTAMP,ga3 + inc errappend +ga3 jmp loop +; +; Parse a command terminator +; +tok_bar anop +tok_amp anop +tok_semi anop +tok_nl anop +tok_eof anop + + lda argc ;terminate the argv list + bne nonnull + lda #0 + sta [waitpid] + lda #T_NULL + jmp exit +nonnull asl2 a + tay + lda #0 + sta [argv],y + iny2 + sta [argv],y +; +; see if there is a conflict between >,>> with | +; + lda token + if2 @a,ne,#T_BAR,runit + lda dstfile + ora dstfile+2 + beq bar2 + lda #err08 ;> or >> conflicts with | + jmp error + +bar2 clc + tdc + adc #pipefds + ldx #0 + pipe @xa +;what if pipes return errors? + +runit pei (argc) + pei (argv+2) + pei (argv) + pei (srcfile+2) + pei (srcfile) + pei (dstfile+2) + pei (dstfile) + pei (errfile+2) + pei (errfile) + pei (append) + pei (errappend) + ldx #0 + if2 token,ne,#T_AMP,run2 + inx +run2 phx + pei (cmdline+2) + pei (cmdline) + pei (jobflag) + pei (inpipe) + pei (pipefds+2) + pei (inpipe2) + pei (pipefds) + pei (pipesem+2) + pei (pipesem) + jsl invoke + sta pid + cmp #-1 + beq exit + + if2 token,ne,#T_BAR,run3 + + pei (waitpid+2) + pei (waitpid) + pei (pipefds) + pei (jobflag) + pei (pipefds+2) + pei (pipesem+2) + pei (pipesem) + pei (stream+2) + pei (stream) + jsl command + bra exit + +run3 lda pid + sta [waitpid] + lda token + +; clean up + +exit pha + + lda dstfile + ora dstfile+2 + beq ex1 + ldx dstfile+2 + lda dstfile + jsl free1024 +ex1 anop + + lda srcfile + ora srcfile+2 + beq ex2 + ldx srcfile+2 + lda srcfile + jsl free1024 +ex2 anop + + lda errfile + ora errfile+2 + beq ex3 + ldx errfile+2 + lda errfile + jsl free1024 +ex3 anop + + ldx word+2 + lda word + jsl free1024 + + ply + + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + tya + rtl + +error ldx #^err00 + jsr errputs + +tok_error pei (cmdline+2) + pei (cmdline) + jsl nullfree + +exit1a pei (argc) + pei (argv+2) + pei (argv) + jsl argfree + lda #-1 + jmp exit + +err00 dc c'gsh: Too many arguments, so no dessert tonight.',h'0d00' +err01 dc c'gsh: Not enough memory for arguments.',h'0d00' +err02 dc c'gsh: Extra ''<'' encountered.',h'0d00' +err03 dc c'gsh: No file specified for ''<''.',h'0d00' +err04 dc c'gsh: Extra ''>'' or ''>>'' encountered.',h'0d00' +err05 dc c'gsh: No file specified for ''>'' or ''>>''.',h'0d00' +err06 dc c'gsh: Extra ''>&'' or ''>>&'' encountered.',h'0d00' +err07 dc c'gsh: No file specified for ''>&'' or ''>>&''.',h'0d00' +err08 dc c'gsh: ''|'' conflicts with ''>'' or ''>>''.',h'0d00' +err09 dc c'gsh: ''|'' conflicts with ''<''.',h'0d00' + + END + +************************************************************************** +* +* dispose the argv +* +************************************************************************** + +argfree START + +space equ 0 + + subroutine (2:argc,4:argv),space + +free1 lda argc + beq free2 + dec a + asl2 a + tay + lda [argv],y + tax + iny2 + lda [argv],y + pha + phx + jsl nullfree + dec argc + bra free1 +free2 pei (argv+2) + pei (argv) + jsl nullfree + return + + END + +************************************************************************** +* +* Interpret a shell script +* This is overly complicated so that it can be run concurrently. +* +************************************************************************** + +ShellExec START + + using vardata + using global + +count equ 1 +data equ count+2 +CRec equ data+4 +RRec equ CRec+4 +NRec equ RRec+4 +ORec equ NRec+4 +ptr equ ORec+4 +space equ ptr+4 +jobflag equ space+3 +argv equ jobflag+2 +argc equ argv+4 +path equ argc+2 +end equ path+4 + +; subroutine (4:path,2:argc,4:argv,2:jobflag),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + +wait ldy mutex + beq wait0 + cop $7F + bra wait +wait0 inc mutex +; +; set the variables 0..argc +; + lda argc + jeq skipvar + stz count +parmloop lda count + asl2 a + tay + lda [argv],y + sta setparm+4 + iny2 + lda [argv],y + sta setparm+6 + lda count + cmp #10 + bcs num1 + short a + adc #'0' + sta num+2 + long a + ld4 num+2,setparm + bra setit +num1 cmp #100 + bcs num2 + Int2Dec (@a,#num+1,#2,#0) + ld4 num+1,setparm + bra setit +num2 Int2Dec (@a,#num,#3,#0) + ld4 num,setparm +setit ph4 setparm + jsr c2pstr2 + phx + pha + stx setparm+2 + sta setparm + ph4 setparm+4 + jsr c2pstr2 + phx + pha + stx setparm+4+2 + sta setparm+4 + Set_Variable setparm + jsl nullfree + jsl nullfree + inc count + lda count + cmp argc + jcc parmloop + +skipvar dec mutex + + ph4 #4 ;Close parms + jsl ~NEW + sta CRec + stx CRec+2 + + ph4 #10 ;Open parms + jsl ~NEW + sta ORec + stx ORec+2 + + ph4 #12 ;NewLine parms + jsl ~NEW + sta NRec + stx NRec+2 + + ph4 #16 ;Read parms + jsl ~NEW + sta RRec + stx RRec+2 + + ph4 #1000 ;data buffer + jsl ~NEW + sta data + stx data+2 + + pei (path+2) ;Convert filename to GS/OS string + pei (path) + jsr c2gsstr + ldy #4 + sta [ORec],y + sta ptr + iny2 + txa + sta [ORec],y + sta ptr+2 + + ldy #8 + lda #1 ;Read access only + sta [ORec],y + + lda #3 ;Open the file + sta [ORec] + pei (ORec+2) + pei (ORec) + ph2 #$2010 ;OPEN + jsl $E100B0 + bcc ok + sta Err + Error Err + jmp done +awshit sta Err + Error Err + jmp almostdone + +ok ldy #2 ;Copy file ref num + lda [ORec],y + sta [NRec],y + sta [RRec],y + sta [CRec],y + + lda #4 ;Do NewLine + sta [NRec] + ldy #4 + lda #$7F + sta [NRec],y + iny2 + lda #1 + sta [NRec],y + iny2 + lda #NLTable + sta [NRec],y + iny2 + lda #^NLTable + sta [NRec],y + pei (NRec+2) + pei (NRec) + ph2 #$2011 ;NEWLINE + jsl $E100B0 + bcs awshit + + lda #4 ;Set up read parm + sta [RRec] + tay + lda data + sta [RRec],y + iny2 + lda data+2 + sta [RRec],y + iny2 + lda #1000 + sta [RRec],y + iny2 + lda #0 + sta [RRec],y + +ReadLoop anop + pei (RRec+2) + pei (RRec) + ph2 #$2012 ;READ + jsl $E100B0 + bcs almostdone + ldy #12 + lda [RRec],y + tay + lda #0 + sta [data],y + lda varecho + beq noecho + ldx data+2 + lda data + jsr puts + jsr newline +noecho lda [data] + and #$FF + if2 @a,eq,#'#',ReadLoop + pei (data+2) + pei (data) +* ph2 #0 +* ph2 #1 + pei (jobflag) + jsl execute + lda exitamundo + bne almostdone + bra ReadLoop + +almostdone anop + stz exitamundo + lda #1 + sta [CRec] + pei (CRec+2) + pei (CRec) + ph2 #$2014 ;CLOSE + jsl $E100B0 + +done pei (CRec+2) + pei (CRec) + jsl nullfree + pei (NRec+2) + pei (NRec) + jsl nullfree + pei (RRec+2) + pei (RRec) + jsl nullfree + pei (ORec+2) + pei (ORec) + jsl nullfree + pei (data+2) + pei (data) + jsl nullfree + pei (ptr+2) + pei (ptr) + jsl nullfree + +exit1a anop + + lda space+1 + sta end-2 + lda space + sta end-3 + pld + tsc + clc + adc #end-4 + tcs + rtl + +NLTable dc h'0d' + +Err ds 2 + +setparm ds 4 + ds 4 +num dc c'000',h'00' + +mutex dc i'0' + + END + +************************************************************************** +* +* Execute a command line by calling command for each command in the buffer +* +************************************************************************** + +execute START + +exebuf equ 1 +pipesem equ exebuf+4 +ptr2 equ pipesem+2 +waitstatus equ ptr2+4 +ptr equ waitstatus+2 +pid equ ptr+4 +term equ pid+2 +space equ term+2 +jobflag equ space+3 ;set if not a job +cmdline equ jobflag+2 +end equ cmdline+4 + +; subroutine (4:cmdline,2:jobflag),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + stz pipesem + stz waitstatus + + pei (cmdline+2) + pei (cmdline) + jsl expandvars + phx + pha + sta ptr + stx ptr+2 + jsl glob + phx + pha + sta ptr2 + stx ptr2+2 + jsl expandalias + phx + pha + sta exebuf + stx exebuf+2 + ldx ptr+2 + lda ptr + jsl free1024 + ldx ptr2+2 + lda ptr2 + jsl free1024 + + lda exebuf + ora exebuf+2 + bne loop + + pla + pla + stz term + lda #0 + jmp ouch + +loop pea 0 ;Bank 0 + tdc + clc + adc #pid + pha + pea 0 + pei (jobflag) + pea 0 + pea 0 ;Bank 0 + tdc + clc + adc #pipesem + pha + pea 0 ;Bank 0 + tdc + clc + adc #exebuf + pha + jsl command + sta term + bmi noerrexit + + lda pid + beq nowait + cmp #-1 + beq noerrexit + + lda jobflag + beq jobwait + + signal (#SIGINT,#0) + phx + pha + signal (#SIGSTOP,#0) + phx + pha + +otherwait ldx #0 + clc + tdc + adc #waitstatus + wait @xa + cmp pid + bne otherwait + lda waitstatus + and #$FF + cmp #$7F + beq otherwait + lda waitstatus + jsr setstatus + + pla + plx + signal (#SIGSTOP,@xa) + pla + plx + signal (#SIGINT,@xa) + + bra nowait + +jobwait jsl pwait + sta waitstatus + +nowait if2 term,eq,#T_EOF,noerrexit + lda [exebuf] + and #$FF + beq exit + jmp loop + +noerrexit stz waitstatus ;non-forked builtins cannot return an error +exit jsl nullfree + lda term ;make sure we return -1 if error + bmi ouch + + lda waitstatus + xba + and #$FF +ouch tay + lda space+1 + sta end-2 + lda space + sta end-3 + pld + tsc + clc + adc #end-4 + tcs + + tya + rtl + + END + +************************************************************************** +* +* System() call vector +* +************************************************************************** + +system START + +retval equ 0 +space equ retval+2 + + subroutine (4:str),space ;need the phk/plb + + pei (str+2) + pei (str) + ph2 #1 ;tells execute we're called by system + jsl execute + sta retval + + return 2:retval + + END diff --git a/bin/gsh/dir.asm b/bin/gsh/dir.asm new file mode 100644 index 0000000..56fe585 --- /dev/null +++ b/bin/gsh/dir.asm @@ -0,0 +1,697 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* DIR.ASM +* By Tim Meekins +* +* Directory stack management +* +************************************************************************** + + keep o/dir + mcopy m/dir.mac + +MAXD gequ 50 + +************************************************************************** +* +* Initialize directory stack +* +************************************************************************** + +InitDStack START + + using DirData + + stz tods + stz dirstack + stz dirstack+2 + + rts + + END + +************************************************************************** +* +* DIRS: builtin command +* syntax: dirs [-l] +* +* display the directory stack +* +************************************************************************** + +dirs START + + using DirData + +arg equ 0 +space equ arg+4 + + subroutine (4:argv,2:argc),space + + lda argc + dec a + beq showshort + dec a + bne using + ldy #4 + lda [argv],y + sta arg + ldy #6 + lda [argv],y + sta arg+2 + lda [arg] + and #$FF + cmp #'-' + bne using + ldy #1 + lda [arg],y + cmp #'l' + beq showlong + +using ldx #^usingstr + lda #usingstr + jsr errputs + bra exit + +showlong jsl dotods + pea 0 + jsl showdir + bra exit + +showshort jsl dotods + pea 1 + jsl showdir + +exit return + +usingstr dc c'usage: dirs [-l]',h'0d00' + + END + +************************************************************************** +* +* PUSHD: builtin command +* syntax: pushd [+n | dir] +* +* change directory and push +* +************************************************************************** + +pushd START + + using DirData + using vardata + +count equ 0 +p equ count+2 +arg equ p+4 +space equ arg+4 + + subroutine (4:argv,2:argc),space + + lda argc + dec a + beq xchange + dec a + bne usage + + ldy #4 + lda [argv],y + sta arg + ldy #6 + lda [argv],y + sta arg+2 + lda [arg] + and #$FF + cmp #'+' + beq rotate + jmp godir + +usage ldx #^usagestr + lda #usagestr + jsr errputs + jmp exit + +xchange lda tods + bne xgoodie + ldx #^err1 + lda #err1 + jsr errputs + jmp exit +xgoodie jsl dotods + lda tods + dec a + asl a + asl a + tax + lda tods + asl a + asl a + tay + lda dirstack,x + pha + lda dirstack,y + sta dirstack,x + pla + sta dirstack,y + lda dirstack+2,x + pha + lda dirstack+2,y + sta dirstack+2,x + pla + sta dirstack+2,y + jmp gototop + +rotate add4 arg,#1,p + pei (p+2) + pei (p) + jsr cstrlen + tax + Dec2Int (p,@x,#0),@a + sta count + cmp #0 + beq godir + lda tods + beq roterr + lda count + cmp tods + beq rotloop + bcc rotloop + +roterr ldx #^err2 + lda #err2 + jsr errputs + jmp exit + +rotloop lda tods + dec a + asl a + asl a + tay + lda dirstack+6,y + pha + lda dirstack+4,y + pha +rotloop2 lda dirstack,y + sta dirstack+4,y + lda dirstack+2,y + sta dirstack+6,y + cpy #0 + beq nextrot + dey + dey + dey + dey + bra rotloop2 +nextrot pla + sta dirstack + pla + sta dirstack+2 + dec count + bne rotloop + bra gototop + +godir jsl dotods + pei (arg+2) + pei (arg) + jsl gotodir + bne exit + + inc tods + lda tods + asl a + asl a + tay + lda #0 + sta dirstack,y + sta dirstack+2,y + jsl dotods + bra done + +gototop lda tods + asl a + asl a + tay + lda dirstack+2,y + pha + lda dirstack,y + pha + jsl gotodir + +done lda varpushdsil + bne exit + pea 1 + jsl showdir + +exit return + +usagestr dc c'usage: pushd [+n | dir]',h'0d00' +err1 dc c'pushd: No other directory',h'0d00' +err2 dc c'pushd: Directory stack not that deep',h'0d00' + + END + +************************************************************************** +* +* POPD: builtin command +* syntax: popd [+n] +* +* pop a directory from stack and cd to it +* +************************************************************************** + +popd START + + using DirData + using vardata + +count equ 0 +arg equ count+2 +space equ arg+4 + + subroutine (4:argv,2:argc),space + + lda argc + dec a + jeq noarg + dec a + bne using + ldy #4 + lda [argv],y + sta arg + ldy #6 + lda [argv],y + sta arg+2 + lda [arg] + and #$FF + cmp #'+' + beq plus + +using ldx #^usingstr + lda #usingstr + jsr errputs + jmp exit + +plus add4 arg,#1,arg + pei (arg+2) + pei (arg) + jsr cstrlen + tax + Dec2Int (arg,@x,#0),@a + sta count + cmp #0 + beq noarg + lda tods + beq pluserr + lda count + cmp tods + beq doplus + bcc doplus + +pluserr ldx #^err2 + lda #err2 + jsr errputs + bra exit + +doplus jsl dotods + sub2 tods,count,@a + asl a + asl a + tax + phx + lda dirstack+2,x + pha + lda dirstack,x + pha + jsl nullfree + plx +plusloop lda dirstack+4,x + sta dirstack,x + lda dirstack+6,x + sta dirstack+2,x + inx4 + dec count + bne plusloop + dec tods + + bra gototop + +noarg lda tods + bne noarg0 + + ldx #^err1 + lda #err1 + jsr errputs + bra exit + +noarg0 lda tods + asl a + asl a + tay + lda dirstack+2,y + pha + lda dirstack,y + pha + jsl nullfree + dec tods + +gototop lda tods + asl a + asl a + tay + lda dirstack+2,y + pha + lda dirstack,y + pha + jsl gotodir + + lda varpushdsil + bne exit + + pea 1 + jsl showdir + +exit return + +usingstr dc c'Usage: popd [+n]',h'0d00' +err1 dc c'popd: Directory stack empty',h'0d00' +err2 dc c'popd: Directory stack not that deep',h'0d00' + + END + +************************************************************************** +* +* Set prefix 0 to the passed c string +* +************************************************************************** + +gotodir PRIVATE + +retval equ 0 +space equ retval+2 + + subroutine (4:dir),space + + stz retval + + pei (dir+2) + pei (dir) + jsr c2gsstr + sta PRecPath + sta GRecPath + stx PRecPath+2 + stx GRecPath+2 + + lock mutex + + GetFileInfo GRec + bcc ok +ohshit sta Err + Error Err + inc retval + bra done + +ok if2 GRecFT,eq,#$F,ok2 + ldx dir+2 + lda dir + jsr errputs + ldx #^direrr + lda #direrr + jsr errputs + inc retval + bra done + +ok2 SetPrefix PRec + bcs ohshit + +done ph4 PRecPath + jsl nullfree + + unlock mutex + + return 2:retval + +mutex key + +PRec dc i'2' +PRecNum dc i'0' +PRecPath ds 4 + +GRec dc i'3' +GRecPath ds 4 +GRecAcc ds 2 +GRecFT ds 2 + +Err ds 2 +dirErr dc c': Not a directory',h'0d00' + + END + +************************************************************************** +* +* Display the directory stack +* +************************************************************************** + +showdir PRIVATE + + using DirData + +idx equ 0 +space equ idx+2 + + subroutine (2:flag),space + + lda tods + asl a + asl a + sta idx + +loop lda flag + beq long + ldy idx + lda dirstack+2,y + pha + lda dirstack,y + pha + jsl path2tilde + phx + pha + jsr puts + jsl nullfree + bra next +long ldy idx + lda dirstack+2,y + tax + lda dirstack,y + jsr puts +next lda #' ' + jsr putchar + lda idx + beq done + sub2 idx,#4,idx + bra loop + +done jsr newline + + return + + END + +************************************************************************** +* +* Set the top of the stack to the current directory +* +************************************************************************** + +dotods PRIVATE + + using DIRDATA + +p equ 0 +idx equ p+4 +space equ idx+2 + + subroutine (0:dummy),space + + lda tods + asl a + asl a + sta idx + tay + lda dirstack,y + ora dirstack+2,y + beq setit + + lda dirstack+2,y + pha + lda dirstack,y + pha + jsl nullfree + +setit lock mutex + jsl alloc256 + sta gppath + stx gppath+2 + sta p + stx P+2 + lda #254 + sta [p] + GetPrefix gpparm + ldy #2 + lda [p],y + xba + sta [p],y + add4 p,#3,p + pei (p+2) + pei (p) + jsr p2cstr + sta p + stx p+2 + ldx gppath+2 + lda gppath + jsl free256 + + unlock mutex + + ldy idx + lda p + sta dirstack,y + lda p+2 + sta dirstack+2,y + + return + +mutex key + +gpparm dc i2'2' + dc i2'0' +gppath dc i4'0' + + END + +************************************************************************** +* +* Directory stack data +* +************************************************************************** + +DirData DATA + +dirstack ds MAXD*4 +tods dc i'0' + + END + +************************************************************************** +* +* Replace $HOME with a '~' in string +* +************************************************************************** + +path2tilde START + +ptr equ 0 +newpath equ ptr+4 +home equ newpath+4 +space equ home+4 + + subroutine (4:path),space + + pei (path+2) + pei (path) + jsr cstrlen + inc2 a + pea 0 + pha + jsl ~NEW + sta newpath + stx newpath+2 + sta ptr + stx ptr+2 + + jsl alloc256 + sta home + stx home+2 + sta varparm+4 + stx varparm+6 + Read_Variable varparm + + ldy #0 + lda [home] + and #$FF + beq copyrest + tax +checkhome lda [path],y + and #$FF + beq notfound2 + jsr tolower + jsr toslash + pha + iny + lda [home],y + and #$FF + jsr tolower + jsr toslash + cmp 1,s + bne notfound + pla + dex + bne checkhome + cmp #'/' + beq found + lda [path],y + and #$FF + beq found + jsr toslash + cmp #'/' + bne notfound2 + +found lda #'~' + sta [ptr] + inc ptr + bra copyrest + +notfound pla +notfound2 ldy #0 +copyrest short a +copyloop lda [path],y + beq endcopy + cmp #':' + bne copyput + lda #'/' +copyput sta [ptr] + long a + inc ptr + short a + iny + bra copyloop +endcopy sta [ptr] + long a + dec ptr + lda [ptr] + cmp #'/' + bne skipshorten + lda #0 + sta [ptr] + +skipshorten ldx home+2 + lda home + jsl free256 + + return 4:newpath + +varparm dc i4'homename' + ds 4 + +homename str 'home' + + END diff --git a/bin/gsh/edit.asm b/bin/gsh/edit.asm new file mode 100644 index 0000000..6ca4786 --- /dev/null +++ b/bin/gsh/edit.asm @@ -0,0 +1,1955 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* EDIT.ASM +* By Tim Meekins +* +* The GNO/Shell command-line editor +* +************************************************************************** + + keep o/edit + mcopy m/edit.mac + +RAW gequ $20 +CRMOD gequ $10 +ECHO gequ $08 +CBREAK gequ $02 +TANDEM gequ $01 + +OAMAP gequ 0001 /* map OA-key to some sequence */ +OA2META gequ 0002 /* map OA-key to meta-key */ +OA2HIBIT gequ 0004 /* map OA-key to key|0x80 */ +VT100ARROW gequ 0008 /* map arrows to vt100 arrows */ + +TIOCGETP gequ $40067408 +TIOCSETP gequ $80067409 +TIOCGETK gequ $40027414 +TIOCSETK gequ $80027413 +TIOCGLTC gequ $40067474 +TIOCSLTC gequ $80067475 + +cmdbuflen gequ 1024 + +; editor key commands + +undefined_char gequ 0 ;<- DO NOT CHANGE THIS DEFINITION +raw_char gequ 1 ;<- DO NOT CHANGE THIS DEFINITION +map_char gequ 2 +backward_char gequ 3 +forward_char gequ 4 +up_history gequ 5 +down_history gequ 6 +beginning_of_line gequ 7 +end_of_line gequ 8 +complete_word gequ 9 +newline_char gequ 10 +clear_screen gequ 11 +redisplay gequ 12 +kill_whole_line gequ 13 +lead_in gequ 14 +backward_delete_char gequ 15 +backward_word gequ 16 +forward_word gequ 17 +list_choices gequ 18 +kill_end_of_line gequ 19 +toggle_cursor gequ 20 +delete_char gequ 21 + +************************************************************************** +* +* get a command line from the user +* +************************************************************************** + +GetCmdLine START + + using global + using HistoryData + using pdata + using keybinddata + using termdata + using vardata + + stz signalled + stz cmdlen + stz cmdloc + stz currenthist + stz currenthist+2 + + ioctl (#1,#TIOCGETP,#oldsgtty) + ioctl (#1,#TIOCGETP,#newsgtty) + lda #CBREAK+CRMOD + sta sg_flags + ioctl (#1,#TIOCSETP,#newsgtty) + + ioctl (#1,#TIOCGETK,#oldttyk) + ioctl (#1,#TIOCSETK,#newttyk) + + ioctl (#1,#TIOCGLTC,#oldltc) + ioctl (#1,#TIOCGLTC,#newltc) + short m + lda #-1 + sta newltc+1 + long m + ioctl (#1,#TIOCSLTC,#newltc) + +cmdloop lda #keybindtab + sta 0 + lda #^keybindtab + sta 2 +nextchar jsr cursoron + jsr flush + jsr getchar + sta 4 + ldx signalled + beq nextchar2 + jsr cmdsig +; bra cmdloop + +nextchar2 jsr cursoroff + lda 4 + cmp #-1 + beq eof + cmp #4 ;CTL-D + bne findcmd + +eof ldx cmdlen + bne findcmd + lda varignore + bne findcmd + jsr cursoron + ioctl (#1,#TIOCSETP,#oldsgtty) + ioctl (#1,#TIOCSETK,#oldttyk) + ioctl (#1,#TIOCSLTC,#oldltc) + sec + rts + +findcmd asl a + sta addidx+1 + asl a +addidx adc #0 + tay + lda [0],y ;get the type of key this is + asl a + tax + jsr (keytab,x) + jmp cmdloop + +keytab dc i'beep' ;undefined-char + dc i'cmdraw' ;raw-char + dc i'cmdloop' ;map-char + dc i'cmdleft' ;backward-char + dc i'cmdright' ;forward-char + dc i'PrevHistory' ;up-history + dc i'NextHistory' ;down-history + dc i'cmdbegin' ;beginning-of-line + dc i'cmdend' ;end-of-line + dc i'dotab' ;complete-word + dc i'cmdnewline' ;newline + dc i'cmdclearscrn' ;clear-screen + dc i'cmdredraw' ;redisplay + dc i'cmdclrline' ;kill-whole-line + dc i'cmdleadin' ;lead-in + dc i'cmdbackdel' ;backward-delete-char + dc i'cmdleftword' ;backward-word + dc i'cmdrightword' ;forward-word + dc i'cmdmatch' ;list-choices + dc i'cmdclreol' ;kill-end-of-line + dc i'cmdcursor' ;toggle-cursor + dc i'cmddelchar' ;delete-char + +;------------------------------------------------------------------------- +; +; it's multiple character command +; +;------------------------------------------------------------------------- + +cmdleadin pla ;kill return address + iny + iny + lda [0],y + tax + iny + iny + lda [0],y + sta 0+2 + stx 0 + jmp nextchar + +;------------------------------------------------------------------------- +; +; Insert or overwrite an alphanum character +; +;------------------------------------------------------------------------- + +cmdraw lda cmdlen + cmp #cmdbuflen + bcc cmIns0 + jmp beep + +cmIns0 lda insertflag + beq cmOver ;Do overstrike mode + short a + ldy cmdlen +cmIns1 cpy cmdloc + beq cmins2 + bcc cmIns2 + lda cmdline-1,y + sta cmdline,y + dey + bra cmIns1 +cmIns2 long a + inc cmdlen +; +; Place character in string and output +; +cmOver lda 4 + ldy cmdloc ;Do overstrike mode + short a + sta cmdline,y + long a + iny + sty cmdloc + jsr putchar + ldy cmdloc + cpy cmdlen + bcc cmdov2 + beq cmdov2 + sty cmdlen +; +; Redraw shifted text +; +cmdov2 lda insertflag + cmp #0 + bne cmdov2a + rts +cmdov2a ldx #0 +cmdov3 if2 @y,eq,cmdlen,cmdov4 + lda cmdline,y + iny + inx + phx + phy + jsr putchar + ply + plx + bra cmdov3 +cmdov4 jmp moveleft + +;------------------------------------------------------------------------- +; +; If the shell is interrupted during an edit +; +;------------------------------------------------------------------------- + +cmdsig stz signalled + jmp cmdredraw + +;------------------------------------------------------------------------- +; +; end of command...newline +; +;------------------------------------------------------------------------- + +cmdnewline pla ;pull off return address + sec + lda cmdlen + sbc cmdlen + tax + jsr moveright + ldx cmdlen ;strip trailing space + beq retdone +fix dex + lda cmdline,x + and #$FF + if2 @a,eq,#' ',fix +fix0 inx + stx cmdlen + stz cmdline,x ;terminate string + txy + beq retdone + ph4 #cmdline + jsl InsertHistory +retdone ioctl (#1,#TIOCSETP,#oldsgtty) + ioctl (#1,#TIOCSETK,#oldttyk) + ioctl (#1,#TIOCSLTC,#oldltc) + clc + rts + +;------------------------------------------------------------------------- +; +; moved character to the left +; +;------------------------------------------------------------------------- + +cmdleft lda cmdloc + bne ctl0a + jmp beep +ctl0a dec a + sta cmdloc + ldx #1 + jmp moveleft + +;------------------------------------------------------------------------- +; +; move character to the right +; +;------------------------------------------------------------------------- + +cmdright ldy cmdloc + if2 @y,ne,cmdlen,ctl1a + jmp beep +ctl1a lda cmdline,y + jsr putchar + inc cmdloc + rts + +;------------------------------------------------------------------------- +; +; show matching files +; +;------------------------------------------------------------------------- + +cmdmatch lda cmdlen + beq dontdomatch + jsr domatcher + jmp cmdredraw +dontdomatch rts + +;------------------------------------------------------------------------- +; +; Clear entire input line +; +;------------------------------------------------------------------------- + +cmdclrline ldx cmdloc + jsr moveleft + stz cmdloc ;fall through to cmdclreol + +;------------------------------------------------------------------------- +; +; Clear to end of line +; +;------------------------------------------------------------------------- + +cmdclreol lda cdcap + ora cdcap + beq ctl4a0 + tputs (cdcap,#1,#outc) + bra ctl4g + +ctl4a0 sub2 cmdlen,cmdloc,@a + inc a + tax + tay + phx +ctl4a phy + lda #' ' + jsr putchar + ply + dey + bne ctl4a + plx + jsr moveleft + +ctl4g lda cmdloc + sta cmdlen + rts + +;------------------------------------------------------------------------- +; +; redraw command-line +; +;------------------------------------------------------------------------- + +cmdredraw jsr newline +redraw2 jsl WritePrompt + ldx cmdlen + stz cmdline,x + ldx #^cmdline + lda #cmdline + jsr puts + sec + lda cmdlen + sbc cmdloc + tax + jmp moveleft + +;------------------------------------------------------------------------- +; +; clear screen +; +;------------------------------------------------------------------------- + +cmdclearscrn jsr clearscrn + bra redraw2 + +;------------------------------------------------------------------------- +; +; Insert toggle +; +;------------------------------------------------------------------------- + +cmdcursor eor2 insertflag,#1,insertflag + rts + +;------------------------------------------------------------------------- +; +; delete character to left +; +;------------------------------------------------------------------------- + +cmdbackdel lda cmdloc + bne ctldel2 + jmp beep +ctldel2 dec a + sta cmdloc + ldx #1 + jsr moveleft ;fall through to cmddelchar + +;------------------------------------------------------------------------- +; +; Delete character under cursor +; +;------------------------------------------------------------------------- + +cmddelchar ldy cmdloc + if2 @y,ne,cmdlen,cmdoa2a + rts +cmdoa2a short a +cmdoa2aa if2 @y,eq,cmdlen,cmdoa2b + lda cmdline+1,y + sta cmdline,y + iny + bra cmdoa2aa +cmdoa2b lda #' ' + sta cmdline-1,y + sta cmdline,y + long a + ldy cmdloc + ldx #0 +cmdoa2c if2 @y,eq,cmdlen,cmdoa2e + bcs cmdoa2d +cmdoa2e lda cmdline,y + iny + inx + phx + phy + jsr putchar + ply + plx + bra cmdoa2c + +cmdoa2d jsr moveleft + dec cmdlen + rts + +;------------------------------------------------------------------------- +; +; Jump to beginning of line +; +;------------------------------------------------------------------------- + +cmdbegin ldx cmdloc + stz cmdloc + jmp moveleft + +;------------------------------------------------------------------------- +; +; Jump to end of line +; +;------------------------------------------------------------------------- + +cmdend if2 cmdloc,eq,cmdlen,cmdoa4a + ldx #1 + jsr moveright + inc cmdloc + bra cmdend +cmdoa4a rts + +;------------------------------------------------------------------------- +; +; Left one word +; +;------------------------------------------------------------------------- + +cmdleftword lda cmdloc + bne cmdoa5a + jsr beep +cmdoa5z rts +cmdoa5a dec a + sta cmdloc +cmdoa5b ldx #1 + jsr moveleft + ldy cmdloc + beq cmdoa5z + lda cmdline,y + and #$FF + cmp #' ' + bne cmdoa5c + dec cmdloc + bra cmdoa5b +cmdoa5c ldy cmdloc + beq cmdoa5z + lda cmdline-1,y + and #$FF + cmp #' ' + beq cmdoa5z + dec cmdloc + ldx #1 + jsr moveleft + bra cmdoa5c + +;------------------------------------------------------------------------- +; +; Move one word to the right +; +;------------------------------------------------------------------------- + +cmdrightword if2 cmdloc,ne,cmdlen,cmdoa6a + jsr beep +cmdoa6z rts +cmdoa6a inc a + sta cmdloc +cmdoa6b ldx #1 + jsr moveright + ldy cmdloc + if2 @y,eq,cmdlen,cmdoa6z + lda cmdline,y + and #$FF + cmp #' ' + beq cmdoa6c + inc cmdloc + bra cmdoa6b +cmdoa6c ldy cmdloc + if2 @y,eq,cmdlen,cmdoa6z + lda cmdline,y + and #$FF + cmp #' ' + bne cmdoa6z + inc cmdloc + ldx #1 + jsr moveright + bra cmdoa6c + +oldsgtty dc i1'0' + dc i1'0' + dc i1'0' + dc i1'0' + dc i2'0' + +newsgtty dc i1'0' + dc i1'0' + dc i1'0' + dc i1'0' +sg_flags dc i2'0' + +oldttyk dc i2'0' +newttyk dc i2'OAMAP+OA2META+VT100ARROW' + +oldltc ds 6 +newltc ds 6 + + END + +;========================================================================= +; +; ^D file matcher +; +;========================================================================= + +domatcher START + + using global + + jsr wordmatch + + lda nummatch + bne m1 + jmp beep +; +; move to end of command-line +; +m1 sec + lda cmdlen + sbc cmdloc + tax + jsr moveright + jsr newline +; +; start displaying each match +; + lda #0 +m4 pha + asl a + asl a + tay + lda matchbuf,y + ldx matchbuf+2,y + jsr puts + lda #' ' + jsr putchar + pla + inc a + cmp nummatch + bne m4 + + jsr newline + jmp clearword + + END + +;========================================================================= +; +; command line expansion +; +;========================================================================= + +dotab START + + using global + +p equ 0 + + jsr wordmatch + lda nummatch + bne t1 +meepmeep jmp beep +; +; only one! trivial case! +; +t1 dec a + bne t2 +t1b mv4 matchbuf,p + ldy wordlen +t1a lda [p],y + and #$FF + jeq completed + sta oldchar + phy + jsr insertcmd + ply + iny + bra t1a +; +; one at a time +; +t2 jsr dofignore + lda nummatch + beq meepmeep + dec a + beq t1b + mv4 matchbuf,p + lda char + sta oldchar + ldy wordlen + lda [p],y + and #$FF + sta char2 + jsr tolower + sta char + lda #0 +t3 pha + asl a + asl a + tay + lda matchbuf,y + sta p + lda matchbuf+2,y + sta p+2 + ldy wordlen + lda [p],y + and #$FF + jsr tolower + cmp char + bne honk + pla + inc a + cmp nummatch + bne t3 + lda char2 + beq completed + jsr insertcmd + inc wordlen + bra t2 + +honk pla + jsr beep + bra donetab + +completed lda cmdloc + cmp cmdlen + bne donetab + lda oldchar + and #$FF + cmp #':' + beq donetab + cmp #'/' + beq donetab + lda #' ' + jsr insertcmd +donetab jmp clearword + +char ds 2 +char2 ds 2 +oldchar ds 2 + + END + +;========================================================================= +; +; remove any entries matching $fignore +; +;========================================================================= + +dofignore START + + using global + +var equ 0 +word equ var+4 +wordnum equ word+4 +wordlen equ wordnum+2 +varpos equ wordlen+2 +newpos equ varpos+2 +wordpos equ newpos+2 + + jsl alloc256 + sta varparms+4 + stx varparms+6 + phx + pha + Read_Variable varparms + jsr p2cstr + sta var + stx var+2 + phx + pha + jsr lowercstr + lda varparms+4 + ldx varparms+6 + jsl free256 + + lda [var] + and #$FF + jeq done + + lda #0 + sta wordnum +bigloop asl a + asl a + tax + lda matchbuf,x + sta word + tay + lda matchbuf+2,x + sta word+2 + pha + phy + jsr cstrlen + sta wordlen + stz newpos +figmatch lda newpos + sta varpos + ldy varpos +eatspace lda [var],y + and #$FF + beq bignext + cmp #' ' + bne yummy + iny + bra eatspace +yummy sty varpos + ldx #0 +eatstuff lda [var],y + and #$FF + beq gotstuff + cmp #' ' + beq gotstuff + inx + iny + bra eatstuff +gotstuff sty newpos + cpx wordlen + beq hgf + bcs figmatch +hgf phx + sec + lda wordlen + sbc 1,s + sta wordpos + plx +chk ldy wordpos + lda [word],y + and #$FF + beq deleteit + ldy varpos + jsr tolower + eor [var],y + and #$FF + bne figmatch + inc varpos + inc wordpos + bra chk + +deleteit lda wordnum + jsr removeword +bignext inc wordnum + lda wordnum + cmp nummatch + bcc bigloop + +done pei (var+2) + pei (var) + jsl nullfree + rts + +varparms dc a4'fignore' + ds 4 + +fignore str 'fignore' + + END + +;========================================================================= +; +; insert a character into the command-line +; +;========================================================================= + +insertcmd START + + using global + + sta tmp + + short a + ldy cmdlen +cmIns1 cpy cmdloc + beq cmins2 + bcc cmIns2 + lda cmdline-1,y + sta cmdline,y + dey + bra cmIns1 +cmIns2 long a + inc cmdlen +; +; Place character in string and output +; +cmOver lda tmp + ldy cmdloc ;Do overstrike mode + short a + sta cmdline,y + long a + iny + sty cmdloc + jsr putchar + ldy cmdloc + cpy cmdlen + bcc cmdov2 + beq cmdov2 + sty cmdlen +; +; Redraw shifted text +; +cmdov2 ldx #0 +cmdov3 if2 @y,eq,cmdlen,cmdov5 + lda cmdline,y + iny + inx + phx + phy + jsr putchar + ply + plx + bra cmdov3 +cmdov5 jmp moveleft + +tmp ds 2 + + END + +;========================================================================= +; +; remove an entry from the word matcher table +; +;========================================================================= + +removeword START + + using global + + pha + asl a + asl a + pha + tax + lda matchbuf+2,x + pha + lda matchbuf,x + pha + jsl nullfree + plx + ply +loop cpy nummatch + beq done + lda matchbuf+4,x + sta matchbuf,x + lda matchbuf+6,x + sta matchbuf+2,x + inx + inx + inx + inx + iny + bra loop + +done dec nummatch + rts + + END + +;========================================================================= +; +; clear the word matcher table +; +;========================================================================= + +clearword START + + using global + + lda #0 +loop pha + asl a + asl a + tay + lda matchbuf,y + ldx matchbuf+2,y + phx + pha + jsl nullfree + pla + inc a + cmp nummatch + bne loop + + stz nummatch + + rts + + END + +;========================================================================= +; +; word matcher for command-line expansion +; +;========================================================================= + +wordmatch START + + using global + using hashdata + using BuiltInData + + lda #'/' + sta sepstyle + + ldx #0 ;for left counter + ldy cmdloc + beq atstart + lda cmdline,y ;if current char is space then + and #$FF ;char to left must be non-space + cmp #' ' + bne findstart2 + lda cmdline-1,y + and #$FF + cmp #' ' + bne findstart + jmp beep +; +; move backwards to find start of word to expand +; +findstart inx + dey + beq atstart +findstart2 lda cmdline-1,y + and #$FF + cmp #';' + beq atstart + cmp #'|' + beq atstart + cmp #'&' + beq atstart + cmp #' ' + bne findstart +; +; isolate the word +; +atstart sty startpos + stx dir+1 + ldx #0 +isolate cpy cmdlen + beq gotiso + lda cmdline,y + and #$FF + cmp #' ' + beq gotiso + cmp #';' + beq gotiso + cmp #'|' + beq gotiso + cmp #'&' + beq gotiso + sta wordbuf,x + iny + inx + bra isolate +gotiso lda #0 + sta wordbuf,x + stx wordlen + sty cmdloc + txa + sec +dir sbc #0 + beq nomove + tax + jsr moveright +nomove anop +; +; start finding matches +; + stz nummatch +; +; see if it's a command or an argument, hopefully this is nice and +; accurate...it should serve its purpose well at least. +; + lda #1 + sta cmdflag ;first, assume it's a command + ldy startpos + beq gotflag + dey + beq gotflag + +flagskip lda cmdline,y + and #$FF + cmp #' ' + bne chkflag + dey + bpl flagskip + bra gotflag +chkflag cmp #';' + beq gotflag + cmp #'|' + beq gotflag + cmp #'&' + beq gotflag + stz cmdflag + +gotflag anop +; +; check if the first character is '$', if so, match for variables ONLY +; + lda wordbuf + and #$FF + cmp #'$' + jne filem + + ld2 1,varParm+8 +varloop Read_Indexed varParm + lda buffer + and #$FF + jeq vardone + dec a + cmp wordlen ;if shorter than word skip + jcc nextvar + ldx #1 +varscan lda wordbuf,x + and #$FF + beq goodvar + jsr tolower + eor buffer,x + and #$FF + jne nextvar + inx + bra varscan + +goodvar stz sepstyle + lda varval + and #$FF + tay + ldx #1 +gv00 dey + bmi gv02 + lda varval,x + and #$FF + cmp #':' + beq gv00b + cmp #'/' + bne gv00a +gv00b sta sepstyle +gv00a inx + bra gv00 + +gv02 lda varval ;check if it really is a directory + and #$FF + sta varval-1 + ld4 varval-1,GFName + GetFileInfo GFParm + lda GFType + cmp #$0F + beq gv02a + stz sepstyle + +gv02a lda nummatch + asl a + asl a + pha + lda buffer + and #$FF + inc a + inc a + inc a + pea 0 + pha + jsl ~NEW + sta 0 + stx 0+2 + ply + sta matchbuf,y + txa + sta matchbuf+2,y + inc nummatch + lda #'$' + sta [0] + lda buffer + and #$FF + tax + ldy #1 +gv01 lda buffer,y + sta [0],y + iny + dex + bne gv01 + lda sepstyle + sta [0],y + +nextvar inc varParm+8 + jmp varloop + +vardone rts +; +; next lets match by file names +; we'll start by moving our wordbuf to a pascal string +; +filem lda #1 + sta iwparm+4 + + short a + lda wordlen + inc a + sta wordpbuf + long a + ldy wordlen + lda #'*' + sta wordbuf,y + + ldx #0 + short a + dey +findsep lda wordbuf,y + cmp #':' + beq gotsep + cmp #'/' + beq gotsep + cmp #'[' + beq gotglob + cmp #'?' + beq gotglob + cmp #'=' + beq gotglob + cmp #'"' + beq gotglob + cmp #"'" + beq gotglob + cmp #'*' + bne nextsep + cpy #0 ;allow boot prefix */ + bne gotglob + lda wordbuf+1 + cmp sepstyle + bne gotglob + bra nextsep +gotglob long a + jmp beep + longa off +gotsep sta sepstyle + inx +nextsep dey + bpl findsep + long a + cpx #0 + beq initit + dec iwparm+4 + +initit Init_Wildcard iwparm + +filematch Next_Wildcard nwparm + lda buffer + and #$FF + jeq filemdone + cmp wordlen + beq filematch + lda nummatch + asl a + asl a + pha + ph4 #buffer + jsr p2cstr + ply + phx ;for c2gsstr + pha + sta matchbuf,y + txa + sta matchbuf+2,y + jsr c2gsstr + phx ;for nullfree + pha + sta GFName + stx GFName+2 + sta 4 + stx 6 + GetFileInfo GFParm + jsl nullfree + lda cmdflag + beq fm01 + lda GFType + cmp #$0F + beq isdir + cmp #$B5 + beq notdir + cmp #$B3 + beq notdir + cmp #$B0 + bne filematch + lda GFAux + cmp #6 + bne filematch + lda GFAux+2 + bne filematch + bra notdir +fm01 lda GFType + cmp #$0F + bne notdir +isdir lda nummatch + asl a + asl a + tax + phx + lda matchbuf,x + sta 0 + lda matchbuf+2,x + sta 2 + lda buffer + and #$FF + inc a + inc a + pea 0 + pha + jsl ~NEW + ply + sta 8 + stx 10 + pei (2) + pei (0) + phx + pha + sta matchbuf,y + txa + sta matchbuf+2,y + jsr copycstr + pei (2) + pei (0) + jsl nullfree + lda buffer + and #$FF + tay + lda sepstyle + sta [8],y + +notdir anop + inc nummatch + jmp filematch + +filemdone anop + lda cmdflag ;if it's not a command, we're done + jeq done +; +; let's now look at the hashed files +; +p equ 0 +q equ 4 + + ldy wordlen ;remove '*' from above + lda #0 + sta wordbuf,y + + lda hash_table + ora hash_table+2 + beq endhash + mv4 hash_table,p + lda hash_numexe + beq endhash + ldy #0 + ldx t_size + beq endhash +; +; loop through every hashed file and add it the string vector +; +hashloop lda [p],y + sta q + iny + iny + lda [p],y + sta q+2 + iny + iny + ora q + beq nexthash + inc q + inc q + phy + phx + pei (q+2) + pei (q) + jsr cstrlen + cmp wordlen + bcc nexthash0 + tax + ldy #0 +hl lda wordbuf,y + and #$FF + beq hl0 + jsr tolower + eor [q],y + and #$FF + bne nexthash0 + iny + bra hl +hl0 inx + lda nummatch + asl a + asl a + pha + pea 0 + phx + jsl ~NEW + ply + pei (q+2) + pei (q) + phx + pha + sta matchbuf,y + txa + sta matchbuf+2,y + inc nummatch + jsr copycstr +nexthash0 plx + ply +nexthash dex + bne hashloop + +endhash anop +; +; add built-ins to the list +; + ld4 builtintbl,p +bilup lda [p] + ldy #2 + ora [p],y + beq bidone + lda [p] + sta q + lda [p],y + sta q+2 + pei (q+2) + pei (q) + jsr cstrlen + cmp wordlen + bcc binext + tax + ldy #0 +bl lda wordbuf,y + and #$FF + beq bl0 + eor [q],y + and #$FF + bne binext + iny + bra bl +bl0 inx + lda nummatch + asl a + asl a + pha + pea 0 + phx + jsl ~NEW + ply + pei (q+2) + pei (q) + phx + pha + sta matchbuf,y + txa + sta matchbuf+2,y + inc nummatch + jsr copycstr +binext add2 p,#10,p + bra bilup +bidone anop + +done rts + +startpos ds 2 +cmdflag ds 2 + +iwparm dc i4'wordpbuf' + dc i2'1' + +nwparm dc i4'buffer' + +GFParm dc i2'4' +GFName dc i4'0' + dc i2'0' +GFType dc i2'0' +GFAux dc i4'0' + + +varParm dc i4'buffer' + dc i4'varval' + dc i2'0' + + ds 1 ;<- don't futz with me!! +varval ds 256 + +sepstyle ds 2 + + END + +************************************************************************** +* +* key bindings data +* +************************************************************************** + +keybinddata DATA + +keybindtab dc i2'undefined_char',i4'0' ;^@ + dc i2'beginning_of_line',i4'0' ;^A + dc i2'backward_char',i4'0' ;^B + dc i2'undefined_char',i4'0' ;^C + dc i2'list_choices',i4'0' ;^D + dc i2'end_of_line',i4'0' ;^E + dc i2'forward_char',i4'0' ;^F + dc i2'undefined_char',i4'0' ;^G + dc i2'backward_delete_char',i4'0' ;^H + dc i2'complete_word',i4'0' ;^I + dc i2'newline_char',i4'0' ;^J + dc i2'undefined_char',i4'0' ;^K + dc i2'clear_screen',i4'0' ;^L + dc i2'newline_char',i4'0' ;^M + dc i2'down_history',i4'0' ;^N + dc i2'undefined_char',i4'0' ;^O + dc i2'up_history',i4'0' ;^P + dc i2'undefined_char',i4'0' ;^Q + dc i2'redisplay',i4'0' ;^R + dc i2'undefined_char',i4'0' ;^S + dc i2'undefined_char',i4'0' ;^T + dc i2'kill_whole_line',i4'0' ;^U + dc i2'undefined_char',i4'0' ;^V + dc i2'undefined_char',i4'0' ;^W + dc i2'kill_whole_line',i4'0' ;^X + dc i2'kill_end_of_line',i4'0' ;^Y + dc i2'undefined_char',i4'0' ;^Z + dc i2'lead_in',i4'defescmap' ;^[ + dc i2'undefined_char',i4'0' ;^\ + dc i2'undefined_char',i4'0' ;^] + dc i2'undefined_char',i4'0' ;^^ + dc i2'undefined_char',i4'0' ;^_ + dc 95i2'raw_char,0,0' ;' ' .. '~' + dc i2'backward_delete_char',i4'0' ;^? (DEL) + +defescmap dc 4i2'undefined_char,0,0' ;^@ .. ^C + dc i2'list_choices',i4'0' ;^D + dc 3i2'undefined_char,0,0' ;^E .. ^G + dc i2'backward_word',i4'0' ;^H + dc i2'complete_word',i4'0' ;^I + dc 2i2'undefined_char,0,0' ;^J, ^K + dc i2'clear_screen',i4'0' ;^L + dc i2'undefined_char,0,0' ;^M + dc i2'undefined_char,0,0' ;^N + dc i2'undefined_char,0,0' ;^O + dc i2'undefined_char,0,0' ;^P + dc i2'undefined_char,0,0' ;^Q + dc i2'undefined_char,0,0' ;^R + dc i2'undefined_char,0,0' ;^S + dc i2'undefined_char,0,0' ;^T + dc i2'forward_word,0,0' ;^U + dc i2'undefined_char,0,0' ;^W + dc i2'undefined_char,0,0' ;^X + dc i2'undefined_char,0,0' ;^X + dc i2'undefined_char,0,0' ;^Y + dc i2'undefined_char,0,0' ;^Z + dc i2'complete_word',i4'0' ;^[ + dc 16i2'undefined_char,0,0' ;^\ .. + + dc i2'beginning_of_line',i4'0' ; , + dc i2'undefined_char,0,0' ; + dc i2'end_of_line',i4'0' ; . + dc 19i2'undefined_char,0,0' ; .+1 .. A + dc i2'backward_word',i4'0' ;B + dc 3i2'undefined_char,0,0' ;C ... E + dc i2'forward_word',i4'0' ;F + dc 8i2'undefined_char,0,0' ;G ... N + dc i2'lead_in',i4'vt100key' ;O + dc 18i2'undefined_char,0,0' ;P ... a + dc i2'backward_word',i4'0' ;b + dc 2i2'undefined_char,0,0' ;c ... d + dc i2'toggle_cursor',i4'0' ;e + dc i2'forward_word',i4'0' ;f + dc 25i2'undefined_char,0,0' ;g ... ^? + +vt100key dc 65i2'undefined_char,0,0' ;^@ ... @ + dc i2'up_history',i4'0' ;A + dc i2'down_history',i4'0' ;B + dc i2'forward_char',i4'0' ;C + dc i2'backward_char',i4'0' ;D + dc 59i2'undefined_char,0,0' ;E ... ^? + + END + +************************************************************************** +* +* bind a key to a function +* +************************************************************************** + +bindkeyfunc START + + using keybinddata + +p equ 0 +tbl equ p+4 +len equ tbl+4 +space equ len+2 + + subroutine (4:keystr,2:function),space + + lda keystr + ora keystr+2 + jeq done + + pei (keystr+2) + pei (keystr) + jsr cstrlen + sta len + ld4 keybindtab,tbl + +loop lda len + jeq done + dec a + beq putit ;last char in string + + lda [keystr] + and #$FF + asl a + sta addb+1 + asl a + clc +addb adc #0 + tay + lda [tbl],y + cmp #lead_in + beq next + phy + ph4 #128*6 + jsl ~NEW + sta p + stx p+2 + ldy #128*6-2 + lda #0 +zap sta [0],y + dey + dey + bpl zap + ply + lda #lead_in + sta [tbl],y + iny + iny + lda p + sta [tbl],y + iny + iny + lda p+2 + sta [tbl],y + mv4 p,tbl + dec len + add4 keystr,#1,keystr + bra loop + +next iny + iny + lda [tbl],y + tax + iny + iny + lda [tbl],y + sta tbl+2 + stx tbl + dec len + add4 keystr,#1,keystr + jmp loop + +putit lda [keystr] + and #$FF + asl a + sta adda+1 + asl a + clc +adda adc #0 + tay + lda function + sta [tbl],y + iny + iny + lda #0 + sta [tbl],y + iny + iny + sta [tbl],y + +done return + + END + +************************************************************************** +* +* BINDKEY: builtin command +* syntax: bindkey [-l] function string +* +* bind a keystring to an editor function. +* +************************************************************************** + +bindkey START + +str equ 0 +func equ str+4 +arg equ func+2 +space equ arg+4 + + subroutine (4:argv,2:argc),space + + lda argc + dec a + bne ok +showusage ldx #^usage + lda #usage + jsr errputs + jmp exit + +ok dec argc + add2 argv,#4,argv + lda [argv] + sta arg + ldy #2 + lda [argv],y + sta arg+2 + lda [arg] + and #$FF + cmp #'-' + bne startbind + ldy #1 + lda [arg],y + cmp #'l' + beq list + bra showusage + +list ldx #^liststr + lda #liststr + jsr puts + jmp exit + +startbind lda argc + dec a + jeq showusage + dec a + jne showusage + + ldy #0 +findloop phy + lda nametbl,y + ora nametbl+2,y + beq nofind + lda nametbl+2,y + pha + lda nametbl,y + pha + pei (arg+2) + pei (arg) + jsr cmpcstr + beq foundit + pla + add2 @a,#4,@y + bra findloop + +nofind pla + ldx arg+2 + lda arg + jsr errputs + ldx #^errstr + lda #errstr + jsr errputs + lda #-1 + jmp exit + +foundit pla + lsr a + tax + lda functbl,x + sta func + + add2 argv,#4,argv + lda [argv] + sta arg + ldy #2 + lda [argv],y + sta arg+2 + + pei (arg+2) + pei (arg) + jsr cstrlen + inc a + inc a + pea 0 + pha + jsl ~NEW + sta str + stx str+2 + pei (arg+2) + pei (arg) + phx + pha + jsl decode + + pei (str+2) + pei (str) + pei (func) + jsl bindkeyfunc + + pei (str+2) + pei (str) + jsl nullfree + +exit return + +usage dc c'Usage: bindkey [-l] function string',h'0d00' +errstr dc c': undefined function',h'0d00' + +liststr dc c' backward-char - move cursor left',h'0d' + dc c' backward-delete-char - delete character to left',h'0d' + dc c' backward-word - move cursor left one word',h'0d' + dc c' beginning-of-line - move cursor to beginning of line',h'0d' + dc c' clear-screen - clear screen and redraw prompt',h'0d' + dc c' complete-word - perform filename completion',h'0d' + dc c' delete-char - delete character under cursor',h'0d' + dc c' down-history - replace command line with next history',h'0d' + dc c' end-of-line - move cursor to end of line',h'0d' + dc c' forward-char - move cursor to the right',h'0d' + dc c' forward-word - move cursor one word to the right',h'0d' + dc c' kill-end-of-line - delete line from cursor to end of line',h'0d' + dc c' kill-whole-line - delete the entire command line',h'0d' + dc c' list-choices - list file completion matches',h'0d' + dc c' newline - finished editing, accept command line',h'0d' + dc c' raw-char - character as-is',h'0d' + dc c' redisplay - redisplay the command line',h'0d' + dc c' toggle-cursor - toggle between insert and overwrite cursor',h'0d' + dc c' undefined-char - this key does nothing',h'0d' + dc c' up-history - replace command line with previous history',h'0d' + dc h'00' + +nametbl dc i4'func1,func2,func3,func4,func5,func6,func7,func8' + dc i4'func9,func10,func11,func12,func13,func14,func15' + dc i4'func16,func17,func18,func19,func20,0' + +func1 dc c'backward-char',h'00' +func2 dc c'backward-delete-char',h'00' +func3 dc c'backward-word',h'00' +func4 dc c'beginning-of-line',h'00' +func5 dc c'clear-screen',h'00' +func6 dc c'complete-word',h'00' +func7 dc c'delete-char',h'00' +func8 dc c'down-history',h'00' +func9 dc c'end-of-line',h'00' +func10 dc c'forward-char',h'00' +func11 dc c'forward-word',h'00' +func12 dc c'kill-end-of-line',h'00' +func13 dc c'kill-whole-line',h'00' +func14 dc c'list-choices',h'00' +func15 dc c'newline',h'00' +func16 dc c'raw-char',h'00' +func17 dc c'redisplay',h'00' +func18 dc c'toggle-cursor',h'00' +func19 dc c'undefined-char',h'00' +func20 dc c'up-history',h'00' + +functbl dc i'backward_char' + dc i'backward_delete_char' + dc i'backward_word' + dc i'beginning_of_line' + dc i'clear_screen' + dc i'complete_word' + dc i'delete_char' + dc i'down_history' + dc i'end_of_line' + dc i'forward_char' + dc i'forward_word' + dc i'kill_end_of_line' + dc i'kill_whole_line' + dc i'list_choices' + dc i'newline_char' + dc i'raw_char' + dc i'redisplay' + dc i'toggle_cursor' + dc i'undefined_char' + dc i'up_history' + + END + +************************************************************************** +* +* decode does the grung work to decode the +* string escapes. +* +************************************************************************** + +decode START + +ch equ 1 +space equ ch+2 +cp equ space+3 +str equ cp+4 +end equ str+4 + +; subroutine (4:str,4:cp),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + ldy #0 + +loop lda [str],y + and #$FF + jeq breakloop + iny + + cmp #'^' + bne caseslash + + lda [str],y + and #$1F + iny + bra casebreak0 + +caseslash cmp #'\' + bne casebreak0 + + lda [str],y + and #$FF + sta ch + iny + + ldx #0 +nextc lda dp1,x + and #$FF + beq nextslash + cmp ch + beq gotslash + inx + bra nextc +gotslash lda dp2,x + and #$FF + bra casebreak0 + +nextslash lda ch + cmp #'0' + bcc casebreak0 + cmp #'9'+1 + bcs casebreak0 + + sec + sbc #'0' + sta ch + + ldx #2 + +numloop asl ch + asl ch + asl ch + lda [str],y + and #$FF + sec + sbc #'0' + clc + adc ch + sta ch + iny + dex + beq casebreak0 + lda [str],y + and #$FF + cmp #'0' + bcc casebreak + cmp #'9'+1 + bcc numloop + +casebreak lda ch +casebreak0 sta [cp] + inc cp + jne loop + inc cp+2 + jmp loop + +breakloop lda #0 + sta [cp] + + lda space+1 + sta end-2 + lda space + sta end-3 + pld + tsc + clc + adc #end-4 + tcs + + rtl + +dp1 dc c'E^\:nrtbf',h'00' +dp2 dc h'1b',c'^\:',h'0a0d09080c' + + END diff --git a/bin/gsh/expand.asm b/bin/gsh/expand.asm new file mode 100644 index 0000000..9f563b4 --- /dev/null +++ b/bin/gsh/expand.asm @@ -0,0 +1,580 @@ +*********************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* EXPAND.ASM +* By Tim Meekins +* +* Command line expansion routines. +* +************************************************************************** + + mcopy m/expand.mac + keep o/expand.mac + +************************************************************************** +* +* glob the command line +* +************************************************************************** + +glob START + + using vardata + +count equ 0 +gname equ count+2 +sepptr equ gname+4 +eptr equ sepptr+4 +exppath equ eptr+4 +filesep equ exppath+4 +shallweglob equ filesep+2 +wordbuf equ shallweglob+2 +ptr equ wordbuf+4 +buf equ ptr+4 +space equ buf+4 + + subroutine (4:cmd),space +; +; Check for noglob variable and exit if it's set to something. +; + lda varnoglob + beq doglob + jsl alloc1024 ;create a tmp output buffer buffer + sta buf + stx buf+2 + pei (cmd+2) + pei (cmd) + pei (buf+2) + pei (buf) + jsr copycstr + jmp bye +; +; noglob isn't set, so now we can actually start. +; +doglob jsl alloc1024 ;create an output buffer buffer + sta buf + sta ptr + stx buf+2 + stx ptr+2 + jsl alloc1024 ;create a word buffer + sta wordbuf + stx wordbuf+2 +; +; strip some white space +; +skipit jsr getbyte + jeq alldone + if2 @a,eq,#' ',whitestuff + if2 @a,eq,#009,whitestuff + if2 @a,eq,#013,whitestuff + if2 @a,eq,#010,whitestuff + if2 @a,eq,#';',whitestuff + if2 @a,eq,#'&',whitestuff + if2 @a,eq,#'|',whitestuff + if2 @a,eq,#'>',whitestuff + if2 @a,eq,#'<',whitestuff + stz shallweglob + ldy #0 + bra grabbingword +whitestuff jsr putbyte + bra skipit +; +; single out the next word [y is initialized above] +; +grabword jsr getbyte +grabbingword if2 @a,eq,#"'",grabsingle + if2 @a,eq,#'"',grabdouble + if2 @a,eq,#'\',grabslash + if2 @a,eq,#' ',procword + if2 @a,eq,#009,procword + if2 @a,eq,#013,procword + if2 @a,eq,#010,procword + if2 @a,eq,#000,procword + if2 @a,eq,#';',procword + if2 @a,eq,#'&',procword + if2 @a,eq,#'|',procword + if2 @a,eq,#'>',procword + if2 @a,eq,#'<',procword + if2 @a,eq,#'[',grabglob + if2 @a,eq,#']',grabglob + if2 @a,eq,#'*',grabglob + if2 @a,eq,#'?',grabglob +grabnext sta [wordbuf],y + iny + bra grabword +grabglob ldx #1 + stx shallweglob + bra grabnext +grabslash sta [wordbuf],y + iny + jsr getbyte + beq procword + bra grabnext +grabsingle sta [wordbuf],y + iny + jsr getbyte + beq procword + if2 @a,eq,#"'",grabnext + bra grabsingle +grabdouble sta [wordbuf],y + iny + jsr getbyte + beq procword + if2 @a,eq,#'"',grabnext + bra grabdouble +; +; we've grabbed the next word, now process the word +; +procword dec cmd + lda #0 + sta [wordbuf],y +; +; Shall we glob? Shall we scream? What happened, to our postwar dream? +; + lda [wordbuf] + and #$FF + if2 @a,eq,#'-',skipdeglob ;This allows '-?' option. + lda shallweglob + bne globword +; +; we didn't glob this word, so flush the word buffer +; +skipdeglob ldy #0 +flushloop lda [wordbuf],y + and #$FF + beq doneflush + jsr putbyte + iny + bra flushloop +doneflush jmp skipit +; +; Hello, boys and goils, velcome to Tim's Magik Shoppe +; +; Ok, here's the plan: +; 1. We give _InitWildcard a PATHNAME. +; 2. _NextWildcard returns a FILENAME. +; 3. We need to expand to the command-line the full pathname. +; 4. Therefore, we must put aside the prefix, and cat each file returned +; from _NextWildcard to the saved prefix, but, we must still pass +; the entire path to _InitWildcard. +; 5. This solves our problem with quoting. Expand the quotes before +; passing along to _InitWildcard, BUT the saved prefix we saved to cat +; to will still have the quotes in it, so that the tokenizer can deal +; with it. Whew! +; +; Well, here goes nuthin'.... [Ya know, and I'm reading Levy's book +; 'Hackers' right now...] +; +; +; +; Expand out the quoted stuff, and keep an eye out for that ubiquitous last +; filename separator... then we can isolate him! +; +globword stz filesep + jsl alloc1024 + sta eptr + stx eptr+2 + sta exppath + stx exppath+2 + + inc eptr ;leave room for pascal length + mv4 eptr,sepptr + + ldy #0 +exploop lda [wordbuf],y + and #$FF + beq endexp + iny + if2 @a,eq,#'\',expslash + if2 @a,eq,#"'",expsingle + if2 @a,eq,#'"',expdouble + if2 @a,eq,#'/',expsep + if2 @a,eq,#':',expsep +expput sta [eptr] + inc eptr + bra exploop +expsep sty filesep + sta [eptr] + inc eptr + mv4 eptr,sepptr + bra exploop +expslash lda [wordbuf],y + iny + and #$FF + beq endexp + bra expput +expsingle lda [wordbuf],y + iny + and #$FF + beq endexp + if2 @a,eq,#"'",exploop + sta [eptr] + inc eptr + bra expsingle +expdouble lda [wordbuf],y + iny + and #$FF + beq endexp + if2 @a,eq,#'"',exploop + sta [eptr] + inc eptr + bra expdouble +; +; We really didn't mean to expand the filename, so, copy it back again.. +; +endexp ldy filesep +copyback lda [wordbuf],y + iny + and #$FF + sta [sepptr] + inc sepptr + cmp #0 + bne copyback +; +; save the length, heh, heh, 16-bit sub will do it! +; + sub2 sepptr,exppath,@a + dec2 a ;don't count length byte or \0! + short a + sta [exppath] + long a +; +; We now have enough to call _InitWildCard!!! +; [ let's mutex the rest so we don't have to fix _InitWC and _NextWC ;-) ] +; +wait2 lda mutex + beq wait2a + cop $7F + bra wait2 +wait2a inc mutex +; +; start 'em up +; + stz count + mv4 exppath,initWCparm + Init_Wildcard initWCparm +; +; hey, we better get some memory for these new files... +; + ph4 #65 + jsl ~NEW + sta gname + stx gname+2 + sta nWCparm + stx nWCparm+2 +; +; start the expansion dudes! +; +WCloop Next_Wildcard nWCparm + lda [gname] + and #$FF + beq nomore + inc count +; +; get that owiginal path outta here! +; + ldy #0 +outtahere if2 @y,eq,filesep,globout + lda [wordbuf],y + jsr putspecial + iny + bra outtahere +; +; now get that newly globbed file outta here +; +globout lda [gname] + and #$FF + tax + ldy #1 +globoutta lda [gname],y + jsr putspecial + iny + dex + bne globoutta +; +; well well well, one down, how many to go? +; + lda #' ' + jsr putbyte + bra WCloop +; +; no more left, whatta we gonna do now! +; +nomore anop +; +; no match +; + lda count + bne yesmore + ldx #^nomatch + lda #nomatch + jsr puts + lda #0 + sta [buf] +yesmore anop +; +; throw em away (we should probably alloc once, not each word... ) +; + pei (gname+2) + pei (gname) + jsl nullfree + ldx exppath+2 + lda exppath + jsl free1024 + dec mutex + lda count + beq alldone2 + jmp skipit +; +; Goodbye, cruel world, I'm leaving you today, Goodbye, goodbye. +; +alldone jsr putbyte +alldone2 ldx wordbuf+2 + lda wordbuf + jsl free1024 + +bye return 4:buf +; +; get a byte from the original command-line +; +getbyte lda [cmd] + inc cmd + and #$FF + rts +; +; put special characters. Same as putbyte, but if it is a special +; shell character then quote it. +; +putspecial and #$7F + if2 @a,eq,#' ',special + if2 @a,eq,#'.',special + if2 @a,eq,#013,special + if2 @a,eq,#009,special + if2 @a,eq,#';',special + if2 @a,eq,#'&',special + if2 @a,eq,#'<',special + if2 @a,eq,#'>',special + if2 @a,eq,#'|',special + bra putbyte +special pha + lda #'\' + jsr putbyte + pla +; +; store a byte into the new command-line +; +putbyte short a + sta [ptr] + long a + inc ptr + rts + +mutex dc i'0' + +InitWCParm ds 4 + dc i2'%00000001' +nWCparm ds 4 + +nomatch dc c'No match.',h'0d00' + + END + +************************************************************************** +* +* Expand variables not in single quotes +* +* * Add error checking if out buf gets too big (> 1024) +* * Get rid of fixed buffers +* +************************************************************************** + +expandvars START + +ptr equ 1 +;ptr equ 0 +buf equ ptr+4 +space equ buf+4 +cmd equ space+3 +end equ cmd+4 + +; subroutine (4:cmd),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + jsl alloc1024 + sta buf + sta ptr + stx buf+2 + stx ptr+2 + +loop jsr getbyte + jeq done + if2 @a,eq,#"'",quote + if2 @a,eq,#'$',expand + if2 @a,eq,#'~',tilde + if2 @a,eq,#'\',slasher + jsr putbyte + bra loop + +slasher jsr putbyte + jsr getbyte + jsr putbyte + bra loop + +quote jsr putbyte + jsr getbyte + jeq done + if2 @a,ne,#"'",quote + jsr putbyte + bra loop + +tilde anop +wait2 lda mutex + beq wait2a + cop $7F + bra wait2 +wait2a inc mutex + + short a + lda #'h' + sta name + lda #'o' + sta name+1 + lda #'m' + sta name+2 + lda #'e' + sta name+3 + long a + ldx #4 + jmp getval +; +; expand the variable since a '$' was encountered. +; +expand anop +wait1 lda mutex + beq wait1a + cop $7F + bra wait1 +wait1a inc mutex + + lda #0 + sta name + lda [cmd] + and #$FF + if2 @a,eq,#'{',braceexpand + if2 @a,eq,#'<',stdinexpand + ldx #0 +nameloop lda [cmd] + and #$FF + beq getval + if2 @a,cc,#'0',getval + if2 @a,cc,#'9'+1,inname + if2 @a,cc,#'A',getval + if2 @a,cc,#'Z'+1,inname + if2 @a,eq,#'_',inname + if2 @a,cc,#'a',getval + if2 @a,cc,#'z'+1,inname + bra getval +inname jsr getbyte + sta name,x + inx + bra nameloop +; +; expand in braces {} +; +braceexpand jsr getbyte + ldx #0 +braceloop lda [cmd] + and #$FF + beq getval + jsr getbyte + if2 @a,eq,#'}',getval + sta name,x + inx + bra braceloop +; +; get text from standard input +; +stdinexpand jsr getbyte + ReadLine (#value+1,#255,#13,#1),@a + bra storeval2 +; +; get a value for this variable +; +getval lda #0 + sta name,x + ph4 #name + jsr c2pstr2 + phx + pha + sta parm + stx parm+2 + Read_Variable parm + jsl nullfree +; +; store the variable value in the out buffer +; +storeval lda value +storeval2 and #$FF + beq expanded + tay + ldx #0 +putval lda value+1,x + jsr putbyte + inx + dey + bne putval + +expanded dec mutex + jmp loop + +done jsr putbyte + + ldx buf+2 + ldy buf + + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + tya + rtl + +getbyte lda [cmd] + inc cmd + and #$FF + rts + +putbyte short a + sta [ptr] + long a + inc ptr + rts + +mutex dc i'0' + +parm dc a4'name' + dc a4'value' + +name ds 256 +value ds 256 + + END diff --git a/bin/gsh/hash.asm b/bin/gsh/hash.asm new file mode 100644 index 0000000..f4e3ec6 --- /dev/null +++ b/bin/gsh/hash.asm @@ -0,0 +1,928 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* HASH.ASM +* By Tim Meekins & Greg Thompson +* +* Command hashing routines +* +************************************************************************** + + keep o/hash + mcopy m/hash.mac + +C1 gequ 11 +C2 gequ 13 +TAB_MULT gequ 4 +; +; Structure for filenames +; +fn_dirNum gequ 0 +fn_name gequ fn_dirNum+2 +fn_next gequ fn_name+32 +fn_size gequ fn_next+4 +; +; Structure for hash table +; +tn_dirNum gequ 0 +tn_name gequ tn_dirNum+2 +tn_size gequ tn_name+32 + +************************************************************************** +* +* Calculate hash value for a filename +* +************************************************************************** + +hash START + + using hashdata + +space equ 1 +num equ space+2 +name equ num+2 +end equ name+4 + + tsc + phd + tcd + + lda num + bne hasher + + stz h + ldy #0 +loop lda [name],y + and #$FF + beq hasher + sta addit+1 + lda h ;left shift 7 + xba + and #$FF00 + lsr a +addit adc #0 ;(cf=0) + phy + UDivide (@a,t_size),(@a,@a) + sta h + ply + iny + bra loop + +hasher lda num ;num*num + sta tmp + lda #0 + ldx #16 +mulloop asl a + asl tmp + bcc nomul + clc + adc num +nomul dex + bne mulloop + + pha ;Acc * C2 + asl a + asl a + sec + sbc 1,s + asl a + asl a + adc 1,s + sta 1,s + + lda num ;num*C1 + (Acc*C2) + h + asl a + adc num + asl a + asl a + adc 1,s + adc h + sec + sbc num + plx + UDivide (@a,t_size),(@a,@y) + + lda space + sta end-2 + pld + tsc + clc + adc #end-3 + tcs + + tya + rts + +h ds 2 +tmp ds 2 + + END + +************************************************************************** +* +* dohash +* +************************************************************************** + +dohash START + + using hashdata + +h equ 1 +temp equ h+2 +qh equ temp+4 +table equ qh+2 +space equ table+4 +files equ space+3 +end equ files+4 + +; subroutine (4:files),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + lda hash_numexe + bne mktsize + + stz table + stz table+2 + jmp done +; +; t_size = (TAB_MULT * numexe) - 1 +; [Shift since TAB_MULT is 4, change later if needed] +; +mktsize asl a + asl a + dec a + sta t_size +; +; table = (tablenode **)malloc(sizeof(tablenode *) * t_size); +; + inc a ;safety precaution + asl a + asl a + pea 0 + pha + jsl ~NEW + sta table + stx table+2 +; +; for (i=0; i < t_size; ++i) table[i] = NULL; +; + ldy #0 + ldx t_size + tya +clrtbl sta [table],y + iny + iny + sta [table],y + iny + iny + dex + bne clrtbl +; +; files = files->next +; +mainloop ldy #fn_next + lda [files],y + tax + ldy #fn_next+2 + lda [files],y + sta files+2 + stx files +; +; while (files != NULL) { +; + ora files + jeq done + stz qh +; +; while (table[h = hash(files->name, qh))]) { ++qh; ++colls; } +; +hashloop pei (files+2) + lda files + inc a + inc a + pha + pei (qh) + jsr hash + asl a + asl a + sta h + tay + lda [table],y + tax + iny + iny + ora [table],y + beq gotit + +; let's see if it's the same, skip if so... + +; pei (files+2) +; lda files +; inc a +; inc a +; pha +; lda [table],y +; pha +; phx +; jsr cmpcstr +; beq mainloop + + inc qh + bra hashloop +; +; table[h] = (tablenode *)malloc(sizeof(tablenode)) +; +gotit ph4 #tn_size + jsl ~NEW + sta temp + stx temp+2 + ldy h + sta [table],y + iny + iny + txa + sta [table],y +; +; table[h]->dirnum = files->dirNum +; + lda [files] + sta [temp] +; +; strcpy(table[h]->name, files->name); +; + pei (files+2) + lda files + inc a + inc a + pha + pei (temp+2) + lda temp + inc a + inc a + pha + jsr copycstr + jmp mainloop + +done anop +; return 4:table + + ldx table+2 + ldy table + + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + tya + rtl + + END + +************************************************************************** +* +* Search the hash table +* +************************************************************************** + +search START + +ptr equ 1 +full_path equ ptr+4 +qh equ full_path+4 +space equ qh+2 +paths equ space+3 +table equ paths+4 +file equ table+4 +end equ file+4 + +; subroutine (4:file,4:table,4:paths),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + stz qh + stz full_path + stz full_path+2 + + lda table + ora table+2 + jeq done + + pei (file+2) + pei (file) + jsr lowercstr +mainloop pei (file+2) + pei (file) + pei (qh) + jsr hash + asl a + asl a + tay + lda [table],y + sta ptr + tax + iny + iny + ora [table],y + jeq done + lda [table],y + sta ptr+2 + pei (file+2) + pei (file) + pha ;ptr+2 + inx ;ptr + #2 + inx + phx + jsr cmpcstr + beq found + inc qh + bra mainloop + +found lda [ptr] + asl a + asl a + ldx paths+2 + adc paths ;(cf=0) + stx ptr+2 + sta ptr + ldy #2 + lda [ptr],y + pha + lda [ptr] + pha + jsr cstrlen + pha + clc + adc #33 + pea 0 + pha + jsl ~NEW + sta full_path + stx full_path+2 + ldy #2 + lda [ptr],y + pha + lda [ptr] + pha + pei (full_path+2) + pei (full_path) + jsr copycstr + pla ;length of path + pei (file+2) + pei (file) + pei (full_path+2) + clc + adc full_path + pha + jsr copycstr + +done ldx full_path+2 + ldy full_path + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + tya + rtl + + END + +************************************************************************** +* +* Dispose the hash table +* +************************************************************************** + +dispose_table START + + using hashdata + +ptr equ 0 +count equ ptr+4 +space equ count+2 + + subroutine (4:table),space + + mv4 table,ptr + mv2 t_size,count +loop ldy #2 + lda [ptr],y + pha + lda [ptr] + pha + jsl nullfree + add2 ptr,#4,ptr + dec count + bne loop + + pei (table+2) + pei (table) + jsl nullfree + + return + + END + +************************************************************************** +* +* Dispose the file table +* +************************************************************************** + +free_files START + +space equ 0 + + subroutine (4:files),space + +loop ora2 files,files+2,@a + beq done + ldy #fn_next + lda [files],y + tax + ldy #fn_next+2 + lda [files],y + pei (files+2) + pei (files) + stx files + sta files+2 + jsl nullfree + bra loop + +done return + + END + +************************************************************************** +* +* Directory search +* +************************************************************************** + +dir_search START + + using hashdata + +temp2 equ 0 +temp equ temp2+4 +entry equ temp+4 +numEntries equ entry+2 +ptr equ numEntries+2 +space equ ptr+4 + + subroutine (4:dir,2:dirNum,4:files),space +; +; Open directory +; + ld2 3,ORec + pei (dir+2) ;copy this string + pei (dir) + jsr c2gsstr + sta ORecPath + stx ORecPath+2 + phx + pha + Open ORec + bcc goodopen + jsl nullfree + jmp exit + +goodopen jsl nullfree + mv2 ORecRef,DRecRef + stz DRecBase + stz DRecDisp + jsl alloc256 + sta DRecName + sta ptr + stx DRecName+2 + stx ptr+2 + lda #254 ;Output buffer size (GT never did this?) + sta [ptr] + GetDirEntry DRec + mv2 DRecEntry,numEntries + ld2 1,(DRecBase,DRecDisp) + stz entry + +loop lda entry + cmp numEntries + jge done + GetDirEntry DRec + if2 DRecFileType,eq,#$B3,goodfile + if2 @a,eq,#$B5,goodfile + cmp #$B0 + jne nextfile + lda DRecAuxType + cmp #$06 + jne nextfile + lda DRecAuxType+2 + jne nextfile +goodfile inc hash_numexe + ldy #2 + lda [ptr],y + add2 @a,#4,@y + lda #0 + sta [ptr],y + add2 ptr,#4,@a + pei (ptr+2) ;for copycstr + pha + pei (ptr+2) + pha + jsr lowercstr + + ldy #fn_next + lda [files],y + sta temp + ldy #fn_next+2 + lda [files],y + sta temp+2 + ph4 #fn_size + jsl ~NEW + sta temp2 + stx temp2+2 + ldy #fn_next + sta [files],y + ldy #fn_next+2 + txa + pha + sta [files],y + lda temp2 + clc + adc #fn_name + pha + jsr copycstr + lda dirNum + sta [temp2] + ldy #fn_next + lda temp + sta [temp2],y + ldy #fn_next+2 + lda temp+2 + sta [temp2],y + +nextfile inc entry + jmp loop + +done ldx DRecName+2 + lda DRecName + jsl free256 + ld2 1,ORec + Close ORec + +exit return + +ORec dc i'3' +ORecRef ds 2 +ORecPath ds 4 +ORecAccess dc i'1' ;read + +DRec dc i'13' +DRecRef ds 2 +DRecFlag ds 2 +DRecBase dc i'0' +DRecDisp dc i'0' +DRecName ds 4 +DRecEntry ds 2 +DRecFileType ds 2 +DRecEOF ds 4 +DRecBlockCnt ds 4 +DRecCreate ds 8 +DRecMod ds 8 +DRecAccess ds 2 +DRecAuxType ds 4 + + END + +************************************************************************** +* +* Hash the path variable +* +************************************************************************** + +hashpath START + + using hashdata + +len equ 1 +pathnum equ len+2 +ptr equ pathnum+2 +files equ ptr+4 +pathptr equ files+4 +space equ pathptr+4 +end equ space+3 + + tsc + sec + sbc #space-1 + tcs + phd + tcd +; +; allocate special file node +; + ph4 #fn_size + jsl ~NEW + sta hash_files + sta files + stx hash_files+2 + stx files+2 + + jsl alloc256 + sta EPParm+6 + stx EPParm+6+2 + sta ptr + stx ptr+2 + lda #254 + sta [ptr] +; +; initialize counters and pointers +; + lda #0 + sta hash_numexe + sta pathnum + ldy #fn_next + sta [files],y + ldy #fn_next+2 + sta [files],y + ldy #fn_name + sta [files],y + sta [files] +; +; allocate memory for $path variable +; + jsl alloc256 + sta pathparm+4 + stx pathparm+4+2 + phx + pha + phx + pha +; +; read $PATH +; + Read_Variable pathparm + + jsr p2cstr + stx pathptr+2 + sta pathptr + stx pathparm+6 ;for disposal only + sta pathparm+4 + pla + plx + jsl free256 ;pushed earlier +; +; begin parsing $path +; +loop lda [pathptr] + and #$FF + jeq done +; +; parse next pathname +; + mv4 pathptr,ptr + ldy #0 +despace lda [pathptr],y + and #$FF + beq gotspace0 + if2 @a,eq,#' ',gotspace1 + if2 @a,eq,#009,gotspace1 + if2 @a,eq,#013,gotspace1 + if2 @a,eq,#'\',gotquote + iny + bra despace +gotquote iny2 + bra despace +gotspace0 tyx + bra gotspace3 +gotspace1 tyx + short a + lda #0 + sta [pathptr],y + long a +gotspace2 iny + lda [pathptr],y + and #$FF + if2 @a,eq,#' ',gotspace2 + if2 @a,eq,#009,gotspace2 + if2 @a,eq,#013,gotspace2 +gotspace3 anop + clc + tya + adc pathptr + sta pathptr + + lda pathnum + cmp #32*4 + bcc numok + ldx #^toomanyerr + lda #toomanyerr + jsr errputs + jmp done + +numok pei (ptr+2) + pei (ptr) + jsr c2gsstr + phx + pha + sta EPParm+2 + stx EPParm+4 + ExpandPath EPParm + bcc epok + + ldx #^eperrstr + lda #eperrstr + jsr errputs + jsl nullfree + jmp next + +epok jsl nullfree + + lda EPParm+6+2 + sta ptr+2 + lda EPParm+6 + inc2 a + sta ptr + lda [ptr] + sta len + inc2 a + tay + lda #0 + sta [ptr],y + pea 0 + phy + jsl ~NEW + phx ;for dir_search + pha + pei (ptr+2) + inc2 ptr + pei (ptr) + phx + pha + sta ptr + stx ptr+2 + ldy pathnum + sta hash_paths,y + txa + sta hash_paths+2,y + jsr copycstr + ldy len + beq go4it + dey + lda [ptr],y + and #$FF + cmp #':' + beq go4it + iny + lda #':' + sta [ptr],y + iny + lda #0 + sta [ptr],y + +go4it lda pathnum + lsr2 a + pha + pei (files+2) + pei (files) + jsl dir_search + add2 pathnum,#4,pathnum + +next jmp loop + +done ph4 pathparm+4 + jsl nullfree + + lda hash_print + beq noprint + + Int2Dec (hash_numexe,#hashnum,#3,#0) + ldx #^hashmsg + lda #hashmsg + jsr puts + +noprint ld2 1,hash_print + + ph4 hash_files + jsl dohash + sta hash_table + stx hash_table+2 + + lda EPParm+6 + ldx EPParm+6+2 + jsl free256 + + pld + tsc + clc + adc #end-4 + tcs + + rtl + +pathparm dc a4'pathvar' + ds 4 +pathvar str 'path' + +hashmsg dc c'hashed ' +hashnum dc c'000 files',h'0d00' + +EPParm dc i'2' + ds 4 + ds 4 + +eperrstr dc c'rehash: Invalid pathname syntax.',h'0d00' +toomanyerr dc c'rehash: Too many paths specified.',h'0d00' + + END + +************************************************************************** +* +* Dispose of hashing tables +* +************************************************************************** + +dispose_hash START + + using hashdata + + ora2 hash_table,hash_table+2,@a + beq done + + ldx #32 + ldy #0 +loop1 phx + phy + lda hash_paths+2,y + pha + lda hash_paths,y + pha + lda #0 + sta hash_paths+2,y + sta hash_paths,y + jsl nullfree +next1 ply + plx + iny4 + dex + bne loop1 + + ph4 hash_files + jsl free_files + stz hash_files + stz hash_files+2 + + ph4 hash_table + jsl dispose_table + stz hash_table + stz hash_table+2 + +done rts + + END + +************************************************************************** +* +* Hash data +* +************************************************************************** + +hashdata DATA + +t_size ds 2 + +hash_paths dc 32i4'0' ;32 paths max for now. +hash_files dc i4'0' +hash_table dc i4'0' +hash_numexe dc i2'0' +hash_print dc i2'0' + + END diff --git a/bin/gsh/history.asm b/bin/gsh/history.asm new file mode 100644 index 0000000..c9037da --- /dev/null +++ b/bin/gsh/history.asm @@ -0,0 +1,574 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* HISTORY.ASM +* By Tim Meekins +* +* Routines for dealing with history buffers. +* +* History Data Structures: +* +* HistoryPtr -> historyRec [HistoryPtr is the most recent history] +* +* Where historyRec is: +* +* [+0] NextHistory: pointer to historyRec +* [+4] HistoryCmd: string of characters +* +************************************************************************** + + keep o/history + mcopy m/history.mac + +histNext gequ 0 +histCmd gequ 4 + +;========================================================================= +; +; Add a C string to the head of the history buffer. +; +;========================================================================= + +InsertHistory START + + using HistoryData + using global + +ptr2 equ 0 +ptr equ ptr2+4 +len equ ptr+4 +space equ len+2 + + subroutine (4:cmd),space + + pei (cmd+2) + pei (cmd) + jsr cstrlen + sta len + pea 0 + clc + adc #4+1 + pha + jsl ~NEW + sta ptr + stx ptr+2 + ora ptr+2 + beq putdone + + inc lasthist + inc numhist + + lda historyptr ;Set up linked list pointers + sta [ptr] + ldy #histNext+2 + lda historyptr+2 + sta [ptr],y + mv4 ptr,historyptr + + pei (cmd+2) + pei (cmd) + pei (ptr+2) + clc + lda ptr + adc #4 + pha + jsr copycstr +; +; Now, find out what the maximum history is and prune to that value +; +putdone anop + + Read_Variable RVParm + lda buffer + and #$FF + beq alldone + Dec2Int (#buffer+1,@a,#0),@a + sta size + beq alldone +; +; Follow linked list until we reach size histories +; + mv4 historyptr,ptr + ldy #histNext+2 +follow lda [ptr] + tax + ora [ptr],y + beq alldone ;not enough + dec size + beq prune + lda [ptr],y + sta ptr+2 + stx ptr + bra follow +; +; we have enough, start pruning +; +prune lda [ptr] + sta ptr2 + lda [ptr],y + sta ptr2+2 + lda #0 + sta [ptr] + sta [ptr],y ;terminate last history +; +; Dispose remaining +; +dispose lda ptr2 + ora ptr2+2 + beq alldone + dec numhist + lda [ptr2] + sta ptr + lda [ptr2],y + sta ptr+2 + pei (ptr2+2) + pei (ptr2) + jsl nullfree + lda ptr + sta ptr2 + lda ptr+2 + sta ptr2+2 + ldy #histNext+2 + bra dispose + +alldone return + +RVParm dc a4'historyStr' + dc a4'buffer' + +size ds 2 + + END + +;========================================================================= +; +; Places the previous history into the command buffer, called when pressing +; UP-ARROW. +; +;========================================================================= + +PrevHistory START + + using HistoryData + using global + using termdata + + ora2 historyptr,historyptr+2,@a ;If no history, then skip + jeq ctl5a + + ldx cmdloc ;Move cursor to beginning of line + jsr moveleft + + lda cdcap + ora cdcap + beq ctl5b0 + tputs (cdcap,#0,#outc) + bra ctl5g + +ctl5b0 ldx cmdlen ;clear line +ctl5b dex + bmi ctl5c + phx + lda #' ' + jsr putchar + plx + bra ctl5b +ctl5c ldx cmdlen + jsr moveleft + +ctl5g ora2 currenthist,currenthist+2,@a + bne ctl5i ;If not set up for current hist then + lda historyptr+2 ;Set up at start. + ldx historyptr + ldy #2 + bra ctl5j + +ctl5i mv4 currenthist,0 ;Otherwise move to previous history + stz cmdlen + stz cmdloc + ldy #HistNext+2 + lda [0] + tax + lda [0],y + +ctl5j sta 0+2 ;Save some pointers + stx 0 + sta currenthist+2 + stx currenthist + ora 0 ;If ptr is 0 then at end, quit + beq ctl5a + + ldx #0 ;Display and store command + iny2 +ctl5h lda [0],y + and #$FF + sta cmdline,x + beq ctl5ha + inx + iny + bra ctl5h +ctl5ha stx cmdlen + stx cmdloc + + ldx #^cmdline + lda #cmdline + jsr puts + +ctl5a rts + + END + +;========================================================================= +; +; Places the next history into the command buffer, called when pressing +; DOWN-ARROW. +; +;========================================================================= + +NextHistory START + + using HistoryData + using global + using termdata + + ora2 historyptr,historyptr+2,@a ;No hist, then skip + jeq ctl6a + + stz 4 ;Walk through linked list searching + stz 4+2 ; for hist prior to last hist. + mv4 historyptr,0 +ctl6i if2 0,ne,currenthist,ctl6j + if2 0+2,eq,currenthist+2,ctl6k +ctl6j mv4 0,4 + ldy #HistNext+2 + lda [0] + tax + lda [0],y + sta 0+2 + stx 0 + bra ctl6i + +ctl6k ldx cmdloc ;Move cursor to left + jsr moveleft + + lda cdcap + ora cdcap + beq ctl6b0 + tputs (cdcap,#0,#outc) + bra ctl6g + +ctl6b0 ldx cmdlen ;clear line +ctl6b dex + bmi ctl6c + phx + lda #' ' + jsr putchar + plx + bra ctl6b +ctl6c ldx cmdlen + jsr moveleft + +ctl6g stz cmdlen ;Get hist info. + stz cmdloc + mv4 4,currenthist + ora2 4,4+2,@a + beq ctl6a ;Whoops, back to end, quit + + ldx #0 ;Output the new command + ldy #4 +ctl6h lda [4],y + and #$ff + sta cmdline,x + beq ctl6ha + iny + inx + bra ctl6h +ctl6ha stx cmdlen + stx cmdloc + + ldx #^cmdline + lda #cmdline + jsr puts + +ctl6a rts + + END + +;========================================================================= +; +; Save History if variable set +; +;========================================================================= + +SaveHistory START + + using HistoryData + using global + + lda historyFN + sta DestroyParm+2 + sta CreateParm+2 + sta OpenParm+4 + lda historyFN+2 + sta DestroyParm+4 + sta CreateParm+4 + sta OpenParm+6 + + Read_Variable RVParm + lda buffer + and #$FF + jeq done + Dec2Int (#buffer+1,@a,#0),size + lda size + jeq done +; +; Create and write history to file +; + Destroy DestroyParm + Create CreateParm + jcs done + Open OpenParm + bcs done + mv2 OpenRef,(WriteRef,WriteCRRef,CloseRef) + +loop1 mv4 historyptr,0 + mv2 size,count + ldy #histNext+2 +loop2 lda 0 + ora 0+2 + beq next + lda [0] + tax + dec count + beq write + lda [0],y + sta 0+2 + stx 0 + bra loop2 +write clc + lda 0 + adc #4 + tax + sta WriteBuf + lda 0+2 + adc #0 + sta WriteBuf+2 + pha + phx + jsr cstrlen + sta WriteReq + Write WriteParm + bcs doneclose + Write WriteCR + bcs doneclose +next dec size + bne loop1 + +doneclose Close CloseParm + +done rts + +RVParm dc a4'savehistStr' + dc a4'buffer' + +DestroyParm dc i2'1' + dc a4'historyFN' + +CreateParm dc i2'3' + dc a4'historyFN' + dc i2'$C3' + dc i2'0' + +OpenParm dc i2'2' +OpenRef ds 2 + dc a4'historyFN' + +WriteParm dc i2'4' +WriteRef ds 2 +WriteBuf dc a4'buffer' +WriteReq ds 4 + ds 4 + +WriteCR dc i2'4' +WriteCRRef ds 2 + dc a4'CRBuf' + dc i4'1' + ds 4 +CRBuf dc i1'13' + +CloseParm dc i2'1' +CloseRef ds 2 + +size ds 2 +count ds 2 + + END + +;========================================================================= +; +; Read History file +; +;========================================================================= + +ReadHistory START + + using HistoryData + using global + + lda historyFN + sta OpenParm+4 + lda historyFN+2 + sta OpenParm+6 + + lda #0 + sta historyptr + sta historyptr+2 + + Open OpenParm + bcs done + mv2 OpenRef,(ReadRef,NLRef,CloseRef) + NewLine NLParm + bcs doneclose + +loop anop + Read ReadParm + bcs doneclose + ldy ReadTrans + beq doneclose + dey + lda #0 + sta buffer,y + ph4 #buffer + jsl InsertHistory + bra loop + +doneclose Close CloseParm + +done rts + +OpenParm dc i2'2' +OpenRef ds 2 + dc a4'historyFN' + +NLParm dc i2'4' +NLRef ds 2 + dc i2'$7F' + dc i2'1' + dc a4'NLTable' +NLTable dc i1'13' + +ReadParm dc i2'4' +ReadRef ds 2 + dc a4'buffer' + dc i4'1024' +ReadTrans ds 4 + +CloseParm dc i2'1' +CloseRef ds 2 + +size ds 2 + + END + +;========================================================================= +; +; Init History +; +;========================================================================= +InitHistory START + using HistoryData + + ph4 #histName + jsl AppendHome + stx historyFN+2 + sta historyFN + rts + END + +;========================================================================= +; +; Print History +; +;========================================================================= + +PrintHistory START + + using HistoryData + using global + +ptr equ 0 +space equ ptr+4 + + subroutine (2:argc,4:argv),space + + lda historyptr + ora historyptr+2 + beq done + + lda numhist + sta num +loop1 mv4 historyptr,ptr + lda num + bmi done + sta count +loop2 lda count + beq print + ldy #histNext+2 + lda [ptr] + tax + lda [ptr],y + sta ptr+2 + stx ptr + ora ptr + beq next + dec count + bra loop2 + +print sub2 lasthist,num,@a + Int2Dec (@a,#numbstr,#4,#0) + ldx #^numbstr + lda #numbstr + jsr puts + clc + ldx ptr+2 + lda ptr + adc #4 +ok jsr puts + jsr newline + +next dec num + bra loop1 + +done return + +numbstr dc c'0000: ',h'00' +num ds 2 +count ds 2 + + END + +;========================================================================= +; +; History Data +; +;========================================================================= + +HistoryData DATA + +lasthist dc i2'0' +numhist dc i2'0' +currenthist ds 4 +historyptr dc i4'0' +historyStr str 'HISTORY' +savehistStr str 'SAVEHIST' +histName dc c'/history',i1'0' +historyFN ds 4 + + END diff --git a/bin/gsh/invoke.asm b/bin/gsh/invoke.asm new file mode 100644 index 0000000..1e840f8 --- /dev/null +++ b/bin/gsh/invoke.asm @@ -0,0 +1,709 @@ +*********************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* INVOKE.ASM +* By Tim Meekins +* +* Command invocation routines. +* +************************************************************************** + + mcopy m/invoke.mac + keep o/invoke.mac + +SIGINT gequ 2 +SIGKILL gequ 9 +SIGTERM gequ 15 +SIGSTOP gequ 17 +SIGTSTP gequ 18 +SIGCONT gequ 19 +SIGCHLD gequ 20 +SIGTTIN gequ 21 +SIGTTOU gequ 22 + +************************************************************************** +* +* Redirect +* +************************************************************************** + +redirect START + +space equ 1 +pipeout2 equ space+3 +pipein2 equ pipeout2+2 +pipeout equ pipein2+2 +pipein equ pipeout+2 +eapp equ pipein+2 +app equ eapp+2 +efile equ app+2 +dfile equ efile+4 +sfile equ dfile+4 +end equ sfile+4 + +; subroutine (4:sfile,4:dfile,4:efile,2:app,2:eapp,2:pipein,2:pipeout,2:pipein2,2:pipeout2),space + + tsc + phd + tcd +; +; standard input +; + ora2 sfile,sfile+2,@a + beq execa + pei (sfile+2) ;for c2pstr + pei (sfile) + pei (sfile+2) + pei (sfile) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + sta RedirectFile + stx RedirectFile+2 + phx + pha + jsr c2pstr + stz RedirectDev + stz RedirectApp + Redirect RedirectParm + php + ph4 RedirectFile + jsl nullfree + plp + bcc execa + ldx #^err1 + lda #err1 + jmp badbye +; +; standard output +; +execa ora2 dfile,dfile+2,@a + beq execb + pei (dfile+2) ;for c2pstr + pei (dfile) + pei (dfile+2) + pei (dfile) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + sta RedirectFile + stx RedirectFile+2 + phx + pha + jsr c2pstr + ld2 1,RedirectDev + mv2 app,RedirectApp + Redirect RedirectParm + php + ph4 RedirectFile + jsl nullfree + plp + bcc execb + ldx #^err2 + lda #err2 + jmp badbye +; +; standard error +; +execb ora2 efile,efile+2,@a + beq execc + pei (efile+2) ;for c2pstr + pei (efile) + pei (efile+2) + pei (efile) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + sta RedirectFile + stx RedirectFile+2 + phx + pha + jsr c2pstr + ld2 2,RedirectDev + mv2 eapp,RedirectApp + Redirect RedirectParm + php + ph4 RedirectFile + jsl nullfree + plp + bcc execc + ldx #^err3 + lda #err3 + jmp badbye +; +; is input piped in? +; +execc lda pipein + beq execd + dup2 (pipein,#1) + mv2 pipein2,CloseRef + Close CloseParm + ldx #0 + lda pipein + SetInputDevice (#3,@xa) +; +; is output piped? +; +execd lda pipeout + beq exece + dup2 (pipeout,#2) + mv2 pipeout2,CloseRef + Close CloseParm + ldx #0 + lda pipeout + SetOutputDevice (#3,@xa) + +exece anop + +goodbye ldy #0 + bra exit +badbye jsr errputs + cop $7F ; get out of the way + ldy #1 +exit lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + cpy #1 + + rtl + +RedirectParm anop +RedirectDev ds 2 +RedirectApp ds 2 +RedirectFile ds 4 +CloseParm dc i'1' +CloseRef dc i'0' + +err1 dc c'gsh: Error redirecting standard input.',h'0d00' +err2 dc c'gsh: Error redirecting standard output.',h'0d00' +err3 dc c'gsh: Error redirecting standard error.',h'0d00' + + END + +************************************************************************** +* +* Invoke a command (PHASE 0) +* +************************************************************************** + +invoke START + + using hashdata + using vardata + using global + using pdata + +p equ 0 +biflag equ p+4 +ptr equ biflag+2 +val equ ptr+4 +dir equ val+2 +space equ dir+4 + + subroutine (2:argc,4:argv,4:sfile,4:dfile,4:efile,2:app,2:eapp,2:bg,4:cmd,2:jobflag,2:pipein,2:pipeout,2:pipein2,2:pipeout2,4:pipesem),space + + ld2 -1,val + stz biflag ;not a built-in + + lda argc + bne chknull + + lda sfile + ora sfile+2 + ora dfile + ora dfile+2 + ora efile + ora efile+2 + beq nulldone + + ldx #^hehstr + lda #hehstr + jsr errputs + +nulldone jmp done +; +; Check for null command +; +chknull ldy #2 + lda [argv] + sta dir + lda [argv],y + sta dir+2 + ora dir + beq gonull + lda [dir] + and #$FF + bne checkfile +gonull jmp done +; +; check for file +; +checkfile anop + + pei (dir+2) + pei (dir) + jsl IsBuiltin ;check builtin first + cmp #-1 + jne trybuiltin + + pei (dir+2) + pei (dir) + ph4 hash_table + ph4 #hash_paths + jsl search + cmp #0 + bne changeit + cpx #0 + beq skip + +changeit sta dir + stx dir+2 + +skip lock mutex2 + pei (dir+2) + pei (dir) + jsr c2gsstr + sta GRecPath + sta ptr + stx GRecPath+2 + stx ptr+2 + + GetFileInfo GRec + unlock mutex2 + jcs notfound + + if2 GRecFileType,eq,#$B5,doExec + if2 @a,eq,#$B3,doExec + ldx vardirexec + bne ft02 + cmp #$0F + jeq doDir +ft02 if2 @a,ne,#$B0,badfile + if2 GRecAuxType,ne,#6,badfile + if2 GRecAuxType+2,ne,#0,badfile + jmp doShell +badfile ldx dir+2 + lda dir + jsr errputs + ldx #^err1 + lda #err1 + jsr errputs +free pei (ptr+2) + pei (ptr) + jsl nullfree + jmp done +; +; launch an executable +; +doExec pei (ptr+2) + pei (ptr) + jsl nullfree + jsr prefork + fork #invoke0 + jsr postfork + jmp done + +invoke0 phk + plb +; +; make a a copy of cmd +; + pha + pha + tsc + phd + tcd + ldx #0 + tsc + FindHandle @xa,1 + ldy #6 + lda [1],y ;This is the UserID! + and #$F0FF + pha + ph4 _cmd + jsr cstrlen + inc a + ply + pha + ldx #0 + NewHandle (@xa,@y,#$4018,#0),1 + ply + ldx #0 + PtrToHand (_cmd,1,@xy) + ldy #2 + lda [1],y + tax + lda [1] + pld + ply + ply + phx ;_cmd + pha +; +; make a a copy of dir +; + pha + pha + tsc + phd + tcd + ldx #0 + tsc + FindHandle @xa,1 + ldy #6 + lda [1],y ;This is the UserID! + and #$F0FF + pha + ph4 _dir + jsr cstrlen + inc a + ply + pha + ldx #0 + NewHandle (@xa,@y,#$4018,#0),1 + ply + ldx #0 + PtrToHand (_dir,1,@xy) + ldy #2 + lda [1],y + tax + lda [1] + pld + ply + ply + phx ;_dir + pha + + jsl infork + bcs invoke1 + case on + jsl execve + case off + rtl +invoke1 pla + pla + pla + pla + rtl +; +; do path (it was a directory entry so change to that directory) +; +doDir lock cdmutex + mv4 GRecPath,PRecPath + SetPrefix PRec + unlock cdmutex + stz val + jmp free +; +; fork a shell script +; +doShell inc biflag ;don't free argv... + jsr prefork + +* int fork2(void *subr, int stack, int prio, char *name, word argc, ...) + pea 0 + ldy #2 + lda [argv],y + pha + lda [argv] + pha + pea 0 + pea 1024 + ph4 #exec0 + case on + jsl fork2 + case off + +* fork #exec0 + jsr postfork + jmp free + +exec0 ph2 _argc ;for argfree + ph4 _argv + + ph4 _dir ;for shellexec + ph2 _argc + ph4 _argv + jsl infork + bcs exec0c + signal (#SIGCHLD,#0) + PushVariables 0 + pea 1 + jsl ShellExec + jsl argfree + PopVariables 0 + rtl +exec0c pla + pla + pla + pla + pla + pla + pla + pla + rtl +; +; file not found, so try a builtin. +; +trybuiltin inc biflag ;it's a built-in + cmp #1 + beq noforkbuiltin + jsr prefork + fork #forkbuiltin + jsr postfork + jmp done + +forkbuiltin cop $7F ;give palloc a chance + ph2 _argc + ph4 _argv + jsl infork + bcs fork0c + jsl builtin + rtl +fork0c pla + pla + pla + rtl + +noforkbuiltin anop + pei (argc) + pei (argv+2) + pei (argv) + jsl builtin + stz val + bra done + +notfound pei (ptr+2) + pei (ptr) + jsl nullfree + ldy #2 + lda [argv],y + tax + lda [argv] + jsr errputs + ldx #^err2 + lda #err2 + jsr errputs + lda pipein + beq notfound0 + ssignal _semaphore + sdelete _semaphore + mv4 pjoblist,p + ldy #16 ;p_jobid + lda [p],y + getpgrp @a + eor #$FFFF + inc a + kill (@a,#9) + sigpause #0 +notfound0 anop + +done cop $7F + lda biflag + bne skipfrarg + + pei (argc) + pei (argv+2) + pei (argv) + jsl argfree + +skipfrarg pei (cmd+2) + pei (cmd) + jsl nullfree + + return 2:val +; +; +; stuff to do just before forking +; +prefork lock mutex + SetInGlobals (#$FF,#00) + mv4 sfile,_sfile + mv4 dfile,_dfile + mv4 efile,_efile + mv2 app,_app + mv2 eapp,_eapp + mv4 cmd,_cmd + mv4 dir,_dir + mv2 argc,_argc + mv4 argv,_argv + mv2 pipein,_pipein + mv2 pipeout,_pipeout + mv2 pipein2,_pipein2 + mv2 pipeout2,_pipeout2 + mv2 bg,_bg + mv2 jobflag,_jobflag + lda [pipesem] + sta _semaphore + lda pipesem + sta putsem+1 + lda pipesem+1 + sta putsem+2 + rts +; +; stuff to do right after forking +; +postfork sta val + lda pipein + beq postfork2 + sta CloseRef + Close CloseParm +postfork2 lda pipeout + beq postfork3 + sta CloseRef + Close CloseParm +postfork3 lda val + cmp #-1 + bne postfork4 + ldx #^deadstr + lda #deadstr + jsr errputs + unlock mutex + jmp done +postfork4 ldx jobflag + dex + beq postfork5 + pha + pei (bg) + pei (cmd+2) + pei (cmd) + lda pipein + bne postfork4a + jsl palloc + bra postfork5 +postfork4a jsl pallocpipe +postfork5 lda >mutex ;DANGER!!!!! Assumes knowledge of + beq postfork6 ;lock/unlock structure!!!!!!!! + cop $7F + bra postfork5 +postfork6 rts +; +; stuff to do in fork +; +infork phk + plb + + lda _jobflag + bne invoke0b + + Open ttyopen + jcs doneinfork + + lda _pipein + bne invoke0a + tcnewpgrp ttyref +invoke0a settpgrp ttyref + lda _bg ;if in background then reset tty to + and #$FF + beq invoke0b ;to the shell process group + tctpgrp (gshtty,gshpid) + +invoke0b ph4 _sfile + ph4 _dfile + ph4 _efile + ph2 _app + ph2 _eapp + ph2 _pipein + ph2 _pipeout + ph2 _pipein2 + ph2 _pipeout2 + jsl redirect + jcs doneinfork + + unlock mutex + + lda _pipein + bne invoke0c + lda _pipeout + beq invoke0d + screate #0 +putsem sta >$FFFFFF + swait @a + bra invoke0d +invoke0c lda _pipeout + bne invoke0d +waitsemy lda _semaphore + bne goodsemy + cop $7F + bra waitsemy +goodsemy ssignal _semaphore + sdelete _semaphore + +invoke0d anop + + clc + bra indone + +doneinfork unlock mutex + sec +indone rtl + +mutex key +mutex2 key +cdmutex key + +_argc dc i2'0' +_argv dc i4'0' +_sfile dc i4'0' +_dfile dc i4'0' +_efile dc i4'0' +_app dc i2'0' +_eapp dc i2'0' +_cmd dc i4'0' +_dir dc i4'0' +_pipein dc i2'0' +_pipeout dc i2'0' +_pipein2 dc i2'0' +_pipeout2 dc i2'0' +_bg dc i2'0' +_jobflag dc i2'0' +_semaphore dc i2'0' + +str dc c'[0]',h'0d00' +err1 dc c': Not executable.',h'0d00' +err2 dc c': Command not found.',h'0d00' +hehstr dc c'heh heh, next time you''ll need to specify a command ' + dc c'before redirecting.',h'0d00' +deadstr dc c'Cannot fork (too many processes?)',h'0d00' ;try a spoon + +GRec dc i'4' +GRecPath ds 4 + ds 2 +GRecFileType ds 2 +GRecAuxType ds 4 + +PRec dc i'2' +PRecNum dc i'0' +PRecPath ds 4 + +CloseParm dc i2'1' +CloseRef dc i2'0' + +Err dc i2'0' + +ttyopen dc i2'2' +ttyref dc i2'0' + dc i4'ttyname' +ttyname gsstr '.tty' + + END diff --git a/bin/gsh/jobs.asm b/bin/gsh/jobs.asm new file mode 100644 index 0000000..921d8d2 --- /dev/null +++ b/bin/gsh/jobs.asm @@ -0,0 +1,1721 @@ +************************************************************************ +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* JOBS.ASM +* By Tim Meekins +* +* Job control handling routines +* +************************************************************************** + + mcopy m/jobs.mac + keep o/jobs + +WSTOPPED gequ $7F + +SIGINT gequ 2 +SIGKILL gequ 9 +SIGTERM gequ 15 +SIGSTOP gequ 17 +SIGTSTP gequ 18 +SIGCONT gequ 19 +SIGCHLD gequ 20 +SIGTTIN gequ 21 +SIGTTOU gequ 22 +; +; process structure used in job control +; +p_next gequ 0 ;next in global proclist +p_friends gequ p_next+4 ;next in job list +p_flags gequ p_friends+4 ;various job status flags +p_reason gequ p_flags+2 ;reason for entering this state +p_index gequ p_reason+2 ;job index +p_pid gequ p_index+2 ;process id +p_jobid gequ p_pid+2 ;process id of job leader +p_command gequ p_jobid+2 ;command (how job invoked) +p_space gequ p_command+4 ;space for structure +; +; p_flags values +; +PRUNNING gequ %0000000000000001 ;running +PSTOPPED gequ %0000000000000010 ;stopped +PNEXITED gequ %0000000000000100 ;normally exited +PAEXITED gequ %0000000000001000 ;abnormally exited +PSIGNALED gequ %0000000000010000 ;terminated by signal != SIGINT +PNOTIFY gequ %0000000000100000 ;notify async when done +PTIME gequ %0000000001000000 ;job times should be printed +PAWAITED gequ %0000000010000000 ;top level is waiting for it +PFOREGND gequ %0000000100000000 ;started in shells pgrp +PDUMPED gequ %0000001000000000 ;process dumped core +PDIAG gequ %0000010000000000 ;diagnostic output also piped out +PPOU gequ %0000100000000000 ;piped output +PREPORTED gequ %0001000000000000 ;status has been reported +PINTERRUPTED gequ %0010000000000000 ;job stopped via interrupt signal +PPTIME gequ %0100000000000000 ;time individual process +PNEEDNOTE gequ %1000000000000000 ;notify as soon as practicle + +;==================================================================== +; +; pwait - wait for foreground processes to finish up. +; +;==================================================================== + +pwait START + + using pdata + +waitpid equ 1 +oldsig equ waitpid+2 +p equ oldsig+4 +space equ p+4 +end equ space+3 + +; subroutine (0:dummy),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + getpid + sta waitpid + +waitloop ldx #%0000000000001010 + lda #%0100000000000000 + sigblock @xa + sta oldsig + stx oldsig+2 + + lda pjoblist + ldx pjoblist+2 + +loop sta p + stx p+2 + + ora p+2 + beq done + ldy #p_flags + lda [p],y + and #PFOREGND+PRUNNING + cmp #PFOREGND+PRUNNING + bne loop2 + ldy #p_pid + lda [p],y + cmp waitpid + beq loop2 + +; check if the process is actually running..if it is not, report to the +; user that a stale process was detected and remove it from job control. + + sigsetmask oldsig + sigpause #0 + bra waitloop +loop2 ldy #p_next+2 + lda [p],y + tax + ldy #p_next + lda [p],y + bra loop + +done sigsetmask oldsig + + pld + tsc + clc + adc #end-4 + tcs + + rtl + + END + +;==================================================================== +; +; jobkiller - kills all jobs +; +;==================================================================== + +jobkiller START + + using pdata + +p equ 0 +space equ p+4 + + subroutine (0:dummy),space + +loop lda pjoblist + beq done + ldx pjoblist+2 + beq done + sta p + stx p+2 + ldy #p_pid + lda [p],y + kill (@a,#SIGKILL) + bra loop + +done return + + END + +;==================================================================== +; +; palloc - allocate a process structure and fill it up +; +;==================================================================== + +palloc START + + using pdata + using global + +pp equ 1 +space equ pp+4 +cmd equ space+3 +bg equ cmd+4 +pid equ bg+2 +end equ pid+2 + +; subroutine (2:pid,2:bg,4:cmd),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + ldx #%0000000000001000 + lda #%0000000000000000 + sigblock @xa + phx + pha + + ph4 #p_space + jsl ~NEW + sta pp + stx pp+2 + + ldy #p_pid ;set pid + lda pid + sta [pp],y + ldy #p_jobid + sta [pp],y + + lda bg ;set running flags + bne bg00 + lda #PRUNNING+PFOREGND + bra bg01 +bg00 lda #PRUNNING +bg01 ldy #p_flags + sta [pp],y + + ldy #p_next + lda pjoblist + sta [pp],y + ldy #p_next+2 + lda pjoblist+2 + sta [pp],y + + ldx pp+2 + ldy pp + stx pjoblist+2 + sty pjoblist + + lda pcurrent + ora pcurrent+2 + bne in01 + stx pcurrent+2 + sty pcurrent + bra in02 +in01 lda pprevious + ora pprevious+2 + bne in02 + stx pprevious+2 + sty pprevious +in02 anop + + ldy #p_friends + lda #0 + sta [pp],y + ldy #p_friends+2 + sta [pp],y + + inc pmaxindex ;set job number + ldy #p_index + lda pmaxindex + sta [pp],y + + pei (cmd+2) + pei (cmd) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + pei (cmd+2) + pei (cmd) + phx + pha + ldy #p_command ;set command + sta [pp],y + txa + ldy #p_command+2 + sta [pp],y + jsr copycstr + + lda bg + beq noprint + pei (pp+2) + pei (pp) + pea 1 + pea 0 + jsl pprint +noprint anop + + case on + jsl sigsetmask + case off + + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + rtl + + END + +;==================================================================== +; +; pallocpipe - allocate a process structure and fill it up and append +; to previous command pipeline. +; +;==================================================================== + +pallocpipe START + + using pdata + using global + +p equ 1 +pp equ p+4 +space equ pp+4 +cmd equ space+3 +bg equ cmd+4 +pid equ bg+2 +end equ pid+2 + +; subroutine (2:pid,2:bg,4:cmd),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + ldx #%0000000000001000 + lda #%0000000000000000 + sigblock @xa + phx + pha + + ph4 #p_space + jsl ~NEW + sta pp + stx pp+2 + + ldy #p_pid ;set pid + lda pid + sta [pp],y + ldy #p_jobid + sta [pp],y + + lda bg ;set running flags + bne bg00 + lda #PRUNNING+PFOREGND + bra bg01 +bg00 lda #PRUNNING +bg01 ldy #p_flags + sta [pp],y + + ldy #p_next + lda #0 + sta [pp],y + ldy #p_next+2 + sta [pp],y + ldy #p_friends + sta [pp],y + ldy #p_friends+2 + sta [pp],y + + pei (cmd+2) + pei (cmd) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + pei (cmd+2) + pei (cmd) + phx + pha + ldy #p_command ;set command + sta [pp],y + txa + ldy #p_command+2 + sta [pp],y + jsr copycstr +; +; update the current pipeline to know about the last pipe. +; + lda pjoblist + ldx pjoblist+2 +loop sta p + stx p+2 + ldy #p_flags + lda [pp],y + sta [p],y + ldy #p_jobid + lda [pp],y + sta [p],y + ldy #p_friends + lda [p],y + ldy #p_friends+2 + ora [p],y + beq addit + lda [p],y + tax + ldy #p_friends + lda [p],y + bra loop + +addit ldy #p_friends + lda pp + sta [p],y + ldy #p_friends+2 + lda pp+2 + sta [p],y + + case on + jsl sigsetmask + case off + + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + rtl + + END + +;==================================================================== +; +; handle a SIGCHLD signal +; +;==================================================================== + +pchild START + + using pdata + using global + +waitstatus equ 1 +pid equ waitstatus+4 ;just in case +p equ pid+2 +space equ p+4 +signum equ space+3 +code equ signum+2 +end equ code+2 + +; subroutine (2:code,2:signum),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + phb + phk + plb + + stz signum +; +; get status for the process that just died +; + ldx #0 + clc + tdc + adc #waitstatus + wait @xa + sta pid +; +; search for the job that has finished. +; +search lda pjoblist + ldx pjoblist+2 +lookloop sta p + stx p+2 + ora p+2 + jeq done + ldy #p_jobid + lda [p],y + cmp pid + beq lookfound + ldy #p_next+2 + lda [p],y + tax + ldy #p_next + lda [p],y + bra lookloop +; +; see how wait was signaled. +; +lookfound anop + lda waitstatus + and #$FF + cmp #WSTOPPED + jne kill + lda waitstatus + xba + and #$FF ;<- signal number + sta signum + cmp #SIGTSTP + beq stop + cmp #SIGTERM + jeq zap + cmp #SIGINT + beq zap + cmp #SIGSTOP + beq stop + cmp #SIGTTIN + beq stop + cmp #SIGTTOU + bne zap + +stop ldy #p_flags + lda [p],y + eor #PRUNNING + ora #PSTOPPED + sta [p],y + pei (p+2) + pei (p) + jsr mkjobcur + ldy #p_flags + lda [p],y + bit #PFOREGND + beq stop2 + tctpgrp (gshtty,gshpid) +stop2 pei (p+2) + pei (p) + pea 0 + pei (signum) + jsl pprint + bra done +kill ldy #p_flags + lda [p],y + bit #PFOREGND ;only set status variable if in + beq zap0 ; foreground + lda waitstatus + jsr setstatus + bra zap +zap0 inc signalled +zap ldy #p_index + lda [p],y + pha + jsl removejob + ldy #p_flags + lda [p],y + bit #PFOREGND + beq done + tctpgrp (gshtty,gshpid) + +done anop + plb + lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + rtl +; +; set status return variable +; +setstatus ENTRY + + xba + and #$FF + + cmp #100 + bcc set1 + Int2Dec (@a,#valstat1+1,#3,#0) + lda #valstat1 + ldx #^valstat1 + bra set0 + +set1 cmp #10 + bcc set2 + Int2Dec (@a,#valstat2+1,#2,#0) + lda #valstat2 + ldx #^valstat2 + bra set0 + +set2 Int2Dec (@a,#valstat3+1,#1,#0) + lda #valstat3 + ldx #^valstat3 + +set0 sta SetParm+4 + stx SetParm+6 + Set_Variable SetParm + + rts + +SetParm dc a4'name' + ds 4 +name str 'status' +valstat1 str '000' +valstat2 str '00' +valstat3 str '0' + + END + +;==================================================================== +; +; remove a job +; +;==================================================================== + +removejob START + + using pdata + +p equ 1 +prev equ p+4 +space equ prev+4 +jobnum equ space+3 +end equ jobnum+2 + +; subroutine (2:jobnum),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + stz prev + stz prev+2 + lda pjoblist + ldx pjoblist+2 + +loop sta p + stx p+2 + ora p+2 + jeq done + ldy #p_index + lda [p],y + cmp jobnum + beq gotit + lda p + sta prev + stx prev+2 + ldy #p_next+2 + lda [p],y + tax + ldy #p_next + lda [p],y + bra loop +; +; adjust linked list pointers +; +gotit ora2 prev,prev+2,@a + beq gotit2 + ldy #p_next + lda [p],y + sta [prev],y + ldy #p_next+2 + lda [p],y + sta [prev],y + bra gotit3 +gotit2 ldy #p_next + lda [p],y + sta pjoblist + ldy #p_next+2 + lda [p],y + sta pjoblist+2 +; +; free the node (may want to check currjob and prevjob pointers) +; +gotit3 anop + + ldy #p_flags + lda [p],y + and #PFOREGND + bne gotit3c + jsr newline + ldy #p_flags + lda #0 + sta [p],y + pei (p+2) + pei (p) + pea 0 + pea 0 + jsl pprint +gotit3c anop + + ldy #p_command+2 + lda [p],y + pha + dey2 + lda [p],y + pha + jsl nullfree + + lda pcurrent + eor pcurrent+2 + eor p + eor p+2 + bne gotit3a + mv4 pprevious,pcurrent + stz pprevious + stz pprevious+2 + lda prev + eor prev+2 + eor pcurrent + eor pcurrent+2 + beq gotit3a + mv4 prev,pprevious +gotit3a lda pprevious + eor pprevious+2 + eor p + eor p+2 + bne gotit3b + stz pprevious + stz pprevious+2 +gotit3b anop + +gotit4 ldy #p_friends + lda [p],y + pha + ldy #p_friends+2 + lda [p],y + pha + pei (p+2) + pei (p) + jsl nullfree + pla + sta P+2 + pla + sta p + ora p+2 + beq gotit5 + + ldy #p_command+2 + lda [p],y + pha + ldy #p_command + lda [p],y + pha + jsl nullfree + bra gotit4 + +gotit5 anop +; +; find maximum job number +; + stz prev + lda pjoblist + ldx pjoblist+2 +fmaxloop sta p + stx p+2 + ora p+2 + beq gotmax + ldy #p_index + lda [p],y + cmp prev + bcc skipmax + sta prev +skipmax ldy #p_next+2 + lda [p],y + tax + ldy #p_next + lda [p],y + bra fmaxloop +gotmax mv2 prev,pmaxindex + +done anop + lda space+1 + sta end-2 + lda space + sta end-3 + pld + tsc + clc + adc #end-4 + tcs + + rtl + + END + + +;==================================================================== +; +; mkjobcur +; +;==================================================================== + +mkjobcur START + + using pdata + +space equ 1 +p equ space+2 +end equ p+4 + +; subroutine (4:p),space + + lda p,s + eor p+2,s + eor pcurrent + eor pcurrent+2 + beq done + + mv4 pcurrent,pprevious + lda p,s + sta pcurrent + lda p+2,s + sta pcurrent+2 + +done lda space,s + sta end-2,s + tsc + clc + adc #end-3 + tcs + + rts + + END + +************************************************************************** +* +* JOBS: builtin command +* syntax: exit +* +* displays jobs +* +************************************************************************** + +jobs START + + using pdata + +pidflag equ 0 +pp equ pidflag+2 +count equ pp+4 +space equ count+2 + + subroutine (4:argv,2:argc),space + + stz pidflag + lda argc + dec a + beq cont + dec a + beq grab +shit ldx #^Usage + lda #Usage + jsr errputs + jmp done + +grab ldy #4 + lda [argv],y + sta pp + ldy #4+2 + lda [argv],y + sta pp+2 + lda [pp] + and #$FF + if2 @a,ne,#'-',shit + ldy #1 + lda [pp],y + if2 @a,ne,#'l',shit + inc pidflag + +cont ld2 1,count +loop lda pjoblist + ldx pjoblist+2 +loop2 sta pp + stx pp+2 + ora pp+2 + beq next + ldy #p_index + lda [pp],y + cmp count + beq gotit + ldy #p_next+2 + lda [pp],y + tax + ldy #p_next + lda [pp],y + bra loop2 + +gotit pei (pp+2) + pei (pp) + pei (pidflag) + pea 0 + jsl pprint + +next inc count + lda count + cmp pmaxindex + beq loop + bcc loop + +done return + +Usage dc c'Usage: jobs [-l]',h'0d00' + + END + +************************************************************************** +* +* KILL: builtin command +* syntax: kill [-sig] [pid ...] +* +* sends a [kill] signal to a process +* +************************************************************************** + +kill START + +ptr equ 1 +arg equ ptr+4 +signum equ arg+4 +pid equ signum+2 +space equ pid+2 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + lda argc + dec a + bne init + + ldx #^Usage + lda #Usage + jsr errputs + jmp done + +init stz pid + ld2 SIGTERM,signum + + dec argc + jeq dokill + add2 argv,#4,argv + ldy #2 + lda [argv] + sta arg + lda [argv],y + sta arg+2 + lda [arg] + and #$FF + cmp #'-' + jne getpid + + inc arg + + lda [arg] + and #$FF + cmp #'0' + bcc getname + cmp #'9'+1 + bcs getname + pei (arg+2) + pei (arg) + jsr cstrlen + tax + Dec2Int (arg,@x,#0),signum + + lda signum ;yeah, yeah, I know... + bmi ohshitnum + cmp #1 + bcc ohshitnum + cmp #25 + bcc next + cmp #30 + beq next + cmp #31 + beq next + +ohshitnum ldx #^err1 + lda #err1 + jsr errputs + jmp done + +getname lda [arg] + cmp #'l' + beq lister + pei (arg+2) + pei (arg) + jsr lowercstr + ld2 1,signum + ld4 names,ptr + +nameloop pei (arg+2) + pei (arg) + pei (ptr+2) + pei (ptr) + jsr cmpcstr + cmp #0 + beq next + inc signum + add2 ptr,#8,ptr + lda signum + cmp #32 + bcc nameloop + + ldx #^err3 + lda #err3 + jsr errputs + bra done + +next dec argc + jeq dokill + add2 argv,#4,argv + ldy #2 + lda [argv] + sta arg + lda [argv],y + sta arg+2 + +getpid pei (arg+2) + pei (arg) + jsl parsepid + sta pid + cmp #0 + beq killnull + cmp #-1 + bne dokill + + ldx #^err2 + lda #err2 + jsr errputs + bra done + +lister ldx #^liststr + lda #liststr + jsr puts + bra done + +killnull ldx #^err4 + lda #err4 + jsr errputs + bra done + +dokill kill (pid,signum) + cmp #0 + beq done + ldx #^err2 + lda #err2 + jsr errputs + +done lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +Usage dc c'Usage: kill [-signum | -signame] [pid | %jobid] ...',h'0d00' +err1 dc c'kill: Invalid signal number.',h'0d00' +err2 dc c'kill: No such job or pid.',h'0d00' +err3 dc c'kill: Invalid signal name.',h'0d00' +err4 dc c'kill: Killing the kernel null process isn''t such a good idea.',h'0d00' + +liststr dc c'sighup sigint sigquit sigill sigtrap sigabrt sigemt ' + dc c'sigfpe sigkill sigbus sigsegv sigsys sigpipe sigalrm ' + dc c'sigterm sigurg sigstop sigtstp sigcont sigchld sigttin ' + dc c'sigttou sigio sigxcpu sigusr1 sigusr2',h'0d00' + +names dc c'sighup',h'0000' ;1 + dc c'sigint',h'0000' ;2 + dc c'sigquit',h'00' ;3 + dc c'sigill',h'0000' ;4 + dc c'sigtrap',h'00' ;5 + dc c'sigabrt',h'00' ;6 + dc c'sigemt',h'0000' ;7 + dc c'sigfpe',h'0000' ;8 + dc c'sigkill',h'00' ;9 + dc c'sigbus',h'0000' ;10 + dc c'sigsegv',h'00' ;11 + dc c'sigsys',h'0000' ;12 + dc c'sigpipe',h'00' ;13 + dc c'sigalrm',h'00' ;14 + dc c'sigterm',h'00' ;15 + dc c'sigurg',h'0000' ;16 + dc c'sigstop',h'00' ;17 + dc c'sigtstp',h'00' ;18 + dc c'sigcont',h'00' ;19 + dc c'sigchld',h'00' ;20 + dc c'sigttin',h'00' ;21 + dc c'sigttou',h'00' ;22 + dc c'sigio',h'000000' ;23 + dc c'sigxcpu',h'00' ;24 + dc h'0000000000000000' ;25 + dc h'0000000000000000' ;26 + dc h'0000000000000000' ;27 + dc h'0000000000000000' ;28 + dc h'0000000000000000' ;29 + dc c'sigusr1',h'00' ;30 + dc c'sigusr2',h'00' ;31 + + END + +************************************************************************** +* +* FG: builtin command +* +************************************************************************** + +fg START + + using pdata + using global + +pid equ 0 +p equ pid+2 +space equ p+4 + + subroutine (4:argv,2:argc),space + + lda argc + dec a + bne getit + ora2 pjoblist,pjoblist+2,@a + jeq whoashit + mv4 pjoblist,p + bra dofg + +getit dec a + beq getit2 + ldx #^usage + lda #usage + jmp puterr +getit2 ldy #4+2 + lda [argv],y + pha + ldy #4 + lda [argv],y + pha + jsl parsepid + sta pid + cmp #-1 + jeq nojob + mv4 pjoblist,p +loop ora2 p,p+2,@a + jeq nojob + ldy #p_jobid + lda [p],y + cmp pid + beq dofg + ldy #p_next + lda [p],y + tax + ldy #p_next+2 + lda [p],y + sta p+2 + stx p + bra loop + +dofg ldy #p_flags + lda [p],y + and #PFOREGND+PRUNNING + cmp #PFOREGND+PRUNNING + bne dofg1 + ldx #^err02 + lda #^err01 + bra puterr +dofg1 lda [p],y + ora #PRUNNING+PFOREGND + sta [p],y + ldy #p_jobid + lda [p],y + tax + tctpgrp (gshtty,@x) + ldy #p_flags + lda [p],y + bit #PSTOPPED + beq dofg2 +; lda [p],y + eor #PSTOPPED + sta [p],y + pei (p+2) + pei (p) + pea 0 + pea 0 + jsl pprint + ldy #p_jobid + lda [p],y + getpgrp @a + eor #$FFFF + inc a + kill (@a,#SIGCONT) + bra dofg3 +dofg2 pei (p+2) + pei (p) + pea 0 + pea 0 + jsl pprint +dofg3 jsl pwait + bra done + +whoashit ldx #^err01 + lda #err01 + bra puterr +nojob ldx #^err03 + lda #err03 +puterr jsr errputs + +done return + +usage dc c'Usage: fg [%job | pid]',h'0d00' +err01 dc c'fg: No job to foreground.',h'0d00' +err02 dc c'fg: Gee, this job is already in the foreground.',h'0d00' +err03 dc c'fg: No such job.',h'0d00' + + END + +************************************************************************** +* +* BG: builtin command +* +************************************************************************** + +bg START + + using pdata + using global + +pid equ 0 +p equ pid+2 +space equ p+4 + + subroutine (4:argv,2:argc),space + + lda argc + dec a + bne getit + ora2 pjoblist,pjoblist+2,@a + jeq whoashit + mv4 pjoblist,p + bra dofg + +getit dec a + beq getit2 + ldx #^usage + lda #usage + jmp puterr +getit2 ldy #4+2 + lda [argv],y + pha + ldy #4 + lda [argv],y + pha + jsl parsepid + sta pid + cmp #-1 + jeq nojob + mv4 pjoblist,p +loop ora2 p,p+2,@a + jeq nojob + ldy #p_jobid + lda [p],y + cmp pid + beq dofg + ldy #p_next + lda [p],y + tax + ldy #p_next+2 + lda [p],y + sta p+2 + stx p + bra loop + +dofg ldy #p_flags + lda [p],y + bit #PRUNNING +; cmp #PRUNNING +; bne dofg1 + beq dofg1 + ldx #^err02 + lda #err02 + bra puterr +dofg1 anop +; lda [p],y + ora #PRUNNING + sta [p],y + bit #PFOREGND + beq dobg0 +; lda [p],y + eor #PFOREGND + sta [p],y +dobg0 anop +; lda [p],y + bit #PSTOPPED + beq dofg2 +; lda [p],y + eor #PSTOPPED + sta [p],y + tctpgrp (gshtty,gshpid) + pei (p+2) + pei (p) + pea 0 + pea 0 + jsl pprint + ldy #p_jobid + lda [p],y + getpgrp @a + eor #$FFFF + inc a + kill (@a,#SIGCONT) + bra dofg3 +dofg2 pei (p+2) + pei (p) + pea 0 + pea 0 + jsl pprint +dofg3 bra done + +whoashit ldx #^err01 + lda #err01 + bra puterr +nojob ldx #^err03 + lda #err03 +puterr jsr errputs + +done return + +usage dc c'Usage: bg [%job | pid]',h'0d00' +err01 dc c'bg: No job to background.',h'0d00' +err02 dc c'bg: Gee, this job is already in the background.',h'0d00' +err03 dc c'bg: No such job.',h'0d00' + + END + +************************************************************************** +* +* STOP: builtin command +* +************************************************************************** + +stop START + + using pdata + using global + +pid equ 0 +p equ pid+2 +space equ p+4 + + subroutine (4:argv,2:argc),space + + lda argc + dec a + bne getit + ora2 pjoblist,pjoblist+2,@a + jeq whoashit + mv4 pjoblist,p + bra dofg + +getit dec a + beq getit2 + ldx #^usage + lda #usage + jmp puterr +getit2 ldy #4+2 + lda [argv],y + pha + ldy #4 + lda [argv],y + pha + jsl parsepid + sta pid + cmp #-1 + jeq nojob + mv4 pjoblist,p +loop ora2 p,p+2,@a + jeq nojob + ldy #p_jobid + lda [p],y + cmp pid + beq dofg + ldy #p_next + lda [p],y + tax + ldy #p_next+2 + lda [p],y + sta p+2 + stx p + bra loop + +dofg ldy #p_flags + lda [p],y + and #PSTOPPED + beq dofg1 + ldx #^err02 + lda #err02 + bra puterr +dofg1 tctpgrp (gshtty,gshpid) + ldy #p_jobid + lda [p],y + getpgrp @a + eor #$FFFF + inc a + kill (@a,#SIGSTOP) + bra done + +whoashit ldx #^err01 + lda #err01 + bra puterr +nojob ldx #^err03 + lda #err03 +puterr jsr errputs + +done return + +usage dc c'Usage: stop [%job | pid]',h'0d00' +err01 dc c'stop: No job to stop.',h'0d00' +err02 dc c'stop: Gee, this job is already stopped.',h'0d00' +err03 dc c'stop: No such job.',h'0d00' + + END + +;==================================================================== +; +; print job +; +;==================================================================== + +pprint START + + using pdata + +p equ 0 +count equ p+4 +space equ count+2 + + subroutine (4:pp,2:idflag,2:signum),space + + stz count +; +; display job number +; + lda #'[' + jsr putchar + ldy #p_index + lda [pp],y + cmp #10 + bcs id10 + adc #'0' + jsr putchar + lda #']' + jsr putchar + lda #' ' + jsr putchar + bra ida +id10 Int2Dec (@a,#dec10,#2,#0) + ldx #^dec10 + lda #dec10 + jsr puts +ida lda #' ' + jsr putchar +; +; display '+' or '-' +; + if2 pp,ne,pcurrent,pcur1 + if2 pp+2,ne,pcurrent+2,pcur1 + lda #'+' + bra pcur3 +pcur1 if2 pp,ne,pprevious,pcur2 + if2 pp+2,ne,pprevious+2,pcur2 + lda #'-' + bra pcur3 +pcur2 lda #' ' +pcur3 jsr putchar + lda #' ' + jsr putchar +; +; display process id +; + lda idflag + beq stat + ldy #p_jobid + lda [pp],y + Int2Dec (@a,#pidstr,#5,#0) + ldx #^pidstr + lda #pidstr + jsr puts + ld2 6,count +; +; status +; +stat ldy #p_flags + lda [pp],y + bit #PRUNNING + beq stat2 + ldx #^statrun + lda #statrun + bra stat0 +stat2 bit #PSTOPPED + beq stat3 + ldx #^statstop + lda #statstop + bra stat0 +stat3 ldx #^statohshit + lda #statohshit +stat0 jsr puts +; +; show signal +; + lda signum + beq sig0 + if2 @a,ne,#SIGTTIN,sig2 + ldx #^sigttinstr + lda #sigttinstr + bra sig1 +sig2 if2 @a,ne,#SIGTTOU,sig3 + ldx #^sigttoustr + lda #sigttoustr + bra sig1 +sig3 ldx #^sigotherstr + lda #sigotherstr +sig1 phx + pha + jsr puts + jsr cstrlen + clc + adc count + sta count +sig0 anop +; +; display command +; +showcmd ldy #p_command + lda [pp],y + sta p + ldy #p_command+2 + lda [pp],y + sta p+2 + ldy #0 +chloop lda [p],y + and #$FF + beq next + phy + jsr putchar + ply + iny + inc count + if2 count,cc,#60,chloop +showell ldx #^ellipsis + lda #ellipsis + jsr puts + bra cmd01 + +next ldy #p_friends + lda [pp],y + pha + ldy #p_friends+2 + lda [pp],y + ora 1,s + beq donename + lda [pp],y + sta pp+2 + plx + stx pp + if2 count,cs,#57,showell + clc + adc #3 + sta count + ldx #^pipestr + lda #pipestr + jsr puts + bra showcmd + +donename pla + + ldy #p_flags + lda [pp],y + and #PFOREGND + bne cmd01 + ldx #^ampstr + lda #ampstr + jsr puts + +cmd01 anop + + jsr newline + + return + +dec10 dc c'00]',h'00' +pidstr dc c'00000 ',h'00' +statrun dc c'Running ',h'00' +statstop dc c'Stopped ',h'00' +statohshit dc c'Done ',h'00' +ampstr dc c' &',h'00' +ellipsis dc c'...',h'00' +pipestr dc c' | ',h'00' +sigttinstr dc c'(tty input) ',h'00' +sigttoustr dc c'(tty output) ',h'00' +sigotherstr dc c'(signal) ',h'00' + + END + +;==================================================================== +; +; parse process id (if starts with '%', then parse job num and +; concert to process id). +; +;==================================================================== + +parsepid START + + using pdata + +p equ 0 +len equ p+4 +pid equ len+2 +space equ pid+2 + + subroutine (4:str),space + + pei (str+2) + pei (str) + jsr cstrlen + sta len + lda [str] + and #$FF + cmp #'%' + beq dojob + cmp #'0' + jcc nojob + cmp #'9'+1 + jcs nojob + Dec2Int (str,len,#0),pid + jmp done +dojob ldy #1 + lda [str],y + and #$FF + beq docurjob + if2 @a,eq,#'+',docurjob + if2 @a,eq,#'%',docurjob + if2 @a,ne,#'-',dojobnum + lda pprevious + ldx pprevious+2 + bra gotjob +docurjob lda pcurrent + ldx pcurrent+2 + bra gotjob +dojobnum ldy len + dey + ldx str+2 + lda str + inc a + Dec2Int (@xa,@y,#0),pid + lda pjoblist + ldx pjoblist+2 + sta p + stx p+2 +loop ora2 p,p+2,@a + beq nojob + ldy #p_index + lda [p],y + cmp pid + beq gotjob2 + ldy #p_next + lda [p],y + tax + ldy #p_next+2 + lda [p],y + sta p+2 + stx p + bra loop +gotjob sta p + stx p+2 +gotjob2 ora2 p,p+2,@a + beq nojob + ldy #p_jobid + lda [p],y + sta pid + bra done +nojob ld2 -1,pid + +done return 2:pid + + END + +;==================================================================== +; +; process data +; +;==================================================================== + +pdata DATA + +pwaitsem dc i2'0' + +pjoblist dc i4'0' ;job list +pcurrent dc i4'0' ;current job in table +pprevious dc i4'0' ;previous job in table + +pmaxindex dc i2'0' ;current maximum job index + + END diff --git a/bin/gsh/link.script b/bin/gsh/link.script new file mode 100644 index 0000000..193ab6f --- /dev/null +++ b/bin/gsh/link.script @@ -0,0 +1,22 @@ +o/main +o/shell +o/history +o/prompt +o/cmd +o/expand +o/invoke +o/shellutil +o/builtin +o/hash +o/alias +o/dir +o/shellvar +o/jobs +o/sv +o/stdio +o/orca +o/edit +o/term +o/bufpool +direct +keep=gsh diff --git a/bin/gsh/m16.gno b/bin/gsh/m16.gno new file mode 100644 index 0000000..3c86ddf --- /dev/null +++ b/bin/gsh/m16.gno @@ -0,0 +1,347 @@ +************************************************************************* +* +* GNO/ME system call macros for Orca/M. +* Copyright (C) 1991 by Procyon, Inc. +* +************************************************************************* + +; +; assembly mutual exclusion macros +; + MACRO +&lab lock &a1 +&lab lda #1 + tsb &a1 + beq *+6 + cop $7F + bra *-7 + MEND + + MACRO +&lab unlock &a1 +&lab stz &a1 + MEND + + MACRO +&lab key +&lab dc i2'0' + MEND +; +; GNO system calls +; + + MACRO +&lab kernVersion &a1 +&lab pha + ldx #$403 + jsl $E10008 + pl2 &a1 + MEND + + MACRO +&lab kernStatus &a1 +&lab pha + ldx #$603 + jsl $E10008 + pl2 &a1 + MEND + + MACRO +&lab kill &a1 +&lab ph2 &a1(2) + ph2 &a1(1) + case on + jsl kill + case off + MEND + + MACRO +&lab fork &a1 +&lab ph4 &a1 + case on + jsl fork + case off + MEND + + MACRO +&lab exec &a1 +&lab ph4 &a1(2) + ph4 &a1(1) + case on + jsl exec + case off + MEND + + MACRO +&lab swait &a1 +&lab ph2 &a1 + case on + jsl swait + case off + MEND + + MACRO +&lab ssignal &a1 +&lab ph2 &a1 + case on + jsl ssignal + case off + MEND + + MACRO +&lab screate &a1 +&lab ph2 &a1 + case on + jsl screate + case off + MEND + + MACRO +&lab sdelete &a1 +&lab ph2 &a1 + case on + jsl sdelete + case off + MEND + + MACRO +&lab signal &a1 +&lab ph4 &a1(2) + ph2 &a1(1) + case on + jsl signal + case off + MEND + + MACRO +&lab wait &a1 +&lab ph4 &a1 + case on + jsl wait + case off + MEND + + MACRO +&lab tcnewpgrp &a1 +&lab ph2 &a1 + case on + jsl tcnewpgrp + case off + MEND + + MACRO +&lab settpgrp &a1 +&lab ph2 &a1 + case on + jsl settpgrp + case off + MEND + + MACRO +&lab tctpgrp &a1 +&lab ph2 &a1(2) + ph2 &a1(1) + case on + jsl tctpgrp + case off + MEND + + MACRO +&lab sigsetmask &a1 +&lab ph4 &a1 + case on + jsl sigsetmask + case off + MEND + + MACRO +&lab sigblock &a1 +&lab ph4 &a1 + case on + jsl sigblock + case off + MEND + + MACRO +&lab execve &a1 +&lab ph4 &a1(2) + ph4 &a1(1) + case on + jsl execve + case off + MEND + + MACRO +&lab alarm &a1 +&lab ph4 &a1 + case on + jsl alarm + case off + MEND + + MACRO +&lab setdebug &a1 +&lab ph2 &a1 + case on + jsl setdebug + case off + MEND + + MACRO +&lab setsystemvector &a1 +&lab ph4 &a1 + case on + jsl setsystemvector + case off + MEND + + MACRO +&lab sigpause &a1 +&lab ph4 &a1 + case on + jsl sigpause + case off + MEND + + MACRO +&lab getpid +&lab case on + jsl getpid + case off + MEND + + MACRO +&lab kvm_open +&lab case on + jsl kvm_open + case off + MEND + + MACRO +&lab kvm_close &a1 +&lab ph4 &a1 + case on + jsl kvm_close + case off + MEND + + MACRO +&lab kvmgetproc &a1 +&lab ph2 &a1(2) + ph4 &a1(1) + case on + jsl kvmgetproc + case off + MEND + + MACRO +&lab kvmnextproc &a1 +&lab ph4 &a1 + case on + jsl kvmnextproc + case off + MEND + + MACRO +&lab kvmsetproc &a1 +&lab ph4 &a1 + case on + jsl kvmsetproc + case off + MEND + + MACRO +&lab getpgrp &a1 +&lab ph2 &a1 + case on + jsl getpgrp + case off + MEND + + MACRO +&lab pipe &a1 +&lab ph4 &a1 + case on + jsl pipe + case off + MEND + + MACRO +&lab dup2 &a1 +&lab ph2 &a1(2) + ph2 &a1(1) + case on + jsl dup2 + case off + MEND + + MACRO +&lab ioctl &a1 +&lab ph4 &a1(3) + ph4 &a1(2) + ph2 &a1(1) + case on + jsl ioctl + case off + MEND + + MACRO +&lab tgetent &a1 +&lab ph4 &a1(2) + ph4 &a1(1) + case on + jsl tgetent + case off + MEND + + MACRO +&lab tgetstr &a1 +&lab ph4 &a1(2) + ph4 &a1(1) + case on + jsl tgetstr + case off + MEND + + MACRO +&lab tgetnum &a1 +&lab ph4 &a1 + case on + jsl tgetnum + case off + MEND + + MACRO +&lab tgetflag &a1 +&lab ph4 &a1 + case on + jsl tgetflag + case off + MEND + + MACRO +&lab tgoto &a1 +&lab ph2 &a1(3) + ph2 &a1(2) + ph4 &a1(1) + case on + jsl tgoto + case off + MEND + + MACRO +&lab tputs &a1 +&lab ph4 &a1(3) + ph2 &a1(2) + ph4 &a1(1) + case on + jsl tputs + case off + MEND + + MACRO +&lab getuid +&lab case on + jsl getuid + case off + MEND diff --git a/bin/gsh/main.asm b/bin/gsh/main.asm new file mode 100644 index 0000000..e5d30de --- /dev/null +++ b/bin/gsh/main.asm @@ -0,0 +1,143 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* MAIN.ASM +* By Tim Meekins +* +************************************************************************** + + keep o/main + mcopy m/main.mac + +init START + jml ~GNO_COMMAND + END + +MAIN START + + using global + +p equ 0 +arg equ p+4 +space equ arg+4 + + subroutine (2:argc,4:argv),space + + kernStatus @a + bcc ok + + ErrWriteCString #str + jmp done + +ok stz FastFlag + stz CmdFlag + stz ExecFlag + +argloop dec argc + jeq start + clc + lda argv + adc #4 + sta argv + ldy #2 + lda [argv] + sta arg + lda [argv],y + sta arg+2 + lda [arg] + and #$FF + cmp #'-' + beq intoption + +; parse remaining args as a command to run + + inc ExecFlag + inc FastFlag + ph4 #1024 + jsl ~NEW + sta ExecCmd + sta p + stx ExecCmd+2 + stx p+2 + +cmd3 ldy #0 +cmd0 lda [arg],y + and #$ff + beq cmd1 + sta [p],y + iny + bra cmd0 +cmd1 lda #' ' + sta [p],y + sec ;inc a + tya + adc p + sta p + dec argc + beq cmd2 + clc + lda argv + adc #4 + sta argv + ldy #2 + lda [argv] + sta arg + lda [argv],y + sta arg+2 + bra cmd3 +cmd2 lda #0 + sta [p] + bra start + +intoption ldy #1 +optloop lda [arg],y + and #$FF + beq nextarg + cmp #'f' + beq optf + cmp #'c' + beq parsec + +showusage ErrWriteCString #usage + bra done + +optf inc FastFlag + +nextopt iny + bra optloop + +nextarg cpy #1 + beq showusage + jmp argloop + +parsec clc + lda argv + adc #4 + sta argv + dec argc + beq showusage + inc CmdFlag + inc FastFlag + mv4 argv,CmdArgV + mv2 argc,CmdArgC + +start case on + jsl shell + case off + +done return + +str dc h'0d0a0a' + dc c'Before gsh may be run, the GNO/ME system, or kernel, must be running.' + dc h'0d0a0a00' + +usage dc c'Usage: gsh [-cf] [argument...]',h'0d0a00' + + END diff --git a/bin/gsh/mdb.mac b/bin/gsh/mdb.mac new file mode 100644 index 0000000..8c0ccb8 --- /dev/null +++ b/bin/gsh/mdb.mac @@ -0,0 +1,281 @@ + MACRO +&lab subroutine &parms,&work +&lab anop + aif c:&work,.a + lclc &work +&work setc 0 +.a + gbla &totallen + gbla &worklen +&worklen seta &work +&totallen seta 0 + aif c:&parms=0,.e + lclc &len + lclc &p + lcla &i +&i seta c:&parms +.b +&p setc &parms(&i) +&len amid &p,2,1 + aif "&len"=":",.c +&len amid &p,1,2 +&p amid &p,4,l:&p-3 + ago .d +.c +&len amid &p,1,1 +&p amid &p,3,l:&p-2 +.d +&p equ &totallen+3+&work +&totallen seta &totallen+&len +&i seta &i-1 + aif &i,^b +.e + tsc + sec + sbc #&work + tcs + inc a + phd + tcd + phb + phk + plb + mend + MACRO +&lab return &r +&lab anop + lclc &len + aif c:&r,.a + lclc &r +&r setc 0 +&len setc 0 + ago .h +.a +&len amid &r,2,1 + aif "&len"=":",.b +&len amid &r,1,2 +&r amid &r,4,l:&r-3 + ago .c +.b +&len amid &r,1,1 +&r amid &r,3,l:&r-2 +.c + aif &len<>2,.d + ldy &r + ago .h +.d + aif &len<>4,.e + ldx &r+2 + ldy &r + ago .h +.e + aif &len<>10,.g + ldy #&r + ldx #^&r + ago .h +.g + mnote 'Not a valid return length',16 + mexit +.h + aif &totallen=0,.i + lda &worklen+1 + sta &worklen+&totallen+1 + lda &worklen + sta &worklen+&totallen +.i + plb + pld + tsc + clc + adc #&worklen+&totallen + tcs + aif &len=0,.j + tya +.j + rtl + mend + MACRO +&lab FindHandle &a1,&a2 +&lab pha + pha + ph4 &a1 + tool $1a02 + pl4 &a2 + mend + MACRO +&lab pl4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop + aif s:longa=1,.start + rep #%00100000 +.start +&char amid &parm,1,1 + aif "&char"<>"{",.chk +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + pla + sta (&parm) + ldy #2 + pla + sta (&parm),y + ago .shorten +.chk + aif "&char"<>"[",.chk2 + pla + sta &parm + ldy #2 + pla + sta &parm,y + ago .shorten +.chk2 + aif "&char"<>"@",.absolute +&char1 amid &parm,2,1 +&char2 setc &char1 + pl&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + pl&char2 + ago .shorten +.absolute + pla + sta &parm + pla + sta &parm+2 +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab ph4 &parm + lclc &char + lclc &char1 + lclc &char2 +&lab anop +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk1 + rep #%00100000 +.chk1 + aif "&char"<>"{",.chk2 +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + ldy #2 + lda (&parm),y + pha + lda (&parm) + pha + ago .shorten +.chk2 + aif "&char"<>"[",.absolute + ldy #2 + lda &parm,y + pha + lda &parm + pha + ago .shorten +.absolute + lda &parm+2 + pha + lda &parm + pha + ago .shorten +.at +&char1 amid &parm,2,1 +&char2 setc &char1 + ph&char1 + aif l:&parm<3,.chk2a +&char2 amid &parm,3,1 +.chk2a + ph&char2 + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea +(&parm)|-16 + pea &parm + ago .done +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend + MACRO +&lab tool &a1 +&lab ldx #&a1 + jsl $e10000 + mend + MACRO +&lab name +&lab anop + aif DebugSymbols=0,.pastName + brl pastName&SYSCNT + dc i'$7771' + dc i1'L:&lab',c'&lab' +pastName&SYSCNT anop +.pastName + MEND + macro +&lab NewHandle &a1,&a2 +&lab pha + pha + ph4 &a1(1) + ph2 &a1(2) + ph2 &a1(3) + ph4 &a1(4) + tool $0902 + pl4 &a2 + mend + macro +&lab DisposeHandle &a1 +&lab ph4 &a1 + tool $1002 + mend + macro +&lab ph2 &parm + lclc &char +&lab anop + aif c:&parm=0,.done +&char amid &parm,1,1 + aif "&char"="#",.immediate + aif "&char"="@",.at + aif s:longa=1,.chk + rep #%00100000 +.chk + aif "&char"<>"{",.absolute +&char amid &parm,l:&parm,1 + aif "&char"<>"}",.error +&parm amid &parm,2,l:&parm-2 + lda (&parm) + pha + ago .shorten +.absolute + lda &parm + pha + ago .shorten +.immediate +&parm amid &parm,2,l:&parm-1 + pea &parm + ago .done +.at +&char amid &parm,2,1 + ph&char +.shorten + aif s:longa=1,.done + sep #%00100000 +.done + mexit +.error + mnote "Missing closing '}'",16 + mend diff --git a/bin/gsh/mmdebug.asm b/bin/gsh/mmdebug.asm new file mode 100644 index 0000000..808e4a8 --- /dev/null +++ b/bin/gsh/mmdebug.asm @@ -0,0 +1,41 @@ + mcopy mdb.mac + +~NEW START +hand equ 0 +ptr equ 4 +_~NEW name + + subroutine (4:size),8 + + NewHandle (size,~USER_ID,#$C018,#0),hand + lda [hand] + sta ptr + ldy #2 + lda [hand],y + sta ptr+2 + return 4:ptr + END + +~DISPOSE START +hand equ 0 +checkptr equ 4 +_~DISPOSE name + + subroutine (4:ptr),8 + + FindHandle ptr,hand + lda [hand] + sta checkptr + ldy #2 + lda [hand],y + sta checkptr+2 + eor ptr+2 + eor ptr + eor checkptr + beq okay + + brk $55 + +okay DisposeHandle hand + return + END diff --git a/bin/gsh/mods b/bin/gsh/mods new file mode 100644 index 0000000..a836c5b --- /dev/null +++ b/bin/gsh/mods @@ -0,0 +1,2 @@ +Removed two references to $E0C000 in shell.asm (signal handlers). +Bad Timmy! diff --git a/bin/gsh/oldorca.asm b/bin/gsh/oldorca.asm new file mode 100644 index 0000000..806c048 --- /dev/null +++ b/bin/gsh/oldorca.asm @@ -0,0 +1,175 @@ +************************************************************************* +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* ORCA.ASM +* By Tim Meekins +* +* Builtin commands for Orca compiling/editing, etc. +* +************************************************************************** + + keep o/orca + mcopy m/orca.mac + +************************************************************************** +* +* EDIT: builtin command +* syntax: edit [pathname] +* +* Invokes an editor and edits a file. +* +************************************************************************** + +edit START + +waitstatus equ 0 +pid equ waitstatus+4 +editfile equ pid+2 +outpath equ editfile+4 +errcode equ outpath+4 +space equ errcode+2 + + subroutine (4:argv,2:argc),space + + stz errcode + + lda argc + cmp #2 + beq ok + bcc toofew + + ldx #^err2 + lda #err2 + jmp error +toofew ldx #^err1 + lda #err1 +error jsr errputs + lda #2 + sta errcode + jmp done + +ok lock mutex + + ldy #6 ;argv[1] -> ep.inputPath + lda [argv],y + pha + ldy #4 + lda [argv],y + pha + jsr c2gsstr ;make it a GS/OS filename + sta ep_inputPath + stx ep_inputPath+2 + jsl alloc256 + sta outpath + stx outpath+2 + sta ep_outputPath + stx ep_outputPath+2 + lda #256 + sta [outpath] + ExpandPath ep + bcc ok2 + ldx #^err3 + lda #err3 + jsr errputs + lda #-1 + sta errcode + ldx outpath+2 + lda outpath + jsl free256 + ph4 ep_inputpath + jsl nullfree + unlock mutex + jmp done + +ok2 ph4 ep_inputpath + jsl nullfree + + ldy #2 + lda [outpath],y + xba + sta [outpath],y + add4 outpath,#3,gl ;gl.sfile + +; convert ':'s to '/'s + + lda [outpath],y + xba + tax + ldy #4 + short a +conv lda [outpath],y + cmp #':' + bne next + lda #'/' + sta [outpath],y +next iny + dex + bne conv + long a + + Set_LInfo gl ;now set up the environment + + ph4 #editorvar + jsl getenv + sta editfile + stx editfile+2 + ora editfile+2 + bne gotedit + ph4 #defedit + jsr p2cstr + sta editfile + stx editfile+2 + +gotedit unlock mutex + + pei (editfile+2) + pei (editfile) + ph2 #0 ;tells execute we're called by system + jsl execute + sta errcode + + ldx outpath+2 + lda outpath + jsl free256 + + pei (editfile+2) + pei (editfile) + jsl nullfree + +done return 2:errcode + +err1 dc c'edit: no filename specified',h'0d00' +err2 dc c'edit: only one filename allowed',h'0d00' +err3 dc c'edit: invalid path name',h'0d00' + +mutex key + +gl dc i4'0' + dc i4'nullparm' + dc i4'nullparm' + dc i4'nullparm' + dc i1'8' + dc i1'0' + dc i1'0' + dc i1'0' + dc i4'0' + dc i4'$8000000' + dc i4'0' + +ep dc i2'2' +ep_inputPath dc i4'0' +ep_outputPath dc i4'0' + +nullparm dc i2'0' + +editorvar dc c'editor',h'00' +defedit str '4/editor' + + END diff --git a/bin/gsh/orca.asm b/bin/gsh/orca.asm new file mode 100644 index 0000000..3013a03 --- /dev/null +++ b/bin/gsh/orca.asm @@ -0,0 +1,286 @@ +************************************************************************* +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* ORCA.ASM +* By Tim Meekins +* +* Builtin commands for Orca compiling/editing, etc. +* +************************************************************************** + + keep o/orca + mcopy m/orca.mac + +************************************************************************** +* +* EDIT: builtin command +* syntax: edit pathname... +* +* Invokes an editor and edits a file or files. +* +************************************************************************** + +MAXPARMBUF gequ 1023 + +edit START +strPtr equ 0 +inLoopPtr equ strPtr+4 +argLoopPtr equ inLoopPtr+4 +sLen equ argLoopPtr+4 +k equ sLen+2 +j equ k+2 +editcommand equ j+2 +retval equ editcommand+4 +sFile equ retval+2 GSString255Ptr +inPath equ sFile+4 +outPath equ inPath+4 +space equ outPath+4 + + subroutine (4:argv,2:argc),space + + stz retval + stz sLen + + lda #1 + sta j + + lda argc make sure there are two or + cmp #2 more parameters, otherwise we + bcs enoughparms + + ldx #^enofile + lda #enofile + jsr errputs + lda #1 + sta retval + jmp goaway + +enoughparms anop + jsl alloc1024 + sta sFile + stx sFile+2 + ora sFile+2 + beq memerr1 + + jsl alloc1024 + sta inPath + stx inPath+2 + ora inPath+2 + beq memerr1 + + jsl alloc1024 + sta outPath + stx outPath+2 + ora outPath+2 + bne noerr1 + +memerr1 ldx #^enomem + lda #enomem + jsr errputs + lda #-1 + sta retval + jmp goaway + +noerr1 anop + lda sFile + clc + adc #2 + sta strPtr + lda sFile+2 + adc #0 + sta strPtr+2 + +doloop lda j + cmp #2 + bcc nodelimit + short m + lda #10 ; newline + sta [strPtr] + long m + inc sLen + inc strPtr + bne nodelimit + inc strPtr+2 + +nodelimit anop + lda j + asl a ; get the proper argv pointer + asl a + tay + lda [argv],y + sta argLoopPtr + iny2 + lda [argv],y + sta argLoopPtr+2 + + lda inPath get text field of inPath + clc + adc #2 + sta inLoopPtr + lda inPath+2 + adc #0 + sta inLoopPtr+2 + + stz k + +whileloop lda [argLoopPtr] + and #$00FF + beq donewhile + + short m + sta [inLoopPtr] + long m + inc argLoopPtr + bne noinc2 + inc argLoopPtr+2 +noinc2 inc inLoopPtr + bne noinc3 + inc inLoopPtr+2 +noinc3 inc k + lda k + cmp #255 + bcc whileloop + ldx #^einval + lda #einval + jsr errputs + lda #2 + sta retval + jmp goaway +donewhile lda k + sta [inPath] + lda #1024 + sta [outPath] + mv4 inPath,ep_inputPath + mv4 outPath,ep_outputPath + + ExpandPath ep + bcc noeperror + ldx #^err3 + lda #err3 + jsr errputs + lda #-1 + sta retval + jmp goaway + +noeperror anop + ldy #2 + lda [outPath],y + sta k + clc + adc sLen + cmp #MAXPARMBUF + bcs doloopend + + pei (k) + pei (outPath+2) + lda outPath + clc + adc #4 + pha + pei (strPtr+2) + pei (strPtr) + jsl rmemcpy + + lda sLen + clc + adc k + sta sLen + lda strPtr + clc + adc k + sta strPtr + lda strPtr+2 + adc #0 + sta strPtr+2 +doloopend inc j + lda j + cmp argc + jcc doloop + + lda sLen + sta [sFile] + mv4 sFile,gl_sFile + + Set_LInfoGS gl ;now set up the environment + + ph4 #editorvar + jsl getenv + sta editcommand + stx editcommand+2 + ora editcommand+2 + bne goteditvar + + ph4 #defedit + jsr p2cstr + sta editcommand + stx editcommand+2 + +goteditvar anop + pei (editcommand+2) + pei (editcommand) + ph2 #0 ;tells execute we're called by system + jsl execute + sta retval + + pei (editcommand+2) + pei (editcommand) + jsl nullfree + +goaway lda sFile + ora sFile+2 + beq donedealloc + ldx sFile+2 + lda sFile + jsl free1024 + + lda inPath + ora inPath+2 + beq donedealloc + ldx inPath+2 + lda inPath + jsl free1024 + + lda outPath + ora outPath+2 + beq donedealloc + ldx outPath+2 + lda outPath + jsl free1024 + +donedealloc return 2:retval + +ep dc i2'2' +ep_inputPath dc i4'0' +ep_outputPath dc i4'0' + +enofile dc c'edit: no filename specified',h'0D00' +enomem dc c'edit: out of memory',h'0D00' +einval dc c'edit: invalid argument (filename too long)',h'0D00' +err3 dc c'edit: invalid path name',h'0d00' + +gl anop + dc i2'11' +gl_sfile dc i4'0' + dc i4'nullparm' + dc i4'nullparm' + dc i4'nullparm' + dc i1'8' + dc i1'0' + dc i1'0' + dc i1'0' + dc i4'0' + dc i4'$8000000' + dc i4'0' + +nullparm dc i2'0' + +editorvar dc c'editor',h'00' +defedit str '4:editor' + END diff --git a/bin/gsh/prompt.asm b/bin/gsh/prompt.asm new file mode 100644 index 0000000..074ab27 --- /dev/null +++ b/bin/gsh/prompt.asm @@ -0,0 +1,415 @@ +************************************************************************* +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* PROMPT.ASM +* By Tim Meekins +* +* This displays the command-line prompt +* +************************************************************************** + + keep o/prompt + mcopy m/prompt.mac + +WritePrompt START + + using HistoryData + + +prompt equ 0 +hour equ prompt+4 +minute equ hour+2 +offset equ minute+2 +pfx equ offset+2 +space equ pfx+4 + +year equ hour +monday equ minute +precmd equ prompt + + subroutine (0:dummy),space + + ph4 #precmdstr + jsl findalias + sta precmd + stx precmd+2 + ora precmd+2 + beq getvar + + pei (precmd+2) + pei (precmd) + ph2 #0 + jsl execute + +getvar Read_Variable promptparm + + php + sei ;interrupt free environment + + lda promptbuf + and #$FF + bne parseprompt + + ldx #^dfltPrompt + lda #dfltPrompt + jsr puts + + bra donemark2 + +precmdstr dc c'precmd',h'00' + +parseprompt anop + + ph4 #promptbuf + jsr p2cstr + phx ;for disposal + pha + stx prompt+2 + sta prompt + +promptloop lda [prompt] + inc prompt + and #$FF + beq done + cmp #'%' + beq special + cmp #'!' + jeq phist + cmp #'\' + jeq quoteit +_putchar jsr putchar + bra promptloop + +done jsr standend + jsr cursoron + jsl nullfree +donemark2 plp + jsr flush + return + +special lda [prompt] + inc prompt + and #$FF + beq done + cmp #'%' + beq _putchar + cmp #'h' + beq phist + cmp #'!' + beq phist + cmp #'t' + beq ptime + cmp #'@' + beq ptime + cmp #'S' + jeq pstandout + cmp #'s' + jeq pstandend + cmp #'U' + jeq punderline + cmp #'u' + jeq punderend + cmp #'d' + jeq pcwd + cmp #'/' + jeq pcwd + cmp #'c' + jeq pcwdend + cmp #'C' + jeq pcwdend + cmp #'.' + jeq pcwdend + cmp #'n' + jeq puser + cmp #'W' + jeq pdate1 + cmp #'D' + jeq pdate2 + cmp #'~' + jeq ptilde + + jmp promptloop +; +; Put history number +; +phist lda lasthist + inc a + jsr WriteNum + jmp promptloop +; +; Print current time +; +ptime ReadTimeHex (minute,hour,@a,@a) + lda hour + and #$FF + if2 @a,cc,#13,ptime2 + sub2 @a,#12,@a +ptime2 if2 @a,ne,#0,ptime2b + lda #12 +ptime2b jsr WriteNum + lda #':' + jsr putchar + lda minute + xba + and #$FF + pha + cmp #10 + bcs ptime2a + lda #'0' + jsr putchar +ptime2a pla + jsr WriteNum + lda hour + and #$FF + if2 @a,cs,#12,ptime3 +ptime5 lda #'a' + bra ptime4 +ptime3 lda #'p' +ptime4 jsr putchar + lda #'m' + jmp _putchar +; +; Set Stand Out +; +pstandout jsr standout + jmp promptloop +; +; UnSet Stand Out +; +pstandend jsr standend + jmp promptloop +; +; Set Underline +; +punderline jsr underline + jmp promptloop +; +; UnSet Underline +; +punderend jsr underend + jmp promptloop +; +; Current working directory +; +pcwd jsl alloc1024 + sta pfx + stx pfx+2 + sta GPpfx + stx GPpfx+2 + lda #1024 + sta [pfx] + + GetPrefix GPParm + ldy #2 + lda [pfx],y + clc + adc #3 + sta offset + ldy #4 +pcwd1 lda [pfx],y + and #$FF + jsr toslash + phy + jsr putchar + ply + iny + cpy offset + bcc pcwd1 + ldx pfx+2 + lda pfx + jsl free1024 + jmp promptloop +; +; Current tail of working directory +; +pcwdend anop + jsl alloc1024 + sta pfx + stx pfx+2 + sta GPpfx + stx GPpfx+2 + lda #1024 + sta [pfx] + + GetPrefix GPParm + ldy #2 + lda [pfx],y + clc + adc #3 + sta offset + tay +pcwdend1 dey + bmi pcwdend2 + lda [pfx],y + and #$FF + cmp #':' + bne pcwdend1 +pcwdend2 iny + cpy offset + beq pcwdend3 + lda [pfx],y + and #$FF + cmp #':' + beq pcwdend3 + phy + jsr putchar + ply + bra pcwdend2 +pcwdend3 ldx pfx+2 + lda pfx + jsl free1024 + jmp promptloop +; +; Current working directory substituting '~' if necessary +; +ptilde anop + jsl alloc1024 + sta pfx + stx pfx+2 + sta GPpfx + stx GPpfx+2 + lda #1024 + sta [pfx] + + GetPrefix GPParm + ldy #2 + lda [pfx],y + clc + adc #4 + tay + lda #0 + sta [pfx],y + pei (pfx+2) + lda pfx + clc + adc #4 + pha + jsl path2tilde + phx + pha + jsr puts + jsl ~DISPOSE + ldx pfx+2 + lda pfx + jsl free1024 + jmp promptloop +; +; Write user name +; +puser Read_Variable userparm + ldx #^buf2 + lda #buf2 + jsr putp + jmp promptloop +; +; Write date as mm/dd/yy +; +pdate1 ReadTimeHex (@a,year,monday,@a) + lda monday + and #$FF00 + xba + inc a + jsr WriteNum + lda #'/' + jsr putchar + lda monday + and #$FF + inc a + jsr WriteNum + lda #'/' + jsr putchar + lda year + and #$FF00 + xba + jsr WriteNum + jmp promptloop +; +; Write date as yy-mm-dd +; +pdate2 ReadTimeHex (@a,year,monday,@a) + lda year + and #$FF00 + xba + jsr WriteNum + lda #'-' + jsr putchar + lda monday + and #$FF00 + xba + inc a + jsr WriteNum + lda #'-' + jsr putchar + lda monday + and #$FF + inc a + jsr WriteNum + jmp promptloop +; +; check for \ quote +; +quoteit lda [prompt] + inc prompt + and #$FF + jeq done + cmp #'n' + beq newline + cmp #'r' + beq newline + cmp #'t' + beq tab + cmp #'b' + beq backspace + jmp _putchar +newline lda #13 + jmp _putchar +tab lda #9 + jmp _putchar +backspace lda #8 + jmp _putchar +; +; Write a number between 0 and 9,999 +; +WriteNum cmp #10 + bcs write1 + adc #'0' + jmp putchar +write1 cmp #100 + bcs write2 + Int2Dec (@a,#num+2,#2,#0) + ldx #^num+2 + lda #num+2 + jmp puts +write2 cmp #1000 + bcs write3 + Int2Dec (@a,#num+1,#3,#0) + ldx #^num+1 + lda #num+1 + jmp puts +write3 Int2Dec (@a,#num,#4,#0) + ldx #^num + lda #num + jmp puts + +GPParm dc i2'2' + dc i2'0' +GPpfx dc a4'0' +promptparm dc a4'promptname' + dc a4'promptbuf' +promptname str 'prompt' +dfltPrompt dc c'% ',h'00' +num dc c'0000',h'00' +promptbuf ds 256 +userparm dc a4'user' + dc a4'buf2' +user str 'user' +buf2 ds 256 + + END diff --git a/bin/gsh/shell.asm b/bin/gsh/shell.asm new file mode 100644 index 0000000..9070daf --- /dev/null +++ b/bin/gsh/shell.asm @@ -0,0 +1,401 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* SHELL.ASM +* By Tim Meekins +* +* This is the main routines for the shell. +* +************************************************************************** + + keep o/shell + mcopy m/shell.mac + +SIGINT gequ 2 +SIGTSTP gequ 18 +SIGCHLD gequ 20 + +cmdbuflen gequ 1024 + + case on +shell start + case off + + using global + using pdata + using HistoryData + using termdata + +p equ 0 +space equ p+4 + + subroutine (0:dummy),space + + tsc + sta cmdcontext + tdc + sta cmddp + +* PushVariables 0 + + Open ttyopen + bcc settty + ErrWriteCString #ttyerr + jmp quit +ttyerr dc c'gsh: Failed opening tty.',h'0d00' + +settty mv2 ttyref,gshtty + tcnewpgrp gshtty + settpgrp gshtty + getpid + sta gshpid + + jsr InitTerm + + lda FastFlag + bne fastskip1 + lda gshpid ; only print the copyright msg + cmp #2 ; if not using login + bne fastskip1 + ldx #^gnostr + lda #gnostr + jsr puts +fastskip1 anop + + signal (#SIGINT,#signal2) + signal (#SIGTSTP,#signal18) + signal (#SIGCHLD,#pchild) + setsystemvector #system +; +; Initialize some stuff +; + lda FastFlag + bne fastskip2 + jsr InitHistory + jsr ReadHistory ;Read in history from disk +fastskip2 jsr initalias ;initialize alias + jsr InitDStack ;initialize directory stack + lda FastFlag + bne fastskip3 + jsr DoLogin ;Read gshrc + jsr newline +fastskip3 anop + lda didReadTerm + bne didit + jsr readterm +didit jsl hashpath ;hash $path + + lda CmdFlag + beq cmdskip + + mv4 CmdArgV,p + ldy #2 + lda [p],y + pha + lda [p] + pha + ph2 CmdArgc + pei (p+2) + pei (p) + pea 0 + jsl ShellExec + jmp done1 + +cmdskip lda ExecFlag + beq execskip + + ph4 ExecCmd + ph2 #0 + jsl Execute + jmp done1 + +execskip anop + + stz lastabort + +gnoloop entry + + phk + plb + + lda cmdcontext ;dare you to make a mistake + tcs + lda cmddp + tcd + + jsl WritePrompt + jsr GetCmdLine + bcs done + jsr newline + lda cmdlen + beq gnoloop + jsr cursoron + jsr newlineX + jsr flush + ph4 #cmdline + ph2 #0 + jsl execute + lda exitamundo + bne done1 + jsr newlineX + stz lastabort + bra gnoloop +; +; shut down gsh +; +done jsr newline + jsr newlineX +done1 ora2 pjoblist,pjoblist+2,@a + beq done2 + lda lastabort + bne donekiller + inc lastabort + stz exitamundo + ldx #^stopstr + lda #stopstr + jsr puts + jsr newlineX + bra gnoloop +donekiller jsl jobkiller +done2 lda FastFlag + bne fastskip5 + jsr SaveHistory +fastskip5 jsr dispose_hash + +quit PopVariables 0 + Quit QuitParm +QuitParm dc i'0' + +gnostr dc h'0d',c'GNO/Shell 2.0.4',h'0d' + dc c'Copyright 1991-1993, Procyon, Inc. & Tim Meekins. ' + dc c'ALL RIGHTS RESERVED',h'0d' + dc h'0d00' +stopstr dc c'gsh: There are stopped jobs.',h'0d00' + +ttyopen dc i2'2' +ttyref dc i2'0' + dc i4'ttyname' +ttyname gsstr '.tty' + +exitstr dc c'000000',h'0d00' + +lastabort ds 2 + + END + +;========================================================================= +; +; Interpret the login file (gshrc). +; If $HOME is set, we presume the gshrc file is there. If not, +; or if an error occurs getting the $HOME variable, we use +; @:gshrc. +; +;========================================================================= + + +* Appends a C string to the value of the $HOME variable. If $HOME is +* not set, then it appends the C string to the string '@/'. Returns +* a pointer to a GC string. Call DisposeHome/AX to deallocate the +* string. + +DisposeHome START + dec a + dec a + jsl free256 + rtl + END + +AppendHome START +outPtr equ 0 +len equ 4 + subroutine (4:str),6 + + jsl alloc256 + stx outPtr1+2 + sta outPtr1 + stx outPtr+2 + sta outPtr + + pei (str+2) + pei (str) + jsr cstrlen + sta len + + lda #256 + sta [outPtr] + + GSOS $014B,rvbl ;ReadVariable + bcs doAtSign + + ldy #2 + lda [outPtr],y + beq doAtSign ; $HOME not defined? + clc + adc #4 ; turn into a cstring + tay + short m + lda #0 + sta [outPtr],y + long m + bra doAppend + +doAtSign lda atSign + ldy #4 + sta [outPtr],y + lda #1 + ldy #2 + sta [outPtr],y + +doAppend anop + ldy #0 + short m +lp lda [outPtr],y + beq noSep + cmp #':' + beq foundSep + cmp #'/' + beq foundSep + iny + bra lp +noSep lda #':' + +foundSep sta [str] + long m + + pei (str+2) + pei (str) + pei (outPtr+2) + lda outPtr + clc + adc #4 + pha + case on + jsl strcat + case off + + inc outPtr + inc outPtr + lda [outPtr] + clc + adc len + sta [outPtr] ; adjust GS/OS string length + return 4:outPtr + +atSign dc c'@',i1'0' +rvbl dc i2'3' + dc a4'in' +outPtr1 dc a4'0' + dc i2'0' ; value of 'Export' flag + +in dosin 'HOME' + + END + +DoLogin START + + ph4 #gshrcName + jsl AppendHome + phx ; saved pointer for later + pha + phx + inc a + inc a ; adjust to the C string + pha + + lda #0 + pha + pha + pha + pea 0 + jsl shellexec + + pla + plx + jsl DisposeHome + rts + +gshrcName dc c'/gshrc',h'00' + + END + +;========================================================================= +; +; GLOBAL data +; +;========================================================================= + +global DATA + +ID ds 2 +GSOSDP ds 2 +cmdloc ds 2 +cmdlen ds 2 +cmdline ds cmdbuflen +buffer ds 256 +wordlen ds 2 +wordpbuf ds 1 +wordbuf ds 256 +nummatch ds 2 +matchbuf ds 512*4 +cmdcontext ds 2 +cmddp ds 2 +gshtty ds 2 +gshpid ds 2 +exitamundo dc i'0' ;!=0 if exit +signalled dc i'0' + +FastFlag dc i'0' +CmdFlag dc i'0' +CmdArgV ds 4 +CmdArgC ds 2 +ExecFlag dc i'0' +ExecCmd ds 4 + + END + +;========================================================================= +; +; SIGINT handler when typed at command-line +; +;========================================================================= + +signal2 START + + using global + + subroutine (4:fubar),0 + WriteCString #msg + inc signalled +; ld2 $80,$E0C000 + return + +msg dc c'^C',h'0d0a00' + + END + +;========================================================================= +; +; SIGTSTP handler when typed at command-line +; +;========================================================================= + +signal18 START + + using global + + subroutine (4:fubar),0 + WriteCString #msg + inc signalled +; ld2 $80,$E0C000 + return + +msg dc c'^Z',h'0d0a00' + + END diff --git a/bin/gsh/shellutil.asm b/bin/gsh/shellutil.asm new file mode 100644 index 0000000..461ecab --- /dev/null +++ b/bin/gsh/shellutil.asm @@ -0,0 +1,744 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* SHELLUTIL.ASM +* By Tim Meekins +* +* Utility functions used by the shell. Mainly string functions. +* +************************************************************************** + + keep o/shellutil + mcopy m/shellutil.mac + +;========================================================================= +; +; Convert the accumulator to lower case. +; +;========================================================================= + +tolower START + + cmp #'A' + bcc done + cmp #'Z'+1 + bcs done + adc #'a'-'A' +done rts + + END + +;========================================================================= +; +; Convert ':' to '/' +; +;========================================================================= + +toslash START + + cmp #':' + bne done + lda #'/' +done rts + + END + +;========================================================================= +; +; Convert a c string to lower case +; +;========================================================================= + +lowercstr START + +space equ 1 +p equ space+2 +end equ p+4 + + tsc + phd + tcd + + short a + + ldy #-1 +loop iny + lda [p],y + beq done + cmp #'A' + bcc loop + cmp #'Z'+1 + bcs loop + adc #'a'-'A' + sta [p],y + bra loop + +done rep #$21 + longa on + lda space + sta end-2 + pld + tsc + adc #end-3 + tcs + + rts + + END + +;========================================================================= +; +; Get the length of a c string. +; +;========================================================================= + +cstrlen START + +space equ 1 +p equ space+2 +end equ p+4 + + tsc + phd + tcd + + short a + + ldy #0 +loop lda [p],y + beq done + iny + bra loop + +done rep #$21 + longa on + lda space + sta end-2 + pld + tsc + adc #end-3 + tcs + + tya + + rts + + END + +;========================================================================= +; +; Copy one string to another. Assumes an alloccstr has been performed on +; destination. +; +;========================================================================= + +copycstr START + +space equ 1 +q equ space+2 +p equ q+4 +end equ p+4 + + tsc + phd + tcd + + short a + + ldy #0 +loop lda [p],y + beq done + sta [q],y + iny + bra loop + +done sta [q],y + + rep #$21 + longa on + lda space + sta end-2 + pld + tsc + adc #end-3 + tcs + + rts + + END + +;========================================================================= +; +; Converts a pascal string to a c string. This allocates memory for the +; new c string. +; +;========================================================================= + +p2cstr START + +cstr equ 1 +space equ cstr+4 +p equ space+2 +end equ p+4 + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + lda [p] + and #$FF + inc a + pea 0 + pha + jsl ~NEW + sta cstr + stx cstr+2 + lda [p] + inc p + and #$FF + tax + + short a + ldy #0 + cpx #0 + beq done +loop lda [p],y + sta [cstr],y + iny + dex + bne loop + +done lda #0 + sta [cstr],y + + ldx cstr+2 + ldy cstr + + rep #$21 + longa on + lda space + sta end-2 + pld + tsc + adc #end-3 + tcs + + tya + + rts + + END + +;========================================================================= +; +; Converts a c string to a pascal string. Does not allocate memory. +; +;========================================================================= + +c2pstr START + +space equ 1 +p equ space+2 +cstr equ p+4 +end equ cstr+4 + + tsc + phd + tcd + + short a + + ldy #0 +loop lda [cstr],y + beq endstr + iny + sta [p],y + bra loop +endstr tya + sta [p] + + rep #$21 + longa on + lda space + sta end-2 + pld + tsc + adc #end-3 + tcs + + rts + + END + +;========================================================================= +; +; Converts a c string to a pascal string. Allocates memory for p string. +; +;========================================================================= + +c2pstr2 START + +p equ 1 +space equ p+4 +cstr equ space+2 +end equ cstr+4 + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + pei (cstr+2) + pei (cstr) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + sta p + stx p+2 + + short a + + ldy #0 +loop lda [cstr],y + beq endstr + iny + sta [p],y + bra loop +endstr tya + sta [p] + + ldx p+2 + ldy p + + rep #$21 + longa on + lda space + sta end-2 + pld + tsc + adc #end-3 + tcs + + tya + + rts + + END + +;========================================================================= +; +; Compare two c strings. Return 0 if equal, -1 if less than, +1 greater +; +;========================================================================= + +cmpcstr START + +space equ 1 +q equ space+2 +p equ q+4 +end equ p+4 + + tsc + phd + tcd + + short a + + ldx #0 + + ldy #0 +strloop lda [p],y + beq strchk + cmp [q],y + bne notequal + iny + bra strloop + +strchk lda [q],y + beq done + +lessthan dex + bra done + +notequal bcc lessthan + inx + +done rep #$21 + longa on + lda space + sta end-2 + pld + tsc + adc #end-3 + tcs + + txa + rts + + END + +;========================================================================= +; +; Convert a c string to a GS/OS string (don't forget to dispose when done) +; +;========================================================================= + +c2gsstr START + +len equ 1 +gstr equ len+2 +space equ gstr+4 +cstr equ space+2 +end equ cstr+4 + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + pei (cstr+2) + pei (cstr) + jsr cstrlen + sta len + adc #3 + pea 0 + pha + jsl ~NEW + sta gstr + stx gstr+2 + inc a + inc a + pei (cstr+2) + pei (cstr) + phx + pha + jsr copycstr + lda len + sta [gstr] + + ldx gstr+2 + ldy gstr + + lda space + sta end-2 + pld + tsc + adc #end-3 + tcs + + tya + rts + + END + +;========================================================================= +; +; Takes two strings, concats into a newly created string. +; +;========================================================================= + +catcstr START + +new equ 1 +space equ new+4 +q equ space+2 +p equ q+4 +end equ p+4 + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + pei (p+2) + pei (p) + jsr cstrlen + pha + pei (q+2) + pei (q) + jsr cstrlen + adc 1,s + inc a + inc a + plx + pea 0 + pha + jsl ~NEW + sta new + stx new+2 + + ldy #0 +copy1 lda [p],y + and #$FF + beq copy2 + sta [new],y + iny + bra copy1 +copy2 lda [q] + and #$FF + sta [new],y + beq done + iny + inc q + bra copy2 + +done ldx new+2 + ldy new + lda space + sta end-2 + pld + tsc + clc + adc #end-3 + tcs + + tya + rts + + END + +;===================================================================== +; +; call ~DISPOSE if pointer is not NULL +; +;===================================================================== + +nullfree START + + lda 4,s + ora 6,s + bne ok + lda 2,s + sta 6,s + lda 1,s + sta 5,s + plx + plx + rtl + +ok jml ~DISPOSE + + END + +;===================================================================== +; +; Print a carriage return and a newline, unless "newline" shell var +; is set. +; +;===================================================================== + +newlineX START + + using vardata + + lda varnewline + beq newline + rts + +;===================================================================== +; +; Print a carriage return and a newline +; +;===================================================================== + +newline ENTRY + + lda #13 + jmp putchar + + END + +************************************************************************** +* +* Quick little routine for reading variables and converting to +* null terminated strings. We could probably just link the Orca/C +* library getenv(), but lets stay Orca-free, after all, that's why this +* is written in assembly! :) +* +* Borrowed from termcap +* +************************************************************************** + +getenv START + +newval equ 1 +len equ newval+4 +namebuf equ len+2 +retval equ namebuf+4 +space equ retval+4 +var equ space+3 +end equ var+4 + +; subroutine (4:var),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + stz retval + stz retval+2 + + lock mutex +; +; get length of variable name +; + short a + ldy #0 +findlen lda [var],y + beq gotlen + iny + bra findlen +gotlen long a + sty len +; +; allocate a buffer to put the pascal string +; + iny + pea 0 + phy + jsl ~NEW + sta namebuf + stx namebuf+2 + sta varparm + stx varparm+2 + ora namebuf+2 + jeq exit +; +; now make a pascal string from the c string +; + short ai + lda len + sta [namebuf] + ldy #0 +copyname lda [var],y + beq copydone + iny + sta [namebuf],y + bra copyname +copydone long ai +; +; allocate a return buffer +; + jsl alloc256 + sta newval + stx newval+2 + sta varparm+4 + stx varparm+6 + ora newval+2 + jeq exit0 +; +; Let's go read the variable +; + Read_Variable varparm +; +; Was it defined? +; + lda [newval] + and #$FF + jeq exit1 ;return a null if not defined +; +; Make a return buffer to return the variable value +; + inc a + pea 0 + pha + jsl ~NEW + sta retval + stx retval+2 + ora retval+2 + jeq exit1 +; +; And copy the resulting value +; + short ai + lda [newval] + tay +copyval cpy #0 + beq val1 + lda [newval],y + dey + sta [retval],y + bra copyval +val1 lda [newval] + tay + lda #0 + sta [retval],y + long ai +; +; hasta la vista, baby +; +exit1 ldx newval+2 + lda newval + jsl free256 + +exit0 pei (namebuf+2) + pei (namebuf) + jsl nullfree + +exit unlock mutex + ldy retval + ldx retval+2 + lda space+1 + sta end-2 + lda space + sta end-3 + pld + tsc + clc + adc #end-4 + tcs + tya + + rtl + +varparm ds 8 +mutex key + + END + +rmemcpy START + subroutine (2:num,4:src,4:dest),0 + + ldy num + beq done + tya + dey + bit #1 + bne odd + dey + bra lp1 +odd short m + lda [src],y + sta [dest],y + long m + dey + dey + bmi done +lp1 lda [src],y + sta [dest],y + dey + dey + bpl lp1 +done return + END diff --git a/bin/gsh/shellvar.asm b/bin/gsh/shellvar.asm new file mode 100644 index 0000000..81c8a4c --- /dev/null +++ b/bin/gsh/shellvar.asm @@ -0,0 +1,920 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* Derek Taubert +* +************************************************************************** +* +* SHELLVAR.ASM +* By Tim Meekins +* +* Routines for handling variables in the shell +* +************************************************************************** + + keep o/shellvar + mcopy m/shellvar.mac + +************************************************************************** +* +* SET: builtin command +* syntax: set - displays all variables +* set ... [var] - displays the value of var +* set [var=value]... - sets var to value +* set [var value]... - sets var to value +* +************************************************************************** + +set START + +arg equ 1 +valbuf equ arg+4 +varbuf equ valbuf+4 +space equ varbuf+4 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + lda argc + dec a + beq showvars +; +; If one parameter check for a '-' starting the parm +; + ldy #4 + lda [argv],y + sta arg + iny2 + lda [argv],y + sta arg+2 + lda [arg] + and #$FF + cmp #'-' + beq showusage + jmp skipvar + +showusage ldx #^Usage + lda #Usage + jsr errputs + jmp exit +; +; show variables +; +showvars anop + + jsl alloc256 + sta varbuf + stx varbuf+2 + ora varbuf+2 + beq svwhoops + jsl alloc256 + sta valbuf + stx valbuf+2 + ora valbuf+2 + bne startshow + ldx varbuf+2 + lda varbuf + jsl free256 +svwhoops ld2 $201,Err + Error Err + jmp exit + +startshow lda #254 + sta [valbuf] + sta [varbuf] + lda setmutex + beq wait0 + cop $7F + bra startshow +wait0 inc setmutex + mv4 varbuf,idxParm+2 + mv4 valbuf,idxParm+6 + ld2 1,idxParm+10 +showloop GSOS $0148,idxParm ;ReadIndexed 2.0 + ldy #2 + lda [varbuf],y + and #$FF + beq showdone + xba + sta [varbuf],y + ldy idxParm+12 + beq noexp + xba + tax + ldy #4 + short a +upper lda [varbuf],y + cmp #'a' + bcc upperfoo + cmp #'z'+1 + bcs upperfoo + sec + sbc #'a'-'A' + sta [varbuf],y +upperfoo iny + dex + bne upper + long a +noexp ldx varbuf+2 + lda varbuf + clc + adc #3 + jsr putp + ldx #^showeq + lda #showeq + jsr puts + ldy #2 + lda [valbuf],y + xba + sta [valbuf],y + lda valbuf + ldx valbuf+2 + clc + adc #3 + jsr putp + jsr newline + inc idxParm+10 + bra showloop + +showdone dec setmutex + ldx varbuf+2 + lda varbuf + jsl free256 + ldx valbuf+2 + lda valbuf + jsl free256 + jmp exit +; +; set variables +; +setvar lda setmutex + beq wait1 + cop $7F + bra setvar +wait1 inc setmutex + lda argc + jeq doneset + ldy #2 + lda [argv] + sta arg + lda [argv],y + sta arg+2 + ldy #0 +chkeql lda [arg],y + and #$FF + beq orcastyle + cmp #'=' + jeq unixstyle + iny + bra chkeql +; +; Orca style set. Uses two arguments. +; +orcastyle add2 argv,#4,argv + dec argc + beq showonevar + pei (arg+2) + pei (arg) + pea 1 + pei (arg+2) + pei (arg) + jsr c2pstr2 + phx + pha + sta varParm + stx varParm+2 + ldy #2 + lda [argv],y + pha + lda [argv] + pha + jsr c2pstr2 + phx + pha + sta varParm+4 + stx varParm+4+2 + Set_Variable varParm + jsl nullfree + jsl nullfree + jsl updatevars + jmp nextvar + +showonevar jsl alloc256 + sta valbuf + sta varParm+4 + stx valbuf+2 + stx varParm+4+2 + ora varParm+4+2 + jeq nextvar + pei (arg+2) + pei (arg) + jsr c2pstr2 + phx + pha + sta varParm + stx varParm+2 + Read_Variable varParm + lda [valbuf] + and #$FF + beq notdef + lda varParm + ldx varParm+2 + jsr putp + lda #showeq + ldx #^showeq + jsr puts + lda varParm+4 + ldx varParm+6 + jsr putp + jsr newline +doneone jsl nullfree + lda valbuf + ldx valbuf+2 + jsl free256 + bra doneset + +notdef ldx #^error2 + lda #error2 + jsr errputs + bra doneone + +unixstyle cpy #0 + bne unix0 + ldx #^error1 + lda #error1 + jsr errputs + bra doneset +unix0 short a + lda #0 + sta [arg],y + long a + tya + sec + adc arg + pei (arg+2) + pha + jsr c2pstr2 + phx + pha + sta varParm+4 + stx varParm+4+2 + pei (arg+2) + pei (arg) + pea 1 + pei (arg+2) + pei (arg) + jsr c2pstr2 + phx + pha + sta varParm + stx varParm+2 + Set_Variable varParm + jsl nullfree + jsl updatevars + jsl nullfree + +nextvar dec setmutex +skipvar add2 argv,#4,argv + dec argc + jmp setvar + +doneset dec setmutex + +exit lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + adc #end-4 + tcs + + lda #0 + + rtl + +varParm ds 4 + ds 4 + ds 2 + +idxParm dc i2'4' + ds 4 + ds 4 + ds 2 + ds 2 + +setmutex dc i'0' +showeq dc c' = ',h'00' +Usage dc c'Usage:',h'0d' + dc c' set - displays all variables',h'0d' + dc c' set ... [var] - displays the value of var',h'0d' + dc c' set [var value]... - sets var to value',h'0d' + dc c' set [var=value]... - sets var to value',h'0d' + dc h'00' +error1 dc c'set: Variable not specified',h'0d00' +error2 dc c'set: Variable not defined',h'0d00' + +Err ds 2 + + END + +************************************************************************** +* +* SETENV: builtin command +* syntax: setenv - displays all variables +* setenv ... [var] - displays the value of var +* setenv [var=value]... - sets var to value +* setenv [var value]... - sets var to value +* +************************************************************************** + +setenv START + +arg equ 1 +valbuf equ arg+4 +varbuf equ valbuf+4 +space equ varbuf+4 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + sec + sbc #space-1 + tcs + phd + tcd + + lda argc + dec a + beq showvars +; +; If one parameter check for a '-' starting the parm +; + ldy #4 + lda [argv],y + sta arg + iny2 + lda [argv],y + sta arg+2 + lda [arg] + and #$FF + cmp #'-' + beq showusage + jmp skipvar + +showusage ldx #^Usage + lda #Usage + jsr errputs + jmp exit +; +; show variables +; +showvars anop + + jsl alloc256 + sta varbuf + stx varbuf+2 + ora varbuf+2 + beq svwhoops + jsl alloc256 + sta valbuf + stx valbuf+2 + ora valbuf+2 + bne startshow + ldx varbuf+2 + lda varbuf + jsl free256 +svwhoops ld2 $201,Err + Error Err + jmp exit + +startshow lda setmutex + beq wait0 + cop $7F + bra startshow +wait0 inc setmutex + mv4 varbuf,varParm+0 + mv4 valbuf,varParm+4 + ld2 1,varParm+8 + PushVariables 0 +showloop Read_Indexed varParm + lda [varbuf] + and #$FF + beq showdone + tax + ldy #1 + short a +upper lda [varbuf],y + cmp #'a' + bcc upperfoo + cmp #'z'+1 + bcs upperfoo + sec + sbc #'a'-'A' + sta [varbuf],y +upperfoo iny + dex + bne upper + long a + lda varParm + ldx varParm+2 + jsr putp + ldx #^showeq + lda #showeq + jsr puts + lda varParm+4 + ldx varParm+6 + jsr putp + jsr newline + inc varParm+8 + bra showloop + +showdone PopVariables 0 + dec setmutex + ldx varbuf+2 + lda varbuf + jsl free256 + ldx valbuf+2 + lda valbuf + jsl free256 + jmp exit +; +; set variables +; +setvar lda setmutex + beq wait1 + cop $7F + bra setvar +wait1 inc setmutex + lda argc + jeq doneset + ldy #2 + lda [argv] + sta arg + lda [argv],y + sta arg+2 + ldy #0 +chkeql lda [arg],y + and #$FF + beq orcastyle + cmp #'=' + jeq unixstyle + iny + bra chkeql +; +; Orca style set. Uses two arguments. +; +orcastyle add2 argv,#4,argv + dec argc + beq showonevar + pei (arg+2) + pei (arg) + pea 1 + pei (arg+2) + pei (arg) + jsr c2pstr2 + phx + pha + sta varParm + stx varParm+2 + sta exportparm + stx exportparm+2 + ldy #2 + lda [argv],y + pha + lda [argv] + pha + jsr c2pstr2 + phx + pha + sta varParm+4 + stx varParm+4+2 + Set_Variable varParm + Export exportparm + jsl nullfree + jsl nullfree + jsl updatevars + jmp nextvar + +showonevar jsl alloc256 + sta valbuf + sta varParm+4 + stx valbuf+2 + stx varParm+4+2 + ora varParm+4+2 + jeq nextvar + pei (arg+2) + pei (arg) + jsr c2pstr2 + phx + pha + sta varParm + stx varParm+2 + PushVariables 0 + Read_Variable varParm + PopVariables 0 + lda [valbuf] + and #$FF + beq notthere + lda varParm + ldx varParm+2 + jsr putp + lda #showeq + ldx #^showeq + jsr puts + lda varParm+4 + ldx varParm+6 + jsr putp + jsr newline +doneone jsl nullfree + ldx valbuf+2 + lda valbuf + jsl free256 + jmp doneset + +notthere ldx #^error2 + lda #error2 + jsr errputs + bra doneone + +unixstyle cpy #0 + bne unix0 + ldx #^error1 + lda #error1 + jsr errputs + bra doneset +unix0 short a + lda #0 + sta [arg],y + long a + clc ;use sec and kill the iny :) + iny + tya + adc arg + pei (arg+2) + pha + jsr c2pstr2 + phx + pha + sta varParm+4 + stx varParm+4+2 + pei (arg+2) + pei (arg) + pea 1 + pei (arg+2) + pei (arg) + jsr c2pstr2 + phx + pha + sta varParm + stx varParm+2 + sta exportparm + stx exportparm+2 + Set_Variable varParm + Export exportparm + jsl nullfree + jsl updatevars + jsl nullfree + +nextvar dec setmutex +skipvar add2 argv,#4,argv + dec argc + jmp setvar + +doneset dec setmutex + +exit lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + adc #end-4 + tcs + + lda #0 + + rtl + +varParm ds 4 + ds 4 + ds 2 + +exportparm ds 4 + dc i'1' + +setmutex dc i'0' +showeq dc c' = ',h'00' +Usage dc c'Usage:',h'0d' + dc c' setenv - displays all variables',h'0d' + dc c' setenv ... [var] - displays the value of var',h'0d' + dc c' setenv [var value]... - sets var to value',h'0d' + dc c' setenv [var=value]... - sets var to value',h'0d' + dc h'00' +error1 dc c'setenv: Variable not specified',h'0d00' +error2 dc c'setenv: Variable not defined',h'0d00' + +Err ds 2 + + END + +************************************************************************** +* +* EXPORT: builtin command +* syntax: export [var] ... +* +* exports each variable given in the list +* +************************************************************************** + +export START + +space equ 1 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + phd + tcd + + lda argc + dec a + bne loop + ldx #^Usage + lda #Usage + jsr errputs + bra done + +loop add2 argv,#4,argv + dec argc + beq done + +wait lda expmutex + beq wait0 + cop $7F + bra wait +wait0 inc expmutex + + ldy #2 + lda [argv],y + pha + lda [argv] + pha + jsr c2pstr2 + phx + pha + sta exportparm + stx exportparm+2 + Export exportparm + jsl nullfree + + dec expmutex + + bra loop + +done lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +expmutex dc i'0' + +exportparm ds 4 + dc i'1' + +Usage dc c'Usage: export var ...',h'0d00' + + END + +************************************************************************** +* +* UNSET: builtin command +* syntax: unset [var] ... +* +* unsets each variable given in the list +* +************************************************************************** + +unset START + +space equ 1 +argc equ space+3 +argv equ argc+2 +end equ argv+4 + +; subroutine (4:argv,2:argc),space + + tsc + phd + tcd + + lda argc + dec a + bne loop + + ldx #^Usage + lda #Usage + jsr errputs + bra done + +loop add2 argv,#4,argv + dec argc + beq done + +wait lda unsmutex + beq wait0 + cop $7F + bra wait +wait0 inc unsmutex + + ldy #2 + lda [argv],y + tax + lda [argv] + phx + pha + pea 0 + phx + pha + jsr c2pstr2 + phx + pha + sta unsetparm + stx unsetparm+2 + UnsetVariable unsetparm + jsl nullfree + jsl updatevars + + dec unsmutex + + bra loop + +done lda space + sta end-3 + lda space+1 + sta end-2 + pld + tsc + clc + adc #end-4 + tcs + + lda #0 + + rtl + +unsmutex dc i'0' + +unsetparm ds 4 + +Usage dc c'Usage: unset var ...',h'0d00' + + END + +;==================================================================== +; +; update shell variable flags +; +; CHANGE TO JUST DO A READVARIABLES ON THE PASSED VAR +; +;==================================================================== + +updatevars START + + using vardata + +space equ 0 + + subroutine (4:var,2:flag),space ;flag 1: set, 0: unset + + pei (var+2) + pei (var) + ph4 #varechoname + jsr cmpcstr + bne up2 + lda flag + sta varecho + jmp done + +up2 pei (var+2) + pei (var) + ph4 #direxecname + jsr cmpcstr + bne up3 + lda flag + sta vardirexec + jmp done + +up3 pei (var+2) + pei (var) + ph4 #newlinename + jsr cmpcstr + bne up4 + lda flag + sta varnewline + jmp done + +up4 pei (var+2) + pei (var) + ph4 #noglobname + jsr cmpcstr + bne up5 + lda flag + sta varnoglob + jmp done + +up5 pei (var+2) + pei (var) + ph4 #nobeepname + jsr cmpcstr + bne up6 + lda flag + sta varnobeep + jmp done + +up6 pei (var+2) + pei (var) + ph4 #pushdsilname + jsr cmpcstr + bne up7 + lda flag + sta varpushdsil + jmp done + +up7 pei (var+2) + pei (var) + ph4 #termname + jsr cmpcstr + bne up8 + jsr readterm + jmp done + +up8 pei (var+2) + pei (var) + ph4 #ignorename + jsr cmpcstr + bne up9 + lda flag + sta varignore + jmp done + +up9 anop + +done return + + END + +;=================================================================== +; +; variable settings +; +;=================================================================== + +vardata DATA + +varechoname dc c'echo',h'00' +direxecname dc c'nodirexec',h'00' +newlinename dc c'nonewline',h'00' +noglobname dc c'noglob',h'00' +nobeepname dc c'nobeep',h'00' +pushdsilname dc c'pushdsilent',h'00' +termname dc c'term',h'00' +ignorename dc c'ignoreeof',h'00' + +varecho dc i'0' +vardirexec dc i'0' +varnewline dc i'0' +varnoglob dc i'0' +varnobeep dc i'0' +varpushdsil dc i'0' +varignore dc i'0' + + END diff --git a/bin/gsh/stdio.asm b/bin/gsh/stdio.asm new file mode 100644 index 0000000..a3f4fd8 --- /dev/null +++ b/bin/gsh/stdio.asm @@ -0,0 +1,441 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* STDIO.ASM +* By Tim Meekins +* +* This is the custom stdio for the shell +* +* stdout buffer size: 512 bytes +* stderr buffer size: 256 bytes +* stdin buffer size: 128 bytes +* +************************************************************************** + + keep o/stdio + mcopy m/stdio.mac + +************************************************************************** +* +* putchar - output a character to standard out +* On entry: A = character +* +************************************************************************** + +putchar START + + using stdout + + tay ;lock destroys Acc + lock mutex + tya + and #$FF + ldx index + sta stream,x ;we're still in long mode, note extra + inx ; length of stream by one :) + cmp #13 + beq _flush + cpx #512 + bcc done +_flush stx index + Write WriteParm + ldx #0 +done stx index + unlock mutex + rts + + END + +************************************************************************** +* +* puts - output a c string to standard out +* On entry: A/X = pointer to string +* +************************************************************************** + +puts START + + using stdout + + tay ;lock destroys Acc + lock mutex + sty getchar+1 + txa + + short a + sta getchar+3 + ora getchar+2 + ora getchar+1 + beq exit + + ldy index + ldx #0 + +getchar lda >$FFFFFF,x + beq done + sta stream,y + iny + inx + cmp #13 + beq _flush + cpy #512 + bcc getchar + +_flush sty index + phx + long a + Write WriteParm + Flush flushparm + short a + plx + ldy #0 + bra getchar + +done sty index +exit long a + unlock mutex + rts + + END + +************************************************************************** +* +* putp - output a p string to standard out +* On entry: A/X = pointer to string +* +************************************************************************** + +putp START + + using stdout + + tay ;lock destroys Acc + lock mutex + sty getchar+1 + sty cmpchar+1 + txa + + short a + sta getchar+3 + sta cmpchar+3 + + ldy index + ldx #1 + bra next + +getchar lda >$FFFFFF,x + sta stream,y + iny + inx + cmp #13 + beq _flush +next txa +cmpchar cmp >$FFFFFF + beq check2 + bcs done +check2 cpy #512 + bcc getchar + +_flush sty index + phx + long a + Write WriteParm + Flush flushparm + short a + plx + ldy #0 + bra next + +done sty index + long a + unlock mutex + rts + + END + +************************************************************************** +* +* flush - flush stdout +* +************************************************************************** + +flush START + + using stdout + + lock mutex + lda index + beq skip + Write WriteParm + Flush flushparm + stz index +skip unlock mutex + + rts + + END + +************************************************************************** +* +* data for standard out +* +************************************************************************** + +stdout PRIVDATA + +mutex key + +WriteParm dc i2'4' + dc i2'2' ;2 is standard out + dc i4'stream' +index dc i4'0' + dc i4'0' + +flushparm dc i2'1' + dc i2'2' + +stream ds 512+1 + + END + +************************************************************************** +* +* errputchar - output a character to standard error +* On entry: A = character +* +************************************************************************** + +errputchar START + + using stderr + + tay ;lock destroys Acc + lock errmutex + tya + and #$FF + ldx errindex + sta errstream,x + inx + cmp #13 + beq _flush + cpx #256 + bcc done +_flush stx errindex + Write errWriteParm + ldx #0 +done stx errindex + unlock errmutex + rts + + END + +************************************************************************** +* +* errputs - output a c string to standard error +* On entry: A/X = pointer to string +* +************************************************************************** + +errputs START + + using stderr + + tay ;lock destroys Acc + lock errmutex + sty getchar+1 + txa + + short a + sta getchar+3 + + ldy errindex + ldx #0 + +getchar lda >$FFFFFF,x + beq done + sta errstream,y + iny + inx + cmp #13 + beq _flush + cpy #256 + bcc getchar + +_flush sty errindex + phx + long a + Write errWriteParm + short a + plx + ldy #0 + bra getchar + +done sty errindex + long a + unlock errmutex + rts + + END + +************************************************************************** +* +* errputp - output a p string to standard error +* On entry: A/X = pointer to string +* +************************************************************************** + +errputp START + + using stderr + + tay ;lock destroys Acc + lock errmutex + sty getchar+1 + sty cmpchar+1 + txa + + short a + sta getchar+3 + sta cmpchar+3 + + ldy errindex + ldx #1 + +getchar lda >$FFFFFF,x + sta errstream,y + iny + inx + cmp #13 + beq _flush +next txa +cmpchar cmp >$FFFFFF + beq check2 + bcs done +check2 cpy #256 + bcc getchar + +_flush sty errindex + phx + long a + Write errWriteParm + short a + plx + ldy #0 + bra next + +done sty errindex + long a + unlock errmutex + rts + + END + +************************************************************************** +* +* errflush - flush stderr +* +************************************************************************** + +errflush START + + using stderr + + lock errmutex + Write errWriteParm + stz errindex + unlock errmutex + + rts + + END + +************************************************************************** +* +* data for standard error +* +************************************************************************** + +stderr PRIVDATA + +errmutex key + +errWriteParm dc i2'4' + dc i2'3' ;3 is standard err + dc i4'errstream' +errindex dc i4'0' + dc i4'0' + +errstream ds 256+1 ;not as large as stdout + + END + +************************************************************************** +* +* getchar - read a single character from standard input +* on exit: a = character, -1 if EOF +* +************************************************************************** + +getchar START + + using stdin + + lock inmutex + + lda insize ;any characters in stream? + bne grabchar ;yup + +readloop Read inReadParm + bcc okread + ldy #-1 ;return EOF on ALL errors + jmp done2 + +okread stz inindex + lda insize + bne grabchar + + cop $7F ;no characters ready, so wait + bra readloop + +grabchar ldx inindex + lda instream,x + and #$7F + inc inindex + dec insize + + tay + +done2 unlock inmutex + tya + rts + + END + +************************************************************************** +* +* data for standard input +* +************************************************************************** + +stdin PRIVDATA + +inmutex key + +inReadParm dc i2'4' + dc i2'1' ;1 is standard input + dc i4'instream' +inrequest dc i4'128' +insize dc i4'0' + +inindex dc i2'0' + +instream ds 128+1 + + END diff --git a/bin/gsh/sv.asm b/bin/gsh/sv.asm new file mode 100644 index 0000000..2b142cb --- /dev/null +++ b/bin/gsh/sv.asm @@ -0,0 +1,535 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* SV.ASM +* By Tim Meekins +* +* String Vector routines. +* +************************************************************************** + + keep o/sv + mcopy m/sv.mac + +************************************************************************** +* +* Allocate a string vector array +* +************************************************************************** + +sv_alloc START + +ptr equ 0 +space equ ptr+4 + + subroutine (2:size),space + + lda size + inc a ;for size and count + inc a ;at least one null entry + asl a + asl a + pea 0 + pha + jsl ~NEW + sta ptr + stx ptr+2 + + ldy #2 + lda size + sta [ptr],y + lda #0 + sta [ptr] + ldy #4 + + ldx size + +init sta [ptr],y + iny + iny + sta [ptr],y + iny + iny + dex + bpl init ;not bne so that extra null at end + + add4 ptr,#4,ptr + + return 4:ptr + + END + +************************************************************************** +* +* Add a string to the string vector +* +************************************************************************** + +sv_add START + +p equ 0 +base equ p+4 +space equ base+4 + + subroutine (4:vect,4:string,2:allocflag),space + + sub4 vect,#4,base + + ldy #2 + lda [base],y + cmp [base] + beq exit ;ack, the vector is full! +; +; 1 = allocate memory, 0 = use string as is... +; + lda allocflag + beq asis + + pei (string+2) + pei (string) + jsr cstrlen + inc a + pea 0 + pha + jsl ~NEW + sta p + stx p+2 + + pei (string+2) + pei (string) + phx + pha + jsr copycstr + bra doit + +asis mv4 string,p + +doit lda [base] + tax + asl a + asl a + tay + lda p + sta [vect],y + iny + iny + lda p+2 + sta [vect],y + + txa + inc a + sta [base] + +exit return + + END + +************************************************************************** +* +* Dispose a string vector +* +************************************************************************** + +sv_dispose START + +p equ 0 +space equ p+4 + + subroutine (4:vect),space + + sub4 vect,#4,p + +loop lda [p] + beq done + asl a + asl a + tay + lda [vect],y + tax + iny + iny + lda [vect],y + pha + phx + jsl nullfree + lda [p] + dec a + sta [p] + bra loop + +done pei (p+2) + pei (p) + jsl nullfree + + return + + END + +************************************************************************** +* +* Column print a string vector +* +************************************************************************** + +sv_colprint START + +numrow equ 0 +numcol equ numrow+2 +base equ numcol+2 +maxlen equ base+4 +space equ maxlen+2 + + subroutine (4:sv),space + + sub4 sv,#4,base +; +; Find the maximum string length +; + lda #1 + sta maxlen + + ldy #0 + lda #0 +lenloop pha + lda [sv],y + tax + iny + iny + lda [sv],y + iny + iny + phy + pha + phx + jsr cstrlen + cmp maxlen + bcc nextlen + sta maxlen +nextlen ply + pla + inc a + cmp [base] + bcc lenloop +; +; add one for a space +; + inc maxlen +; +; calculate the number of columns....this is probably simpler than doing +; a divide.. +; + ldx #0 + txa + dex + clc +colloop inx + adc maxlen + cmp #80 + bcc colloop + cpx #6+1 + bcc okcol + ldx #6 ;limit of 6 columns +okcol stx numcol +; +; recalculate the width +; + UDivide (#80,@x),(maxlen,@a) +; +; calculate the height +; + lda [base] + UDivide (@a,numcol),(numrow,@x) + cpx #0 + beq foocol + inc numrow +foocol anop +; +; find the index for each column... +; + lda #0 + tax + clc +mkidxloop sta offtbl,x + inx + adc numrow + cmp [base] + bcc mkidxloop +; +; well....I think we can print now (yay!) +; + ldx #0 +printloop lda offtbl,x + and #$FF + cmp [base] + bcs nextprint0 + inc a + short a + sta offtbl,x + long a + phx + dec a + asl a + asl a + tay + lda [sv],y + tax + iny + iny + lda [sv],y + pha + phx + tax + lda 1,s + jsr puts + jsr cstrlen +tabit cmp maxlen + bcs nextprint + pha + lda #' ' + jsr putchar + pla + inc a + bra tabit +nextprint plx + inx + cpx numcol + bcc printloop +nextprint0 jsr newline + ldx #0 + dec numrow + bne printloop + +doneprint return + +offtbl ds 7 + + END + +************************************************************************** +* +* Sort a string vector +* +************************************************************************** + +sv_sort START + +space equ 0 + + subroutine (4:sv),space + + pei (sv+2) + pei (sv) + sub4 sv,#4,sv + pea 0 + lda [sv] + dec a + pha + jsl _qsort + + return + + END + +_qsort PRIVATE + +vleft equ 0 +i equ vleft+4 +last equ i+2 +ptr2 equ last+2 +ptr1 equ ptr2+4 +idx1 equ ptr1+4 +space equ idx1+2 + + subroutine (4:sv,2:left,2:right),space +; +; if (left >= right) +; return; +; + lda right ;if one or two elements do nothing + jmi exit + cmp left + jcc exit +; +; swap(v, left, (left + right)/2); +; + lda left + asl a + asl a + sta idx1 + tay + lda [sv],y + sta ptr1 + iny + iny + lda [sv],y + sta ptr1+2 + add2 left,right,@a + lsr a + asl a + asl a + tay + lda [sv],y + sta ptr2 + lda ptr1 + sta [sv],y + iny + iny + lda [sv],y + sta ptr2+2 + lda ptr1+2 + sta [sv],y + ldy idx1 + lda ptr2 + sta [sv],y + iny + iny + lda ptr2+2 + sta [sv],y +; +; last = left; +; + lda left + sta last + + asl a + asl a + tay + lda [sv],y + sta vleft + iny + iny + lda [sv],y + sta vleft+2 +; +; for (i=left+1; i <=right; i++) +; + lda left + inc a + sta i +forloop lda i + cmp right + beq okloop + bcs endloop +okloop anop +; +; if (strcmp(v[i],v[left]) < 0) +; + asl a + asl a + tay + lda [sv],y + tax + iny + iny + lda [sv],y + pha + phx + pei (vleft+2) + pei (vleft) + jsr cmpcstr + bpl nextloop +; +; swap (v, ++last, i) +; + inc last + lda last + asl a + asl a + sta idx1 + tay + lda [sv],y + sta ptr1 + iny + iny + lda [sv],y + sta ptr1+2 + lda i + asl a + asl a + tay + lda [sv],y + sta ptr2 + lda ptr1 + sta [sv],y + iny + iny + lda [sv],y + sta ptr2+2 + lda ptr1+2 + sta [sv],y + ldy idx1 + lda ptr2 + sta [sv],y + iny + iny + lda ptr2+2 + sta [sv],y + +nextloop inc i + jmp forloop +; +; swap(v, left, last) +; +endloop lda left + asl a + asl a + sta idx1 + tay + lda [sv],y + sta ptr1 + iny + iny + lda [sv],y + sta ptr1+2 + lda last + asl a + asl a + tay + lda [sv],y + sta ptr2 + lda ptr1 + sta [sv],y + iny + iny + lda [sv],y + sta ptr2+2 + lda ptr1+2 + sta [sv],y + ldy idx1 + lda ptr2 + sta [sv],y + iny + iny + lda ptr2+2 + sta [sv],y +; +; qsort(v, left, last-1) +; + pei (sv+2) + pei (sv) + pei (left) + lda last + dec a + pha + jsl _qsort +; +; qsort(v, last+1, right) +; + pei (sv+2) + pei (sv) + lda last + inc a + pha + pei (right) + jsl _qsort + +exit return + + END diff --git a/bin/gsh/term.asm b/bin/gsh/term.asm new file mode 100644 index 0000000..1816a1d --- /dev/null +++ b/bin/gsh/term.asm @@ -0,0 +1,485 @@ +************************************************************************** +* +* The GNO Shell Project +* +* Developed by: +* Jawaid Bazyar +* Tim Meekins +* +************************************************************************** +* +* TERM.ASM +* By Tim Meekins +* +* Routines for dealing with Termcap under gsh. +* +************************************************************************** + + keep o/term + mcopy m/term.mac + +TIOCGETP gequ $40067408 + +************************************************************************** +* +* Initialize the system for termcap - checks to see if $TERM exists +* and is set, if not, sets to GNOCON +* +************************************************************************** + +InitTerm START + + using termdata + + Set_Variable setparm + Export expparm + ph4 #1024 + jsl ~NEW + sta bp + stx bp+2 + ph4 #1024 + jsl ~NEW + sta areabuf + stx areabuf+2 + rts + +setparm dc i4'termname' ;default term type + dc i4'termval' + +expparm dc i4'termname' + dc i2'1' + +termname str 'term' +termval str 'gnocon' + + END + +************************************************************************** +* +* read new temcap information +* +************************************************************************** + +readterm START + + using termdata + +backward_char equ 3 +forward_char equ 4 +up_history equ 5 +down_history equ 6 + + lda #1 + sta didReadTerm + + ph4 #termname + jsl getenv + phx + pha + tgetent (bp,@xa) ;xa is pushed first + beq noentry + dec a + beq ok + + jsl nullfree + stz termok + ldx #^error1 + lda #error1 + jmp errputs + +noentry jsl nullfree + stz termok + ldx #^error2 + lda #error2 + jsr errputs + ph4 #termname + jsl getenv + jsr errputs + lda #13 + jmp errputchar + +ok jsl nullfree + lda #1 + sta termok + mv4 areabuf,area + + tgetstr (#isid,#area) + jsr puts + tgetstr (#leid,#area) + sta lecap + stx lecap+2 + tgetstr (#ndid,#area) + sta ndcap + stx ndcap+2 + tgetstr (#veid,#area) + sta vecap + stx vecap+2 + tgetstr (#viid,#area) + sta vicap + stx vicap+2 + tgetstr (#vsid,#area) + sta vscap + stx vscap+2 + tgetstr (#blid,#area) + sta blcap + stx blcap+2 + tgetstr (#clid,#area) + sta clcap + stx clcap+2 + tgetstr (#soid,#area) + sta socap + stx socap+2 + tgetstr (#seid,#area) + sta secap + stx secap+2 + tgetstr (#cdid,#area) + sta cdcap + stx cdcap+2 + tgetstr (#ueid,#area) + sta uecap + stx uecap+2 + tgetstr (#usid,#area) + sta uscap + stx uscap+2 + + tgetstr (#klid,#area) + phx + pha + ph2 #backward_char + jsl bindkeyfunc + tgetstr (#krid,#area) + phx + pha + ph2 #forward_char + jsl bindkeyfunc + tgetstr (#kuid,#area) + phx + pha + ph2 #up_history + jsl bindkeyfunc + tgetstr (#kdid,#area) + phx + pha + ph2 #down_history + jsl bindkeyfunc + +; the following is VERY important. It doesn't seem so, but I actually tested +; a terminal that dropped characters w/o it. + + ioctl (#1,#TIOCGETP,#sgtty) + lda sg_ospeed ;let termcap know our speed + case on + sta >ospeed + case off + + rts + +termname dc c'term',h'00' +error1 dc c'Error reading termcap file!',h'0d0d00' +error2 dc c'Termcap entry not found for ',h'00' +isid dc c'is',h'00' +leid dc c'le',h'00' +ndid dc c'nd',h'00' +veid dc c've',h'00' +viid dc c'vi',h'00' +vsid dc c'vs',h'00' +blid dc c'bl',h'00' +clid dc c'cl',h'00' +soid dc c'so',h'00' +seid dc c'se',h'00' +klid dc c'kl',h'00' +krid dc c'kr',h'00' +kuid dc c'ku',h'00' +kdid dc c'kd',h'00' +cdid dc c'cd',h'00' +ueid dc c'ue',h'00' +usid dc c'us',h'00' + +sgtty anop + dc i1'0' +sg_ospeed dc i1'0' + dc i1'0' + dc i1'0' +sg_flags dc i2'0' + END + +************************************************************************** +* +* outc for outputting characters by termcap +* +************************************************************************** + +outc START + +space equ 0 + + subroutine (2:char),space + + lda char + jsr putchar + + return + + END + +************************************************************************** +* +* move left x characters +* +************************************************************************** + +moveleft START + + using termdata + + lda termok + beq done + +loop dex + bmi done + phx + tputs (lecap,#0,#outc) + plx + bra loop + +done rts + + END + +************************************************************************** +* +* move right x characters +* +************************************************************************** + +moveright START + + using termdata + + lda termok + beq done + +loop dex + bmi done + phx + tputs (ndcap,#0,#outc) + plx + bra loop + +done rts + + END + +************************************************************************** +* +* cursor off +* +************************************************************************** + +cursoroff START + + using termdata + + lda termok + beq done + lda vicap + ldx vicap+2 + jmp puts +done rts + + END + +************************************************************************** +* +* cursor on +* +************************************************************************** + +cursoron START + + using termdata + + lda termok + beq done + lda insertflag + beq dovs + + lda vecap + ldx vecap+2 + jmp puts + +dovs lda vscap + ldx vscap+2 + jmp puts +done rts + + END + +************************************************************************** +* +* Beep the bell if it's ok. +* +************************************************************************** + +beep START + + using vardata + using termdata + + lda varnobeep + bne beepdone + lda termok + beq beepdone + tputs (blcap,#0,#outc) +beepdone rts + + END + +************************************************************************** +* +* clear the screen +* +************************************************************************** + +clearscrn START + + using termdata + + lda termok + beq done + tputs (clcap,#0,#outc) +done rts + + END + +************************************************************************** +* +* begin standout mode +* +************************************************************************** + +standout START + + using termdata + + lda termok + beq done + + tputs (socap,#0,#outc) + +done rts + + END + +************************************************************************** +* +* end standout mode +* +************************************************************************** + +standend START + + using termdata + + lda termok + beq done + + tputs (secap,#0,#outc) + +done rts + + END + +************************************************************************** +* +* begin underline mode +* +************************************************************************** + +underline START + + using termdata + + lda termok + beq done + + tputs (uscap,#0,#outc) + +done rts + + END + +************************************************************************** +* +* end underline mode +* +************************************************************************** + +underend START + + using termdata + + lda termok + beq done + + tputs (uecap,#0,#outc) + +done rts + + END + +************************************************************************** +* +* TSET: builtin command +* syntax: tset +* +* reset the termcap for gsh +* +************************************************************************** + +tset START + + using global + +space equ 0 + + subroutine (4:argv,2:argc),space + + jsr readterm + + return + + END + +************************************************************************** +* +* termcap data +* +************************************************************************** + +termdata DATA + +didReadTerm dc i2'0' + +termok dc i2'0' +insertflag dc i2'1' + +bp ds 4 +areabuf ds 4 +area ds 4 + +blcap ds 4 +cdcap ds 4 +clcap ds 4 +lecap ds 4 +ndcap ds 4 +secap ds 4 +socap ds 4 +uecap ds 4 +uscap ds 4 +vecap ds 4 +vicap ds 4 +vscap ds 4 + + END + diff --git a/bin/gsh/tests/history b/bin/gsh/tests/history new file mode 100644 index 0000000..8e27d58 --- /dev/null +++ b/bin/gsh/tests/history @@ -0,0 +1,4 @@ +set term=gno +ls +ls -l >.null & +ls diff --git a/bin/gsh/tests/test b/bin/gsh/tests/test new file mode 100644 index 0000000..3904501 --- /dev/null +++ b/bin/gsh/tests/test @@ -0,0 +1 @@ +/bin/ls diff --git a/bin/gsh/tests/testscr b/bin/gsh/tests/testscr new file mode 100644 index 0000000..127d772 --- /dev/null +++ b/bin/gsh/tests/testscr @@ -0,0 +1,2 @@ +echo "hi there!" +ls g*