home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
BDOS
/
NOVADOSI.LBR
/
NVDS-1.ZZ0
/
NVDS-1.Z80
Wrap
Text File
|
2000-06-30
|
21KB
|
689 lines
if z33adr or intadr
.phase bdosloc
endif
boot equ p2bios+00000h ; P2 system cold boot
wboot equ p2bios+00003h ; P2 system warm boot
const equ p2bios+00006h ; P2 system console status
conin equ p2bios+00009h ; P2 system console input
conout equ p2bios+0000ch ; P2 system console output
list equ p2bios+0000fh ; P2 system list output
punch equ p2bios+00012h ; P2 system punch output
reader equ p2bios+00015h ; P2 system reader input
home equ p2bios+00018h ; P2 system home disk
seldsk equ p2bios+0001bh ; P2 system select disk
settrk equ p2bios+0001eh ; P2 system select track
setsec equ p2bios+00021h ; P2 system select sector
setdma equ p2bios+00024h ; P2 system set DMA address
read equ p2bios+00027h ; P2 system read 128 bytes
write equ p2bios+0002ah ; P2 system write 128 bytes
listst equ p2bios+0002dh ; P2 system list status
sectrn equ p2bios+00030h ; P2 system sector translation
if dotime
time equ p2bios+timeoff ; P2 system get/set time
endif ; Must be changed if routine present
; Internal definitions
;
contc equ 003h ; Key to generate warm boot
conte equ 005h ; Break line
conth equ 008h ; Backspace
tab equ 009h ; Tab
lf equ 00ah ; Line feed
cr equ 00dh ; Carriage return
contp equ 010h ; Set/reset print flag
contr equ 012h ; Repeat line
conts equ 013h ; Stop console output
contu equ 015h ; Delete line
contx equ 018h ; Delete line (backspaces)
drvsep equ 03ah ; Drive seperator (:)
rubout equ 07fh ; Delete last char
;
if hifuncs
maxcmd equ 52 ; Number of valid P2dos commands
else
if pathcall
maxcmd equ 42
else
maxcmd equ 41
endif
endif
dosstrt equ $
;
; Start program
;
P2dos::
;
vers: version ; Macro in header file
db 0
;
; Start P2dos
;
start: jp entry ; Jump to entry point P2dos
;
; Error messages P2dos
;
; Bad sector message changed to read/write messages-b.h.
stbdsc: defw 0000 ; Bad sector message (dummy)
stsel: defw selerr ; Select error
stro: defw rdonly ; Drive read only
sfilro: defw filro ; File read only
srderr: defw rderr ; Read error message
swrter: defw wrterr ; Write error message
;
; External path name
;
if ispath
path: defw ramlow+pathoff ; Pathname for open file command
endif
;
; Time address P2bios
;
if dotime
timead: defw time ; Time routine address for time
; and date stamps
else
timead: defw const
endif
;
; Flags for specials
; Bit 0: Public file enable(1)/disable(0)
; Bit 1: Delay 256 characters active(1)/disable(0)
; Bit 2: Allow high bits into console buffer yes(1)/no(0)
; Bit 3: Allow high bits output yes(1)/no(0)
; Bit 4: Public attribute files are R/O yes(1)/no(0)
;
flags: db flagbyte ; Flag bite
;
; Entry point P2dos commands
;
entry: ld a,c ; Get function number
ld (funct),a ; Save it for later use
xor a ; Clear a
sbc hl,hl ; Set hl to zero
ld (pexit),hl ; Clear exit code
ld (passfg),hl ; Reset pass flag and read/write flag
ld (retflg),hl ; Reset return flag and drv sel done flg
ld (spsave),sp ; Save stack pointer
ld sp,p2doss ; Get internal stack pointer
push ix ; Save index register
push de ; Save parameter register
pop ix ; Get it back in ix
if relfunc
exx ; Save alternate registers too
push hl ; if using relocation function
push de
exx
endif
ld hl,p2exit ; Get exit address P2dos
push hl ; Save it on stack to return from P2dos
ld a,c ; Get function code
;
if dotime
cp 200 ; Test get time
jp z,gettim ; Yes then get time
cp 201 ; Test set time
jp z,settim ; Yes then set time
endif
;
cp maxcmd+1 ; Test greater then maxcmd
ret nc ; If so return to caller and do nothing
ld hl,ctable ; Load table
ld b,0 ; Prepare 16 bit add
add hl,bc ; Add
add hl,bc ; Add twice to get word value
ld a,(hl) ; Get LSB
inc hl ; Pointer to MSB
ld h,(hl) ; Get MSB
ld l,a ; Save LSB in l
ld c,e ; Put argument in C for BIOS
ld a,e ; Put argument in A for DOS
jp (hl) ; Jump to routine
;
; Command table
;
;
; Func Name Input Parameters Returned Values
; 0 boot none none
; 1 console input none a=character
; 2 console output e=character a=00h
; 3 reader input none a=character
; 4 punch output e=character a=00h
; 5 list output e=character a=00h
; 6 direct console I/O e=0ffh a=input character
; a=00h if no character
; present
; e=0feh a=console status
; e=000h..0fdh a=00h
; 7 get I/O byte none a=I/O byte (ramlow+03h)
; 8 set I/O byte e=I/O byte a=00h
; 9 print string de=address string a=00h
; 10 read console buffer de=address buffer a=00h
; 11 get console status none a=00h if no character
; present
; 01h if character present
; 12 return version number none a=version number (022h)
; 13 reset disk system none a=00h no $*.* file
; a=ffh $*.* file present
; 14 select disk e=disk number a=00h
; 15 open file de=address FCB a=directory code
; 16 close file de=address FCB a=directory code
; 17 search for first de=address FCB a=directory code
; 18 search for next de=address FCB a=directory code
; 19 delete file de=address FCB a=error code
; 20 read sequential de=address FCB a=read/write code
; 21 write sequential de=address FCB a=read/write code
; 22 make file de=address FCB a=directory code
; 23 rename file de=address FCB a=error code
; 24 return login vector none hl=login vector
; 25 return current disk none a=current disk
; 26 set DMA address de=DMA address a=00h
; 27 get allocation address none hl=address allocation
; vector
; 28 write protect disk none a=00h
; 29 get r/o vector none hl=r/o vector
; 30 set file attributes de=address FCB a=error code
; 31 get address dpb none hl=address dpb
; 32 set/get user code e=0ffh a=user number
; e=user number a=00h
; 33 read random de=address FCB a=read/write code
; 34 write random de=address FCB a=read/write code
; 35 compute file size de=address FCB a=error code
; 36 set random record de=address FCB a=00h
; 37 reset multiple drive de=mask a=00h
; 38 not implemented none a=00h
; 39 * get perm. media vector none hl=perm. media vector
; 40 write random with de=address FCB a=read/write code
; zero fill
; 41 set flags byte e=flags none
; 42 get/set DOS path de=path, de=00 current path if de=0
; 47 * return DMA address none hl=DMA address
; 48 * return ZRDOS version none hl=a valid ZRDOS vs. #
; 50 * set warm boot trap de=trap address none
; 52 * reset warm boot trap none none
; 200 get time de=address to put time a=00h
; 201 set time de=address time a=00h
;
; Function numbers marked with * are ZRDOS functions selectable by assembly
; option.
;
; Directory code : a=00h,01h,02h,03h if no error
; a=0ffh if error
; Error code : a=00h if no error
; a=0ffh if error
; Read/write code: a=00h if no error
; a=01h read => end of file
; write => directory full
; a=02h disk full
;
ctable: defw wboot ; Warm boot
defw rdcon ; Console input
defw bwrcon ; Console output
defw rdrdr ; Reader input
defw punch ; Punch output - BIOS direct
defw list ; List output - BIOS direct
defw dcio ; Direct console I/O
defw giost ; Get I/O byte
defw siost ; Set I/O byte
defw mess ; Print string
defw rdbuf ; Read console buffer
defw tstcs ; Get console status
defw cmnd12 ; Return version number
defw cmnd13 ; Reset disk system
defw cmnd14 ; Select disk
defw cmnd15 ; Open file
defw cmnd16 ; Close file
defw cmnd17 ; Search for first
defw cmnd18 ; Search for next
defw cmnd19 ; Delete file
defw cmnd20 ; Read sequential
defw cmnd21 ; Write sequential
defw cmnd22 ; Make file
defw cmnd23 ; Rename file
defw cmnd24 ; Return login vector
defw cmnd25 ; Return current disk
defw cmnd26 ; Set DMA address
defw cmnd27 ; Get address allocation vector
defw cmnd28 ; Write protect disk
defw cmnd29 ; Get r/o vector
defw cmnd30 ; Set file attributes
defw cmnd31 ; Get address disk parameter header(dph)
defw cmnd32 ; Get/set user code
defw cmnd33 ; Read random
defw cmnd34 ; Write random
defw cmnd35 ; Compute file size
defw cmnd36 ; Set random record
defw cmnd37 ; Reset multiple drive
if relfunc
defw cmnd38 ; Relocation
else
defw dummy
endif
if hifuncs
defw permdsk ; Get permanent medium vector
else
defw dummy
endif
defw cmnd40 ; Write random with zero fill
defw setflag ; Set the flags byte
if pathcall and ispath
defw setpath ; Set the DOS path address
else
if hifuncs
defw dummy
endif
endif
if hifuncs
defw dummy ; Not implemented
defw dummy ; Not implemented
defw dummy ; Not implemented
defw dummy ; Not implemented
defw getdma ; Return DMA address
defw zrdos ; Return ZRDOS version number
defw dummy ; Not implemented
defw wbtrap ; Set a warm boot trap
defw dummy ; Not implemented
defw wbtres ; Reset warm boot trap
endif
;
; I/O routines
;
; P2dos console input
;
; Read character from console and echo
; if char=cr,lf,tab,conth or >=space
;
rdcon: call getch ; Get character
call tstch ; Test if cr,lf,tab,conth or >=space
jr c,exit ; No then exit
call wrcon ; Echo character
exit: ld (pexit),a ; Return character
dummy: ret ; And exit P2dos
;
; Read reader
;
rdrdr: call reader ; Get character from reader
jr exit ; And return it to caller
;
;
; Direct console input/output
;
dcio: inc e ; Test if 0ffh
jr z,dcio0 ; Yes do input
inc e ; Test if 0feh
jp nz,conout ; No then output character
call const ; Get console status
jr exit ; And return it to caller
dcio0: call gconst ; Get console status (release I)
or a ; Test it
ret z ; Exit if no character present
call getch ; Get character (release I)
jr exit ; And return it to caller
;
; Get I/O status byte
;
giost: ld a,(ramlow+03h) ; Get I/O byte from ram
jr exit ; And return it to caller
;
; Set I/O status byte
;
siost: ld (ramlow+03h),a ; And save it in ram
ret ; Exit to caller
;
; Test console status
;
tstcs: call gconst ; Get console status
jr exit ; And return it to caller
;
; Output char (control char = ^char)
;
outch: call tstch ; Test it cr,lf,tab,conth or >=space
jr nc,wrcon ; Yes then jump
push af ; Save character
ld a,'^' ; Load a with '^'
call wrcon ; Output it
pop af ; Get character back
push af ; Save it again
add a,'A'-1 ; Add offset
call wrcon ; Output it
pop af ; Get character
ret ; Return to caller
;
; Echo cr,lf
;
crout: ld a,cr ; A=carriage return
call wrcon ; Output it
ld a,lf ; A=line feed
; fall through to output routine
;
; Write character on console
;
;
; P2dos write console
;
bwrcon:
wrcon: cp tab ; Test if tab
jr nz,wrcon1 ; No then jump
wrcon0: ld a,' ' ; Expand tab with spaces
call wrcon ; Write space
ld a,(tabcnt) ; Get tab count
and 7 ; Test if done
jr nz,wrcon0 ; No then repeat
ld a,tab ; Return tab
ret ; Return to caller
wrcon1: push af ; Save character
call gconst ; Test status and conts/contc
pop af ; Get character back
push af ; Save it again
if hibiton
ld hl,flags ; Get the output high bit flag
bit 3,(hl) ; Output high bit is flag bit 3
jr nz,shohb ; If not set, output the character
and 07fh ; Else mask off the high bit
endif
shohb: ld c,a
call conout ; Output it
pop af ; Get character back
push af ; Save it again
ld c,a ; Copy it
ld a,(fcontp) ; Get printer echo flag
or a ; Test it
call nz,list ; Non zero => output char to printer
ld a,(flags) ; Get flag byte
bit 1,a ; Test delay 256 bytes active
jr z,wrcon2 ; No then exit
ld hl,delay ; Get delay counter
xor a ; A=0
or (hl) ; Test counter=0
jr z,wrcon2 ; Yes then exit
dec (hl) ; Else decrement counter
wrcon2: pop af ; Restore character
; fall through to count routine
;
; Count characters in line
;
countc: ld hl,tabcnt ; Get pointer to tab counter
; Part of delete key fix--b.h.
; cp rubout ; Test if character = rubout
; ret z ; Yes no update tab counter
inc (hl) ; Increment tab counter
cp ' ' ; Test if char >= ' '
ret nc ; Yes, normal character then exit
dec (hl) ; Control character, decrement tab count
cp conth ; Test backspace
jr nz,count0 ; No backspace then jump
dec (hl) ; Decrement tab counter
ret ; And exit
cp rubout
jr nz,count0
dec (hl)
ret
count0: cp cr ; Test carriage return
jr nz,count1 ; No then jump
ld (hl),0 ; Reset tab count
ret ; And exit
count1: cp tab ; Test tab character
ret nz ; No then exit
push af ; Save character
ld a,(hl) ; Get tab count
add a,8 ; Advance it 8 position
and 0f8h ; Set it to next tab position
ld (hl),a ; Save it
pop af ; Restore character
ret ; And exit
;
; Get character from console
;
getch: ld hl,lastch ; Get pointer to last input character
ld a,(hl) ; Get character
ld (hl),0 ; Reset last character
or a ; Test if character present
ret nz ; Return if so
jp conin ; Else get character
;
; Get console status
;
gconst: ld a,(delay) ; Get 256 bytes delay
or a ; Test it
jr nz,gcons0 ; Non zero, delay stil active or disabled
call const ; Get console status
and 1 ; Test it
jr nz,gcons1 ; Non zero then get character
gcons0: ld a,(lastch) ; Get last character
or a ; Test it
jr nz,gcons3 ; Non zero then character present
call const ; Get console status
and 1 ; Test it
ret z ; Return if no character present
gcons1: call conin ; Get character
cp conts ; Test stop character
jr nz,gcons2 ; Not then exit character
call conin ; Get next character
cp contc ; Test if user wants to exit
jp z,error5a ; Yes then warm boot
jr gconst ; Test again
gcons2: ld (lastch),a ; Save character
ld a,0ffh ; Set delay counter
ld (delay),a ; And save it
gcons3: ld a,0ffh ; Character present code
ret ; Return to caller
;
; Test character
; Exit carry=0: cr,lf,tab,conth or >= space
; carry=1: All other characters
;
tstch: cp cr ; Test carriage return
ret z ; Return if so
cp lf ; Test line feed
ret z ; Return if so
cp tab ; Test tab
ret z ; Return if so
cp conth ; Test backspace
; Added next two lines as a part of delete key fix--b.h.
ret z ; Return if so
cp rubout
ret z
cp ' ' ; Test >=space
ret ; Return to caller
;
; Write backspace,space,backcpace
;
wconth: call wcont0 ; Write backspace
ld c,' ' ; Load space
call conout ; And output it
wcont0: ld c,conth ; Load backspace
jp conout ; And output it
;
; Output message
;
mess: ld a,(de) ; Get byte from buffer
cp '$' ; Test last byte
ret z ; Yes, then return to caller
inc de ; Point to next byte
push de ; Save pointer
call wrcon ; Output character
pop de ; Restore pointer
jr mess ; And test again
;
; Again prints #,cr,lf and advances to tabcx1
;
again: ld a,'#' ; Load '#'
call wrcon ; Output it
again0: call crout ; Output carriage return/line feed
again1: ld hl,tabcnt ; Get tab count pointer
ld a,(tabcx1) ; Get position first character line
cp (hl) ; Check it
ret z ; Return if on same position
ld a,' ' ; Load space
call wrcon ; Output it
jr again1 ; And test again
;
; Delete char
; Entry : hl=start buffer-1
; b =character counter (always>0)
;
delch: dec b ; Decrement character counter
ld a,(tabcnt) ; Get tab counter
push af ; Save it
push bc ; Save character counter
ld a,(tabcx1) ; Get position first character line
ld (tabcnt),a ; Save it in tab counter
delch0: ld a,b ; Copy character counter
or a ; Test if 0
jr z,delch2 ; Yes then jump
dec b ; Decrement it
inc hl ; Increment buffer pointer
ld a,(hl) ; Get character from buffer
push hl ; Save buffer pointer
call tstch ; Test if cr,lf,tab,conth or >=sp
jr nc,delch1 ; Yes then jump
rra ; Else must be control character
call countc ; Count control character twice
delch1: call countc ; Count character
pop hl ; Get buffer pointer
jr delch0 ; And test again
delch2: pop bc ; Restore character counter
pop af ; And tab counter
push hl ; Save buffer pointer
push bc ; And character counter
ld hl,tabcnt ; Get tab counter pointer
sub (hl) ; Calculate difference
delch3: dec a ; Decrement it
cp 8 ; Compare with 8
jr nc,delch4 ; Jump if >=8
push af ; Save difference
call wconth ; Remove character end line
pop af ; Restore counter
jr delch3 ; Remove more characters
delch4: pop bc ; Restore character counter
pop hl ; Restore buffer pointer
ret ; And return to caller
;
; Read buffer
;
rdbuf: ld a,(tabcnt) ; Get current position cursor
ld (tabcx1),a ; Save it
rdbuf0: push ix ; Save start address buffer
pop hl ; Get it in hl
ld c,(hl) ; Get maximum line length
inc hl ; Increment to line length position
ld b,0 ; Clear line length counter
push hl ; Save start line - 1
rdbuf1: push hl ; Save registers
push bc
rdbuf2: call getch ; Get character
pop bc ; Restore registers
if hibiton
ld hl,flags
bit 2,(hl) ; Allow high bits in command line
endif
pop hl ; if flags bit 2 is set
if hibiton
jr nz,hibit
endif
and 07fh ; Mask character
hibit:
cp conte ; Test if conte
jr nz,rdbuf3 ; Not then jump
push hl ; Save registers
push bc
call again0 ; Move cursor to next line
jr rdbuf2 ; And get next char
rdbuf3: cp conth ; Test backspace
jr nz,rdbuf4 ; Not then jump
doback: ld a,b ; Test if deleting char from empty line
or a
jr z,rdbuf1 ; Yes then get next char
pop hl ; Get start line
push hl ; And save it again
call delch ; Delete character
jr rdbuf1 ; Get next character
rdbuf4: cp contp ; Test print enable/disable
if contron
jr nz,rdbuf6 ; Not then jump
else
jr nz,rdbufa
endif
ld a,(fcontp) ; Complement print flag
cpl
ld (fcontp),a
rdbuf5: jr rdbuf1 ; And get next character
if contron
rdbuf6: cp contr ; Test repeat line
jr nz,rdbufa ; Not then jump
push bc ; Save registers
call again ; Move cursor to next line
pop bc ; Restore registers
pop hl ; Get start line
push hl ; Save it again
push bc ; Save line counter/maximum line length
rdbuf7: ld a,b ; Test last character echoed
or a
jr z,rdbuf8 ; Yes then jump
inc hl ; Increment pointer
ld a,(hl) ; Get character
dec b ; Decrement line counter
push hl ; Save registers
push bc
call outch ; Output character
pop bc ; Restore registers
pop hl
jr rdbuf7 ; And test end line
rdbuf8: pop bc ; Restore line counter/max line length
rdbuf9: jr rdbuf5 ; And get next char
endif ; contron
rdbufa: cp contu ; Test delete line
jr nz,rdbufc ; Not then jump
pop hl ; Get start line
call again ; Move cursor to next line
rdbufb: jr rdbuf ; And start routine again
rdbufc: cp contx ; Test delete line
jr nz,rdbufe ; Not then jump
rdbufd: pop hl ; Get start line
ld a,b ; Test if last character deleted
or a
jr z,rdbufb ; Yes start routine again
push hl ; Save pointer
call delch ; Delete last character line
jr rdbufd ; Test last character deleted
rdbufe: cp rubout ; Test delete last character
jr nz,rdbuff ; Not then jump
jr doback ; Part of delete key fix
; Remove code for echoing deleted character--b.h.
; ld a,b ; Test first character line
; or a
; jr z,rdbuf9 ; Yes, do not delete
; ld a,(hl) ; Get last character
; dec hl ; Decrement pointer line
; dec b ; Decrement line counter
; jr rdbufg ; Echo last character
rdbuff: cp cr ; Test carriage return
jr z,rdbufi ; Yes, then exit
cp lf ; Test line feed
jr z,rdbufi ; Yes then exit
inc hl ; Increment pointer
ld (hl),a ; And save character
inc b ; Increment line counter
rdbufg: push hl ; Save registers
push bc
call outch ; Echo character
pop bc ; Restore registers
pop hl
cp contc ; Test warm boot
ld a,b ; Get line count
jr nz,rdbufh ; No warm boot then jump
cp 1 ; Test contc is first character line
jp z,error5a ; Yes then execute warm boot
rdbufh: cp c ; Test line length=maximum line length
if contron
jr nz,rdbuf9 ; Not then get next character
else
jr nz,rdbuf5
endif
rdbufi: pop hl ; Get start line - 1
ld (hl),b ; Save line counter
ld a,cr ; Load carriage return
jp wrcon ; And echo it
;