This commit is contained in:
mgcaret 2017-09-15 09:55:29 -07:00
commit d9b665d62a
21 changed files with 4894 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
*.o
*.p8c
*.lst
*.map
*.po
*.SHK
*.shk
help
test

49
Makefile Executable file
View File

@ -0,0 +1,49 @@
DAVEX=../davex-code/src
ACMD=java -jar ~/bin/AppleCommander-1.3.5-ac.jar
NULIB2=nulib2
BOOTDSK=~/vii_hd.2mg
CA65=ca65
LD65=utils/auto_origin.sh ld65
GENHELP=utils/gen_help.sh
MG_CMDS=at.info.p8c at.zones.p8c afp.userprefix.p8c afp.sessions.p8c alias.p8c at.boot.p8c deschw.p8c dmem.p8c nbp.lookup.p8c tardis.p8c nbp.parse.p8c iie.card.p8c idemu.p8c mig.insp.p8c
.PHONY: all
all: shk ;
.phony: shk
shk: DAVEX.MG.SHK ;
.phony: disk
disk: davex.mg.po ;
davex.mg.po: $(MG_CMDS)
$(ACMD) -pro140 davex.mg.po DAVEX.MG
set -x; for CMD in $(MG_CMDS); do $(ACMD) -p davex.mg.po $${CMD%.*} 'BIN' '0x8001' < $$CMD; done
#set -x; for HLP in help/*; do $(ACMD) -p davex.mg.po $$HLP 'TXT' < $$HLP; done
# Adjust for your emulation scenario
emulate: davex.mg.po
open $(BOOTDSK) davex.mg.po -a 'Virtual ]['
DAVEX.MG.SHK: $(MG_CMDS)
rm -f DAVEX.MG.SHK
set -x; for CMD in $(MG_CMDS); do cp -p $$CMD "$${CMD%.*}#2E8001"; done
$(NULIB2) -ae DAVEX.MG.SHK *2E8001
rm -f *2E8001
set -x; for HLP in help/*; do cp -p $$HLP "$$HLP#040000"; done
$(NULIB2) -ae DAVEX.MG.SHK help/*040000
rm -f help/*040000
ls -l DAVEX.MG.SHK
%.p8c: %.o
${LD65} -t none -m $@.map -o $@ $<
%.o: %.s
$(CA65) --include-dir $(DAVEX) -l $@.lst -o $@ $<
mkdir -p help; FILE="$<"; $(GENHELP) $< "help/$${FILE%.*}"
.PHONY: clean
clean:
rm -f *.o *.p8c *.lst *.map davex.mg.po DAVEX.MG.SHK help/*
rmdir help

108
README.md Normal file
View File

@ -0,0 +1,108 @@
# MG's DaveX Utilities
This is a collection utilities for [davex](https://sourceforge.net/p/davex/home/Home/), mostly centered around AppleTalk, but also a few others including fixed or enhanced versions of a few existing davex.
## Utilities
See the source or generated help files for each utility, for further information/options/etc.
### AppleTalk
#### afp.sessions
Displays AFP sessions.
#### afp.userprefix
Print or set the AFP user prefix.
#### at.boot
Boots over Appletalk.
#### at.info
Display some AppleTalk info
#### at.zones
Display AppleTalk zone information.
#### nbp.lookup
Look up NBP names registered on the network.
#### nbp.parse
Parse an NBP name and display the parts. Mainly used for testing the parsing routine.
#### tardis
Get time from TimeLord server.
### Fixed/Enhanced
#### alias
This is a fixed version of the alias command included in davex 1.30p.
#### deschw
This has been enhanced to identify the CPU and to detect emulation. If an emulator supporting EMUBYTE is found, displays its name and version if known.
See idemu for more comprehensive emulator detection.
There are also a few other enhancements around SmartPort device info.
### Misc
#### dmem
Displays info on davex "dynamic memory." Mainly for testing purposes.
#### idemu
Identifies emulators. If a positive ID on EMUBYTE can be used, uses it. Otherwise, attempts to use the various emulators' idiosynchracies regarding emulator ROM and I/O space to make the identification. It does not interact with any slot hardware.
#### iie.card
Display or change the speed of the 65C02 on the Apple //e Card for Macintosh LC.
Optionally, use undocumented features to display the user-selected startup slot.
#### mig.insp
View the contents of the Apple IIc Plus MIG RAM.
## Building
Building the utilities requires a Unix-like environment with GNU Make and the usual set of Unix utilities such as sed, awk, egrep, etc.
A working installtion of cc65 must be present and in the PATH (for ca65, ld65, od65).
The davex source code (link at top) must be present somewhere, and the DAVEX variable in the Makefile should point to it.
In order to build the default target (a ShrinkIt file), nulib2 must be present and in the PATH.
In order to build a disk image, you must have AppleCommander CLI version set up and must modify the Makefile.
The utilities are developed on macOS X.
### Interesting make targets
* ``all``: build shrinkit file DAVEX.MG.SHK
* ``disk``: build davex.mg.po
* ``emulate``: builds disk and attempts to open with Virtual ][. Set BOOTDSK in Makefile first.
## Developing
Fork it, send pull requests, etc.
I created a custom set of macros and tools for doing davex external commands. These are in ``davex-mg.inc`` and in the ``utils`` directory.
In particular, the macros along with ``utils/auto_origin.sh`` allow automatically meeting the davex external command loading recommendations, which are "load on a page boundary so that the end of the file loads between $AF00 and $AFFF."
Additionaly, ``utils/gen_help.sh`` is used to extract the help file contents from the source code of each utility.

169
afp.sessions.s Normal file
View File

@ -0,0 +1,169 @@
; %help
; afp.sessions - Display AFP sessions.
; %hend
.pc02
.include "davex-mg.inc"
sptr = xczpage
altbuf = filebuff3 ; if no dynamic mem avail
altbufsz = $04 ; pages
DX_start dx_mg_auto_origin ; load address
DX_info $01,$12,dx_cc_iie_or_iigs,$00
DX_ptab
DX_end_ptab
DX_desc "Display AFP sessions."
DX_main
cli ; appletalk requires interrupts
ATcall inforeq
bcc :+
jmp noatalk
: jsr getatbuf
sta bufp+1
sty bufp
stx buflen+1
ATcall filsess
bcs nosess1
lda nument ; number of entries returned
bne :+
jsr xmess
asc_hi "No sessions."
.byte $8d,$00
nosess1: jmp nosess
: lda bufp+1
sta sptr+1
lda bufp
sta sptr
jsr xmess
asc_hi " session vol id dev volume name (* = user volume)"
.byte $8d
asc_hi " ------- ------ --- --------------------------------"
.byte $8d,$00
; loop to display sessions
dispsess: ldy #$00
sty num+1
sty num+2
lda (sptr),y ; ref num
sta num
jsr xprdec_pad
lda #' '+$80
jsr cout
ldy #$1e ; offset of volume id
lda (sptr),y
sta num
iny
lda (sptr),y
sta num
jsr xprdec_pad
lda #' '+$80
jsr cout
ldy #$01 ; offset of devnum
lda (sptr),y
pha
jsr xprint_sd
lda #' '+$80
jsr cout
pla
and #$01 ; isolate user volume flag
beq notuser
lda #'*'+$80
bne :+
notuser: lda #' '+$80
: jsr cout
lda sptr+1
pha ; save sptr
lda sptr
pha
lda #$02 ; offset to volume name
jsr addsptr
jsr prpas
lda #$8d
jsr cout
pla ; restore sptr to where it was
sta sptr
pla
sta sptr+1
lda #$20 ; size of entry
jsr addsptr ; now point at next entry
jsr xcheck_wait ; see if should pause or quit
bcs nosess ; quit if esc pressed
dec nument
bne dispsess
nosess: ;ldx mli_close ; free mem
;jsr xmmgr ; do it
rts
noatalk: lda #$01
jsr xredirect
jsr xmess
asc_hi "AppleTalk offline!"
.byte $00
exiterr: lda #$ff
jsr xredirect
jmp xerr
;
; increment sptr by a
.proc addsptr
clc
adc sptr
sta sptr
bcc :+
inc sptr+1
: rts
.endproc
; print pascal string at sptr
; leave sptr pointed at one past end
; of string
.proc prpas
ldy #$00
lda (sptr),y ; get length
tax
next: lda #$01
jsr addsptr
dex
bpl :+
rts
: lda (sptr),y ; get char
ora #$80 ; make printable
jsr cout
bra next
.endproc
; allocate a big buffer for appletalk operations
; returns ay = start, x = size in pages
; tries to use dynamic mem for operations
; otherwise returns altbuf
.proc getatbuf
ldx #mli_read
jsr xmmgr
bcs usealt
cmp #altbufsz
bcc usealt
sta tmp ; save num pages
ldx #mli_open
jsr xmmgr ; allocate all
bcc usealt ; if error
ldx tmp ; get num pages
ldy #$00 ; always on page boundary
rts
usealt: ldy #<altbuf
lda #>altbuf
ldx altbufsz
rts
tmp: .byte $00
.endproc
;
inforeq: .byte 0,2 ; sync GetInfo
.word $0000 ; result code
.dword $00000000 ; completion address
thisnet: .word $0000 ; this network #
abridge: .byte $00 ; local bridge
hwid: .byte $00 ; hardware ID, IIgs only
romver: .word $00 ; ROM version, IIgs only
nodenum: .byte $00 ; node number
;
filsess: .byte 0,$2f ; sync FIListSessions
.word $0000 ; result code
buflen: .word altbufsz*$100 ; buffer length
bufp: .dword altbuf ; buffer pointer
nument: .byte $00 ; entries returned
DX_end

177
afp.userprefix.s Normal file
View File

@ -0,0 +1,177 @@
; %help
; afp.userprefix - Display or set the AFP user prefix.
;
; options: -s <path> Set to <path>, normally only if not already set.
; -f Force setting even if it is already set.
; -c Set current prefix to user prefix.
;
; Note that setting the user prefix uses undocumented features of the
; AppleTalk stack.
; %hend
.pc02
.include "davex-mg.inc"
sptr = xczpage
setflag = sptr+2
pfxbuf = filebuff2
DX_start dx_mg_auto_origin ; load address
DX_info $01,$12,dx_cc_iie_or_iigs,$00
DX_ptab
DX_parm 's',t_path ; path to set
DX_parm 'f',t_nil ; force setting
DX_parm 'c',t_nil ; set prefix
DX_end_ptab
DX_desc "Display or set AFP User Prefix."
DX_main
cli ; appletalk requires interrupts
ATcall inforeq
bcc :+
jmp noatalk
: stz setflag
lda #'s'|$80
jsr xgetparm_ch
bcs :+ ; set not requested
inc setflag
: lda #'f'|$80
jsr xgetparm_ch
bcs getit ; not being forced to set
lda setflag
beq :+ ; user said -f without -s, go to error
jmp setpfx ; -s and -f, set prefix
: lda #$01
jsr xredirect
jsr xmess
asc_hi "-f without -s!"
.byte $00
bra exiterr
getit: stz dirflag ; make sure we are getting, not setting
ATcall pfxreq ; get user prefix
bcc :+ ; if no error
lda setflag ; error, see if we should try setting it?
beq pfxerr ; nope, error out
bra tryset ; otherwise, try setting
: lda #<pfxbuf ; set sptr to prefix buffer
sta sptr
lda #>pfxbuf
sta sptr+1
ldy #$00 ; index of length byte
lda (sptr),y ; check length
beq :+ ; no prefix, see if we should set it
stz setflag ; have a prefix already, so flag don't set
jsr prpas ; and print
: lda setflag ; user wants prefix set?
beq :+ ; no, so skip doing it
tryset: jmp setpfx ; go to the set routine
: lda #'c'|$80
jsr xgetparm_ch ; change to wanted?
bcs :+ ; nope, skip to the end
P8call $c6,p8pfxreq ; enact the change
bcc :+ ; all good, skip error
jmp xProDOS_err ; if something went pear-shaped
: rts ; buhbye
pfxerr: lda #$01
jsr xredirect
jsr xmess
asc_hi "Get/set user prefix error!"
.byte $00
bra exiterr
noatalk: lda #$01
jsr xredirect
jsr xmess
asc_hi "AppleTalk offline!"
.byte $00
exiterr: lda #$ff
jsr xredirect
jmp xerr
;
setpfx: lda #'s'|$80 ; get the pointer to option
jsr xgetparm_ch
bcs badpath ; shouldn't happen here!!!
sty sptr ; set sptr to check length
sty parm1 ; and parm1 for copy
sta sptr+1
sta parm1+1
lda (sptr),y ; check length
beq badpath ; and if zero, it must be bad
jsr xpmgr ; copy from user option to pfxbuf
.byte pm_copy ; davex function
parm1: .addr pfxbuf ; source, initially something not entirely insane
.addr pfxbuf ; destination
P8call $c4,fileinfo ; P8 GET_FILE_INFO
bcc :+ ; no error, continue
jmp xProDOS_err ; something went pear-shaped
: lda fitype ; get file type
cmp #$0f ; is directory?
bne badpath ; nope... error out
lda #$aa ; undocumented, found in LOGON program
sta dirflag
ATcall pfxreq ; set user prefix
bcc :+ ; all good, skip error
jmp pfxerr ; sigh... error out
: stz setflag ; avoid infinite loop
jmp getit ; wind back to get/print/maybe change dir
badpath: lda #$01
jsr xredirect
jsr xmess
asc_hi "Bad new prefix!"
.byte $00
bra exiterr
; increment sptr by a
.proc addsptr
clc
adc sptr
sta sptr
bcc :+
inc sptr+1
: rts
.endproc
; print pascal string at sptr
; leave sptr pointed at one past end
; of string
.proc prpas
ldy #$00
lda (sptr),y ; get length
tax
next: lda #$01
jsr addsptr
dex
bpl :+
rts
: lda (sptr),y ; get char
ora #$80 ; make printable
jsr cout
bra next
.endproc
;
inforeq: .byte 0,2 ; sync GetInfo
.word $0000 ; result code
.dword $00000000 ; completion address
thisnet: .word $0000 ; this network #
abridge: .byte $00 ; local bridge
hwid: .byte $00 ; hardware ID, IIgs only
romver: .word $00 ; ROM version, IIgs only
nodenum: .byte $00 ; node number
;
pfxreq: .byte 0,$2a ; sync FIUserPrefix
.word $0000 ; result
dirflag: .byte $00 ; direction flag (bit 7)
.dword pfxbuf ; buffer (at least 64 bytes)
;
p8pfxreq: .byte $01
.addr pfxbuf
;
fileinfo: .byte $0a
.addr pfxbuf ; buffer
.byte $00 ; access
fitype: .byte $00 ; want to see $0f
.word $0000 ; aux type
.byte $00 ; storage type
.word $0000 ; blocks used
.word $0000 ; mod date
.word $0000 ; mod time
.word $0000 ; create date
.word $0000 ; create time
DX_end

581
alias.s Normal file
View File

@ -0,0 +1,581 @@
;*************************************************
;*************************************************
;
; 'alias' -- external command for Davex
;
; alias -- view and modify Davex aliases
;
; alias [-s] [-l] [-r] <str1> <str2>
;
; alias displays all aliases
; alias <a> <b> adds alias
; alias -r <a> removes alias <a>
; alias -s saves aliases to %aliases
; alias -l loads aliases from %aliases
;
;*************************************************
;
; Converted to MPW IIgs 20-Sep-92 DAL
;
; Fixed from the 1.30P version on SourceForge 26-Jul-17 MG
;
;*************************************************
;.segment "CODE_A000"
OrgAdr = $A000 ;change as necessary (end below $B000)
.org OrgAdr ; Makes the listing more readable, though it doesn't really org the code - the linker does that.
.include "Common/2/Globals2.asm"
.include "Common/2/Apple.Globals2.asm"
.include "Common/2/Mli.Globals2.asm"
.include "Common/Macros.asm"
;include 'm16.util2'
low_cr = $0D
;
MyVersion = $09
MinVersion = $12
MinVerAux = $05
;*************************************************
rts
.byte $ee,$ee
.byte MyVersion,MinVersion
.byte %00000000 ;hardware req
.addr descr
.addr OrgAdr
.addr start
.byte MinVerAux,0,0,0
; parameters here
.byte 0,t_string
.byte 0,t_string
.byte $80+'r',t_nil
.byte $80+'s',t_nil
.byte $80+'l',t_nil
.byte 0,0
descr:
pstr "display or modify command aliases"
;*************************************************
; dum xczpage ;32 locations
AliasPages = xczpage
AliasP = AliasPages+1
AliasEnd = AliasP+2
myP = AliasEnd+2
str1 = myP+2
str2 = str1+2
char = str2+2
count = char+1 ;.res 2
; dend
;
start = *
sta str1+1
sty str1
lda #1
jsr xgetparm_n
sta str2+1
sty str2
ldx #1
jsr xshell_info
sta AliasP+1
sty AliasP
sty AliasEnd
stx AliasPages
txa
clc
adc AliasP+1
sta AliasEnd+1
lda #$80+'l'
jsr xgetparm_ch
bcs noLoad
jsr load_aliases
noLoad:
jsr DoAlias
lda #$80+'s'
jsr xgetparm_ch
bcs noSave
jsr save_aliases
noSave:
rts
;*************************************************
;
; handle adding, removing, or showing aliases
;
DoAlias:
lda #$80+'r'
jsr xgetparm_ch
bcs noRmv
jmp remove_alias
noRmv:
ldy #0
lda (str1),y
bne doAdd
lda (str2),y
bne doAdd
jsr xgetnump
cmp #2
beq show_aliases
rts
doAdd: jmp add_alias
;*************************************************
;
; Display all the aliases
;
show_aliases:
jsr CalcUsedSize
jsr xprdec_2
jsr xmess
asc_hi " bytes used (of "
.byte 0
lda AliasPages
ldy #0
jsr xprdec_2
jsr xmess
asc_hi ") to store these aliases:"
.byte low_cr
asc_hi " "
.byte 0
;
lda AliasP+1
ldy AliasP
sta myP+1
sty myP
ShowA1: lda (myP),y
beq ShowedA
jsr NeatCout
bcs ShowedA
iny
bne ShowA1
inc myP+1
bne ShowA1
ShowedA: rts
NeatCout: ora #$80
cmp #$8d
beq isCR
jsr cout
clc
rts
isCR: jsr xcheck_wait
bcs isCR2
jsr crout
lda #$80+' '
jsr cout
jsr cout
clc
isCR2: rts
;*************************************************
;
; Save aliases to %aliases file
;
save_aliases:
lda #>AliasName
ldy #<AliasName
jsr xbuild_local
sta aPath+1
sty aPath
sta acPath+1
sty acPath
jsr mli
.byte mli_create
.addr CreateA
bcc CreateOK
cmp #err_dupfil
bne DiskError
CreateOK:
jsr mli
.byte mli_open
.addr OpenA
bcs DiskError
lda aRef
sta aRef2
sta aRef3
sta aRef4
jsr CalcUsedSize
sta WriteA+5
sty WriteA+4
jsr mli
.byte mli_write
.addr WriteA
bcs DiskError
jsr mli
.byte mli_getmark
.addr MarkA
jsr mli
.byte mli_seteof
.addr MarkA
jsr mli
.byte mli_close
.addr CloseA
bcs DiskError
rts
;*************************************************
;
; Load aliases from %aliases file
;
load_aliases:
lda #>AliasName
ldy #<AliasName
jsr xbuild_local
sta aPath+1
sty aPath
jsr mli
.byte mli_open
.addr OpenA
bcs DiskError
lda aRef
sta aRef2
sta aRef3
lda AliasPages
ldy #0
sta ReadA+5
sty ReadA+4
jsr mli
.byte mli_read
.addr WriteA
php
pha
jsr strip7
pla
plp
bcs DiskError
jsr mli
.byte mli_close
.addr CloseA
bcs DiskError
rts
DiskError: jmp xProDOS_err
CreateA: .byte 7
acPath: .addr 0
.byte $C3 ;access
.byte tTXT ;filetype
.addr 0 ;auxtype
.byte 1 ;storage type
.addr 0,0 ;create date/time
OpenA: .byte 3
aPath: .addr 0
.addr filebuff
aRef: .byte 0
ReadA:
WriteA: .byte 4
aRef2: .byte 0
.addr Aliases,$0000,0
MarkA: .byte 2
aRef4: .byte 0
.byte 0,0,0
CloseA: .byte 1
aRef3: .byte 0
AliasName:
.byte 7,"ALIASES"
strip7: lda AliasPages
sta count
lda AliasP+1
ldy AliasP
sta myP+1
sty myP
ldy #0
strip1: lda (myP),y
and #%01111111
sta (myP),y
dey
bne strip1
dec count
bne strip1
rts
;*************************************************
;
; remove an alias
;
remove_alias:
ldy #0
lda (str2),y
beq rmv2ok
jsr xmess
.byte cr
asc_hi "*** too many parameters for removing an alias"
.byte low_cr,0
jmp xerr
rmv2ok:
jsr FindAlias
bcc rmvFound
jsr xmess
.byte cr
asc_hi "*** no such alias found"
.byte low_cr,0
jmp xerr
rmvFound: jsr remove_it
rts
;
; Add an alias, possibly replacing an existing one
;
add_alias:
jsr FindAlias
bcs addMissing
lda #1
jsr xredirect
jsr xmess
asc_hi "Okay to replace existing alias "
.byte $A2,0
lda str1+1
ldy str1
jsr xprint_path
lda #$A2
jsr cout
lda #$80+'n'
jsr xyesno2
php
lda #<-1
jsr xredirect
plp
bne ReplacIt
rts
ReplacIt: jsr remove_it
addMissing:
jsr CalcUsedSize
ldy #0
clc
lda (str1),y
adc (str2),y
adc #3
adc count
lda count+1
adc #0
cmp AliasPages
bcc haveRoom
jsr xmess
.byte cr
asc_hi "*** no room for that alias"
.byte low_cr,0
jmp xerr
haveRoom:
ldy #0
lda (str1),y
tax
bne aNameOK
jsr xmess
.byte cr
asc_hi "*** empty string is not a legal alias"
.byte low_cr,0
jmp xerr
aNameOK: iny
lda (str1),y
jsr CramChar
dex
bne aNameOK
lda #$80+' '
jsr CramChar
ldy #0
lda (str2),y
tax
beq aDefDone
AddDef: iny
lda (str2),y
jsr CramChar
dex
bne AddDef
aDefDone: lda #$0d
jsr CramChar
lda #0
jmp CramChar
;
; CramChar -- append A to (myP)
;
CramChar: sty cramY
ldy #0
sta (myP),y
ldy cramY
inc myP
bne cram_ok
inc myP+1
cram_ok: rts
cramY: .byte 0
;
; FindAlias -- return CLC if found, myP points to it
;
FindAlias:
lda AliasP+1
ldy AliasP
sta myP+1
sty myP
FindA1:
jsr compare
bcc FoundIt
jsr NextAlias
ldy #0
lda (myP),y
bne FindA1
sec
FoundIt: rts
;
; compare--check if alias at myP matches str1, returning
; CLC if they do (and preserving myP)
;
compare:
lda myP+1
pha
lda myP
pha
ldy #0
lda (str1),y
tax
beq NoMatch
iny ;Y=1
jsr decP
cmp1:
lda (str1),y
jsr xdowncase
sta char
jsr FetchChar
and #%01111111
beq NoMatch
jsr xdowncase
cmp char
bne NoMatch
iny
dex
bne cmp1
jsr FetchChar
cmp #$80+' '
bne NoMatch
matches: clc
compared:
pla
sta myP
pla
sta myP+1
rts
NoMatch:
sec
bcs compared
;
; increment myP and return the character it points at
;
FetchChar: inc myP
bne P2ok
inc myP+1
P2ok = *
sty ytemp
ldy #0
lda (myP),y
ldy ytemp
ora #%10000000
rts
ytemp: .res 1
;
; advance myP to next alias
;
NextAlias: jsr FetchChar
cmp #$8d
beq FetchChar
and #%01111111
bne NextAlias
rts
;*************************************************
;
; Remove the alias that myP is pointing at
;
remove_it:
ldy #0
lda (myP),y
beq removed
pha
jsr KillCharP
pla
and #$7f
cmp #$0d
bne remove_it
removed: rts
;
; Kill a character at myP, shifting forward all the
; characters after myP until AliasEnd
;
KillCharP:
lda myP+1
pha
lda myP
pha
KillLoop:
ldy #1
lda (myP),y
dey
sta (myP),y
inc myP
bne p_ok
inc myP+1
p_ok: lda myP+1
cmp AliasEnd+1
bne KillLoop
lda myP
cmp AliasEnd
bne KillLoop
pla
sta myP
pla
sta myP+1
rts
;
; CalcUsedSize--return used bytes in AY,
; myP pointing at the $00 marker at the end
; of the alias data
;
CalcUsedSize:
lda #0
sta count
sta count+1
lda AliasP+1
ldy AliasP
sta myP+1
sty myP
ldy #0
cus1: lda (myP),y
beq cus_done
inc count
bne count_ok
inc count+1
count_ok: inc myP
bne cus1
inc myP+1
bne cus1
cus_done: lda count+1
ldy count
rts
;
decP: lda myP
bne decP1
dec myP+1
decP1: dec myP
rts

47
at.boot.s Normal file
View File

@ -0,0 +1,47 @@
; %help
; at.boot - Boot over AppleTalk.
; %hend
; TODO: If AT is not initialized, then:
; If //e: Find and init workstation card and execute boot if it's not already
; initialized.
; If IIgs: Try Apple IIgs AT boot vectors.
.pc02
.include "davex-mg.inc"
DX_start dx_mg_auto_origin ; load address
DX_info $01,$12,dx_cc_iie_or_iigs,$00
DX_ptab
DX_end_ptab
DX_desc "Reboot over the network."
DX_main
cli ; appletalk requires interrupt
ATcall inforeq
bcs noatalk
ATcall boot
lda #$01
jsr xredirect
jsr xmess
asc_hi "Network boot failed!"
.byte $00
bra errexit
noatalk: lda #$01
jsr xredirect
jsr xmess
asc_hi "AppleTalk offline!"
.byte $00
errexit: lda #$ff
jsr xredirect
jmp xerr
inforeq: .byte 0,2 ; sync GetInfo
.word $0000 ; result code
.dword $00000000 ; completion address
thisnet: .word $0000 ; this network #
abridge: .byte $00 ; local bridge
hwid: .byte $00 ; hardware ID, IIgs only
romver: .word $00 ; ROM version, IIgs only
nodenum: .byte $00 ; node number
boot: .byte $00,$06 ; sync boot
.word $0000 ; result code
DX_end

123
at.info.s Normal file
View File

@ -0,0 +1,123 @@
; %help
; at.info -- Display AppleTalk info.
;
; syntax: at.info
;
; Displays AppleTalk node number, bridge node, and (for IIgs) hardware
; ID and ROM version.
;
; If AppleTalk is offline, will print the slot number of an installed
; Workstation Card.
; %hend
.pc02
.include "davex-mg.inc"
cardptr = xczpage
DX_start $ae00 ; load address
DX_info $01,$12,dx_cc_iie_or_iigs,$00
DX_ptab
DX_end_ptab
DX_desc "Display AppleTalk info."
DX_main
cli ; appletalk requires interrupt
ATcall inforeq
bcs noatalk
lda thisnet
ldy thisnet+1
jsr xprdec_2
jsr xmess
asc_hi "."
.byte $00
lda #$00
ldy nodenum
jsr xprdec_2
ldy abridge
beq :+
phy
jsr xmess
asc_hi ", bridge "
.byte $00
ply
lda #$00
jsr xprdec_2
: lda #$8d
jsr cout
sec
jsr checkmach
bcs :+
; display IIgs specific
jsr xmess
asc_hi "Hardware ID: "
.byte $00
lda #$00
ldy hwid
jsr xprdec_2
jsr xmess
asc_hi ", ROM version "
.byte $00
lda #$00
ldy romver
jsr xprdec_2
lda #$8d
jsr cout
: rts
noatalk: lda #$01
jsr xredirect
jsr xmess
asc_hi "AppleTalk offline!"
.byte $00
jsr FindCard
bcs :+ ; no card
and #$0f ; get slot #
pha
jsr xmess
asc_hi "Workstation Card in slot "
.byte $00
pla
tay
lda #$00
jsr xprdec_2
jsr xmess
.byte $8d,$00
: lda #$ff
jsr xredirect
jmp xerr
.proc FindCard
lda #$f9 ; offset to ID bytes
sta cardptr
lda #$c7 ; start at slot 7
sta cardptr+1
NextSlot: ldy #$03
: lda (cardptr),y
cmp idtbl,y ; check ID byte
bne NoMatch
dey
bpl :-
ldy #$04
lda (cardptr),y
beq NoMatch ; Skip IIgs AppleTalk
cmp #$01 ; Workstation card?
bne NoCard ; nope, something else
clc
lda cardptr+1 ; get slot
rts
NoMatch: dec cardptr+1
lda cardptr+1
cmp #$c0 ;are we finished scanning the slots?
bne NextSlot
NoCard: lda #$00
sec
rts
idtbl: .byte "ATLK" ; msb off
.endproc
inforeq: .byte 0,2 ; sync GetInfo
.word $0000 ; result code
.dword $00000000 ; completion address
thisnet: .word $0000 ; this network #
abridge: .byte $00 ; local bridge
hwid: .byte $00 ; hardware ID, IIgs only
romver: .word $00 ; ROM version, IIgs only
nodenum: .byte $00 ; node number
DX_end

163
at.zones.s Normal file
View File

@ -0,0 +1,163 @@
; %help
; at.zones -- Display AppleTalk zones.
;
; syntax: at.info
;
; Displays local AppleTalk zone and all known zones.
; %hend
.pc02
.include "davex-mg.inc"
sptr = xczpage
altbuf = filebuff3 ; if no dynamic mem avail
altbufsz = $04 ; pages
DX_start dx_mg_auto_origin ; load address
DX_info $01,$12,dx_cc_iie_or_iigs,$00
DX_ptab
DX_end_ptab
DX_desc "Display AppleTalk zones."
DX_main
cli ; appletalk requires interrupts
ATcall inforeq
bcc :+
jmp noatalk
jsr getatbuf ; allocate buffer
sta bufp1+1
sty bufp1
sta bufp2+1
sty bufp2
stx buflen2+1
: lda abridge
sta zbridge ; zone req needs it
ATcall myzone
bcs nozone
lda bufp1+1
sta sptr+1
lda bufp1
sta sptr
ldy #$00
lda (sptr),y
beq nozone
jsr xmess
asc_hi "Local zone: "
.byte $00
jsr prpas
lda #$8d
jsr cout
nozone: ATcall getzones
bcs nozones ; TODO: check for buffer overflow and display what we get
lda numzones+1
ora numzones
beq nozones ; short circuit if no zones
jsr xmess
asc_hi "Zone list:"
.byte $8d,$00
lda bufp2+1 ; set up pointer
sta sptr+1
lda bufp2
sta sptr
przone: ;lda numzones+1
;ldy numzones
;jsr xprdec_2
jsr xmess
asc_hi " "
.byte $00
jsr prpas ; print zone name
lda #$8d
jsr cout
lda numzones
sec
sbc #$01
sta numzones
bcs :+ ; no borrow
dec numzones+1
bit numzones+1 ; set N flag
bmi nozones
: jsr xcheck_wait
bcs nozones
lda numzones
ora numzones+1
beq nozones ; if zero
bra przone
nozones: rts
noatalk: lda #$01
jsr xredirect
jsr xmess
asc_hi "AppleTalk offline!"
.byte $00
exiterr: lda #$ff
jsr xredirect
jmp xerr
; print pascal string at sptr
; leave sptr pointed at one past end
; of string
.proc prpas
ldy #$00
lda (sptr),y ; get length
tax
next: lda sptr
clc
adc #$01
sta sptr
bcc :+
inc sptr+1
: dex
bpl :+
rts
: lda (sptr),y ; get char
ora #$80 ; make printable
jsr cout
bra next
.endproc
; allocate a big buffer for appletalk operations
; returns ay = start, x = size in pages
; tries to use dynamic mem for operations
; otherwise returns altbuf
.proc getatbuf
ldx #mli_read
jsr xmmgr
bcs usealt
cmp #altbufsz
bcc usealt
sta tmp ; save num pages
ldx #mli_open
jsr xmmgr ; allocate all
bcc usealt ; if error
ldx tmp ; get num pages
ldy #$00 ; always on page boundary
rts
usealt: ldy #<altbuf
lda #>altbuf
ldx altbufsz
rts
tmp: .byte $00
.endproc
inforeq: .byte 0,2 ; sync GetInfo
.word $0000 ; result code
.dword $00000000 ; completion address
thisnet: .word $0000 ; this network #
abridge: .byte $00 ; local bridge
hwid: .byte $00 ; hardware ID, IIgs only
romver: .word $00 ; ROM version, IIgs only
nodenum: .byte $00 ; node number
;
myzone: .byte 0,$1a ; sync GetMyZone
.word $0000 ; result
.dword $00000000 ; completion
bufp1: .dword altbuf ; buffer
.byte 4,4 ; 4 times every 1 sec
.word $0000 ; reserved
;
getzones: .byte 0,$1b ; async GetZoneList
.word $0000 ; result
.dword $00000000 ; completion
buflen2: .word altbufsz*$100 ; buffer len
bufp2: .dword altbuf ; buffer
zbridge: .byte $00 ; bridge node
.word $0001 ; start index
.byte 8,16 ; 16 times every 2 secs
numzones: .word $0000 ; num zones returned
.dword $0000000 ; reserved
DX_end

1
boot.dsk Symbolic link
View File

@ -0,0 +1 @@
/Users/lshadow/DavexProDOS.dsk

174
davex-mg.inc Normal file
View File

@ -0,0 +1,174 @@
; MG's davex macros
;
; A skeleton for using this:
; DX_start $a000 ; load address
; DX_info $01,$26,dx_cc_iie_or_iigs,$00
; DX_ptab
; DX_parm 's',t_path
; DX_end_ptab
; DX_desc "My command"
; DX_main
; <code>
; DX_end
;
; *********
.ifdef I_MG_DAVEX
.warning "davex-mg included more than once"
.else
I_MG_MAC = 1
; *********
.include "Common/2/Globals2.asm"
.include "Common/2/MLI.Globals2.asm"
.include "Common/2/Macros2.asm"
cout = $fded ; character out
checkmach = $fe1f ; clears carry on IIgs, no effect on //e
p8_mli = $bf00
mli_atlk = $42
dx_cc_any = 0
dx_cc_40col = 1 << 7
dx_cc_80col = 1 << 6
dx_cc_iie_or_iigs = 1 << 5
dx_cc_iic = 1 << 4
dx_cc_iigs = 1 << 3
dx_cc_bit2 = 1 << 2
dx_cc_bit1 = 1 << 1
dx_cc_bit0 = 1 << 0
dx_mg_auto_origin = 0 ; value for auto origination
; using utils/auto_origin.sh
dx_desc_none = 0
.macro P8call CallNum, PList
jsr p8_mli
.byte CallNum
.addr PList
.endmacro
.macro ATcall PList
P8call mli_atlk, PList
.endmacro
; if the Load address is zero, we don't export X_DX_LOAD
; so that later we can calculate an appropriate start addr
; and let the linker do it.
.macro DX_start Load
.ifdef DID_DX_start
.warning "DX_start used more than once"
.else
.export DID_YOU_DX_end
.export X_DX_MACROS
X_DX_MACROS = 1
.if Load > 0
.org Load
.export X_DX_LOAD
.else
.export X_DX_AUTO_LOAD
X_DX_AUTO_LOAD = 1
.endif
X_DX_LOAD := *
ext_start:
rts
.byte $ee, $ee
DID_DX_start = 1
.endif
.endmacro
.macro DX_info CVer, DXVer, CCs, DAVer
.ifdef DID_DX_start
.byte CVer, DXVer, CCs ; versions and characteristics
.addr X_DX_DESC ; description pointer to pascal str
.addr X_DX_LOAD ; load address
.addr X_DX_EXEC ; exec address
.byte DAVer ; minor version
.byte $00, $00, $00 ; spares
DID_DX_info = 1
.else
.warning "DX_info must happen after DX_start"
.endif
.endmacro