home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Transactor
/
Transactor_27_1988_Transactor_Publishing.d64
/
shellram.sda
/
SHELLMAIN.A
< prev
next >
Wrap
Text File
|
2023-02-26
|
7KB
|
497 lines
;
; shellram
;
; By: Adrian Pepper
; Toronto, Ontario
;
; based on, but heavily modified from
; the Pro-Line/Spinnaker
; C POWER/POWER C shell for the
; Commodore 64 home computer.
;
; The shell was modified to reduce
; the size of the code, and arrange
; things so memory page 22 (hex $16)
; will be free for use as a "RAMdisk
; Interface Page", for use with the
; Commodore 1764 256K RAM expander
; for the Commodore 64
;
; This (basically) allows all programs
; designed to run under the shell to
; operate with the RAM disk
;
;
; shellmain.a - main loop, plus
; startup, initialization, nmi
; handling
;
;
; shell data setup
;
.ref usrprog
.ref sysdev
.ref sysdrv
.ref wrkdev
.ref wrkdrv
.ref stdinfl
.ref stdoufl
.ref argstk
;
; kernal routines, etc
;
.ref cint
.ref ioint
.ref setlfs
.ref setnam
.ref open
.ref close
.ref chkin
.ref chkout
.ref clrchn
.ref chrin
.ref chrout
.ref stop
;
.ref nmivec
;
charclr=$0286
scrbase=$0288
;
; =$0801 - link at -s $0801
;
.byte $0c,$08 ;link to next basic statement
.byte $0a,$00 ;line number 10
.byte $9e,$20,'2,'0,'6,'2 ; sys 2062
.byte 0,0,0 ; end of basic program
;
.def c$start
.def savnmi
.def outchr
.def outln
.def clrstdo
.def kwrkfil
.def ksysfil
.def filcls
.def opnwrk
.def opnsys
;
kwrkfil = 16
ksysfil = 15
;
.ref dprintf
.ref dsprint
.ref dfprint
.ref c$getchar
.ref c$funct{CBM-@}init
.ref c$1102
.ref c$2102
.ref cmdlbuf
.ref curcmdn
.ref argv
;
.ref srchcmd
.ref strout
.ref strechn
.ref doload
.ref ostdin
.ref ostdout
.ref oprout
;
; vectors to C library routines
;
; these are necessary for C programs
; to work
;
init jmp dinit
jmp c$1102
jmp c$funct{CBM-@}init
jmp dprintf
jmp dfprint
jmp dsprint
jmp c$getchar
jmp c$2102
;
dinit lda nmivec
sta savnmi
lda nmivec+1
sta savnmi+1
tsx
stx savsp
lda #12
sta $d020
lda #15
sta $d021
lda #0
sta charclr
lda #8
sta sysdev
sta wrkdev
lda #1
sta sysdrv
lda #0
sta wrkdrv
sta cmdlbuf+81
sta vintcnt
sta curcmdn
;
;
; we come back here after interrupting
; a C program because of STOP/RESTORE
;
intrein lda #$0d
jsr chrout
lda #<inthdl
sta nmivec
lda #>inthdl
sta nmivec+1
lda $d018
ora #$02
sta $d018
lda #<kwrkfil
jsr close
jsr opnwrk
mainlp = *
jsr filcls
ldx sysdev
jsr opnsys
jsr shprmpt
jsr shgetln
jsr shexeln
jmp mainlp
;
filcls jsr clrchn
ldx #15
t0080b txa
pha
jsr close
pla
tax
dex
bne t0080b
rts
;
;
; shprompt - prompt user for command line
;
shprmpt lda #'%
jsr chrout
lda #$20
jmp chrout
;
;
; shgetln - read command line from screen
;
shgetln ldy #0
t0005b jsr chrin
cmp #$0d
beq t0020f
cmp #'a ; ignore non-alphabetics at start of line
bcc t0005b
cmp #1+'z
bcs t0005b
t0010b cmp #$0d ; copy line up to a new line character
beq t0020f
sta cmdlbuf,y
jsr chrin
iny
bne t0010b
t0020f = *
jsr chrout
lda #0
sta cmdlbuf,y
rts
;
;
; this is where we handle nmi interrupts
; this allows STOP/Restore to break
; a looping C program
;
inthdl pha
lda vintcnt
beq t0050f
pla ; ignore redundant interrupts
rti
t0050f txa ; save regs
pha
tya
pha
lda #$7f
sta $dd0d
ldy $dd0d
bpl t0060f
jmp $fe72
t0060f jsr stop
beq t0070f
jmp $fe72
t0070f inc vintcnt
lda $1
ora #$07
sta $1
lda #$04
sta scrbase
lda charclr
pha
lda $d020
pha
lda $d021
pha
jsr ioint ; too bad this clears screen!
jsr cint
pla
sta $d021
pla
sta $d020
pla
sta charclr
ldx savsp
txs
cli
dec vintcnt
jmp intrein
;
savnmi .bss 2
savsp .bss 1
vintcnt .bss 1
;
;
; shexeln - interpret/execute a line
;
shexeln ldy #0
sty $29 ; arg count
sty stdinfl
sty stdoufl
ldx #$ff
;
shexlp inx
lda cmdlbuf,x
bne t0690f
jmp shexend
t0690f cmp #$20
beq t0700f
cmp #$a0
t0700f beq shexlp
;
cmp #'< ; check for input redirection
bne t0720f
jsr ostdin
bcc t0710f
ldx #<scnopni
ldy #>scnopni
jmp strout ; and return
t0710f jmp shexlp
;
t0720f cmp #'> ; check for output redirection
bne t0760f
inx
lda cmdlbuf,x
;
cmp #'> ; >> means redirect out to printer
bne t0740f
jsr oprout
bcc t0730f
ldx #<sprtrnp
ldy #>sprtrnp
jmp strout ; and return
t0730f jmp shexlp
;
t0740f dex
jsr ostdout
bcc t0750f
ldx #<scnopno
ldy #>scnopno
jmp strout ; and return
;
t0750f jmp shexlp
;
t0760f inc $29 ; got an arg
cmp #'"
bne t0780f
inx ; save an arg enclosed in '"'
jsr savargv
dex
t0770b inx
lda cmdlbuf,x
beq shexend
cmp #'"
bne t0770b
lda #0
sta cmdlbuf,x
jmp shexlp
;
t0780f jsr savargv
t0790b inx ; save a normal arg
lda cmdlbuf,x
beq shexend
cmp #$20
beq t0800f
cmp #$a0
t0800f bne t0790b
lda #0
sta cmdlbuf,x
jmp shexlp
;
shexend lda $29
bne t0810f
rts
;
t0810f = *
t0850f jsr srchcmd ; look for internal command
bcc t0860f ;; found internal command
ldx #<cmdlbuf ; otherwise, try and load a C program
ldy #>cmdlbuf
jsr doload
bcs t0860f
jsr execmd ; execute C program if it was loaded okay
t0860f rts
;
; strings for open failures
;
scnopni .byte "can't open input file"
.byte $0d,0
scnopno .byte "can't open output file"
.byte $0d,0
sprtrnp .byte "printer not present"
.byte $0d,0
;
; execmd - call a c program
; which has already been loaded at $2000
;
execmd lda #<ksysfil
jsr close
lda $29
sta argstk
lda #0
sta argstk+1
lda #<argv
sta argstk+2
lda #>argv
sta argstk+3
lda charclr
sta savcclr
lda $d020
sta savbclr
lda $d021
sta savsclr
;
jsr usrprog
;
lda savbclr
sta $d020
lda savsclr
sta $d021
lda savcclr
sta charclr
ldx #$d8
ldy #0
sty $2a
t0900b stx $2b
t0910b sta ($2a),y
iny
bne t0910b
inx
cpx #$dc
bne t0900b
rts
;
savcclr .bss 1
savbclr .bss 1
savsclr .bss 1
;
; savargv - save address of current arg
; into argv vector for command
;
savargv clc
txa
adc #<cmdlbuf ; add x to &cmdlbuf
sta argv,y
iny
lda #$00
adc #>cmdlbuf
sta argv,y
iny
rts
;
;
; opnsys - open a command channel for
; the system (or another) device
; Should be closed before calling user
; program, but not before "ls"
;
opnsys cpx wrkdev
bne t1000f
clc ; assume success
rts
t1000f stx savdev
lda #<ksysfil
jsr close
ldx savdev
lda #<ksysfil
bne t1010f ;; try the open
;
;
; opnwrk - open a command channel for
; the work device
; Should be opened and closed once per
; command line only
;
opnwrk lda #<kwrkfil
ldx wrkdev
t1010f stx savdev
ldy #15 ;
jsr setlfs
lda #m$rlen
ldx #<sm$r
ldy #>sm$r
jsr setnam
jsr open ;; open tcmdfil,x,15,"m-r"
bcs t1020f ;; no device
ldx savdev
jsr strechn ;; read, but ignore, error
clc
t1020f rts ;; and return -- sec on error
sm$r .byte "m-r"
m$rlen = *-sm$r
savdev .bss 1
;
;
;
; outchr - output char (in a)
; to stdout
; not for user commands, since
; argstk used as buffer
;
stdoutx .bss 1
;
outchr stx vdolc
ldx stdoutx
sta argstk,x
inc stdoutx
cmp #$0d
beq outln
ldx vdolc
rts
outln lda stdoufl
beq t1130f
jsr clrchn
ldx #2
jsr chkout
t1130f ldx #0
t1140b cpx stdoutx
beq t1150f
lda argstk,x
jsr chrout
inx
bne t1140b
t1150f lda stdoufl
beq t1160f
jsr clrchn
ldx #4
jsr chkin
;
.ref vdolc
t1160f ldx vdolc
clrstdo lda #0
sta stdoutx
rts