home *** CD-ROM | disk | FTP | other *** search
- ; Z80DOS - Z80 Disk Operating System
- ;
- ; Version 1.0 - 05 Sept. 87 by Carson Wilson
- ;
-
- ; -------------------------------------------------------------------
- ;
- ; Z80DCHAR.Z80 - DOS Entry Points, Character I/O, and Error Routines
- ;
- ; -------------------------------------------------------------------
-
- org DOS+6 ; Preserve serial number for CP/M
- ; ..overlay
- ;
- ; Start DOS
- ;
- start: jp entry ; Jump to entry point DOS
- ;
- ; Error messages DOS - for programs which intercept DOS errors
- ;
- defw 0 ; Bad Sector - not implemented
- StSel: defw SelErr ; Select error
- stro: defw rdonly ; Drive read only
- sfilro: defw filro ; File read only
-
- ;
- ; Run-time configurable options:
- ;
-
- timead: defw BIOStim ; Dummy or address of BIOS routine
- ; ..configurable at run time
- flags: defb options ; Flag bite
-
- ;
- ; Entry point for DOS commands
- ;
- Entry: ld a,c ; Get function number
- ld (funct),a ; Save it for later use
- ld hl,0 ; Set hl to zero
- ld (pexit),hl ; Clear exit code
- xor a ; Clear a
- ld (fldrv),a ; Reset drive select done flag
- ld (rdwr),a ; Reset read/write flag
- ld (spsave),sp ; Save stack pointer
- ld sp,DOSs ; Get internal stack pointer
- push ix ; Save index register
- push de ; Save parameter register
- pop ix ; Get it back in ix
- ld hl,p2exit ; Get exit address DOS
- push hl ; Save it on stack to return from DOS
- ld a,c ; Get function code
- cp 105 ; Test get time <crw>
- jp z,gettim ; Yes then get time
- cp 104 ; Test set time <crw>
- jp z,settim ; Yes then set time
- cp 55 ; Test use time stamp <crw>
- jp z,UseStp
- cp 54 ; Test get time stamp <crw>
- jp z,Getstp
- 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
- jp (hl) ; Jump to routine
- ;
- ; Command Jump Table
- ;
- CTable: defw WBoot ; Warm boot
- defw rdcon ; Console input
- defw bwrcon ; Console output
- defw rdrdr ; Reader input
- defw wpunch ; Punch output
- defw wlist ; List output
- 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
- defw dummy ; Access drive - not implemented
- defw dummy ; Free drive - not implemented
- defw cmnd40 ; Write random with zero fill
-
-
- ; ---------------------------------
-
- ; Character Routines
-
- ; ---------------------------------
-
- ; DOS 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 DOS
- ;
- ; DOS write console
- ;
- bwrcon: ld a,e ; Copy character
- jr wrcon ; And output it
- ;
- ; read reader
- ;
- rdrdr: call reader ; Get character from reader
- jr exit ; And return it to caller
- ;
- ; write punch
- ;
- wpunch: ld c,e ; Copy character
- jp punch ; And output it to punch device
- ;
- ; Write list
- ;
- wlist: ld c,e ; Copy character
- jp list ; And output it to list device
- ;
- ; Direct console input/output
- ;
- DCIO: ld c,e ; Copy character
- 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
- and 1 ; Test it
- jr exit ; And return it to caller
- DCIO0: call ConSt ; Get console status
- and 1 ; Test it
- ret z ; Exit if no character present
- call ConIn ; Get character
- jr exit ; And return it to caller
- ;
- ; Get I/O status byte
- ;
- giost: ld a,(RamLow+00003h) ; Get I/O byte from ram
- jr exit ; And return it to caller
- ;
- ; Set I/O status byte
- ;
- siost: ld a,e ; Copy I/O byte
- ld (RamLow+00003h),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
- ;
- 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
- ld c,a ; Copy it
- 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
- 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
- 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,RamLow+00000h ; 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,1 ; 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 tab ; Test tab
- ret z ; Return if so
- cp ContH ; Test backspace
- ret z ; Return if so
- cp rubout
- ret z
- cp ' ' ; Test >=space
- ret ; Return to caller
- ;
- ; Write backspace, space, backspace
- ;
- 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: 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 again ; 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 lenght
- inc hl ; Increment to line lenght position
- ld b,0 ; Clear line lenght counter
- push hl ; Save start line - 1
- rdbuf1: push hl ; Save registers
- push bc
- rdbuf2: call getch ; Get character
- pop bc ; Restore registers
- pop hl
- and 07fh ; Mask character
- 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
- jr nz,rdbufC ; Not then jump
- ld a,(fContP) ; Complement print flag
- cpl
- ld (fContP),a
- 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
- jp z,RDBUF ; 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
- rdbuff: cp cr ; Test carriage return
- 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,RamLow+00000h ; Yes then execute warm boot
- rdbufh: cp c ; Test line length=maximum line length
- jp nz,rdbuf1 ; Not then get next character
- rdbufi: pop hl ; Get start line - 1
- ld (hl),b ; Save line counter
- ld a,cr ; Load carriage return
- jp wrcon ; And echo it
-
-
- ;---------------------------
-
- ; Error routines
-
- ;---------------------------
-
- SelErr: ld de,msel ; Load selected error message
- jr derror ; And display error
- ;
- ; File read only error
- ;
- FilRO: ld de,mfilro ; Load file R/O message
- ld a,0ffh ; Set file R/O message flag
- jr error ; And display error
- ;
- ; Read error message--b.h.
- ;
- rderr: ld de,mrderr
- jr derror
- ;
- ; Write error message--b.h.
- wrterr: ld de,mwrter
- jr derror
- ;
- ; Drive read only error
- ;
- rdonly: ld de,mro ; Load drive R/O message
- derror: xor a ; Set no file R/O message
-
- ;
- ; Display error message
- ;
-
- ; "Error message" error on d:
- ; Function nn
- ; File filename.typ
-
- ;
- error: ld c,a ; Save file R/O message flag
- push bc
- push de ; Save error message pointer
- call crout ; Display cr/lf
- pop de
- call mess ; Display error
- ld a,(defdrv) ; Get current drive
- add a,'A' ; Make ASCII
- ld (mdrive),a ; Save it
- ld de,mberr ; Load message " error on d:"
- call mess ; Display message
- ld de,mbfunc ; Load message "function "
- call mess ; Display message
- ld a,(funct) ; Get function number
- push af ; Save it
- ld bc,100 ; Display number / 100
- call num
- ld c,10 ; Display number / 10
- call num
- ld bc,101h ; Always display number / 1
- call num
- pop af ; Get function number
- pop bc ; Get file R/O flag
- cp 15 ; Test if FCB used in command
- jr c,error3 ; Commands <16, don't show filename
- cp 24
- jr c,error1 ; Commands 16..23 show file
- cp 30
- jr z,error1 ; Command 30 show file
- cp 33
- jr c,error3 ; Other commands 24..32 no file
- cp 37
- jr c,error1 ; 33..36 show
- cp 40
- jr nz,error3 ; 37 don't show
-
- error1: push ix ; Display "file ="
- sub 19 ; Test delete file function
- jr nz,error2 ; Not then jump
- or c ; Test file R/O flag
- jr z,error2 ; No file R/O then jump
- call caldir ; Get FCB from directory buffer
- ex (sp),hl ; Save it
- error2: ld de,mfile ; Get message " file ="
- call mess ; Display message
- pop hl ; Get pointer FCB
- ld b,8 ; Display first 8 characters
- call filenm
- ld a,'.' ; Load '.'
- push hl ; Save FCB pointer
- call wrcon ; Echo it
- pop hl ; Restore FCB pointer
- ld b,3 ; Display last 3 characters
- call filenm
-
- ; Absorb any pending characters:
-
- error3: call gConSt ; Test if character pending
- or a
- jr z,error4 ; No then jump
- call getch ; Get character
- jr error3 ; And test again
- ;
- ; Allow retry on read/write errors
- ;
- error4:
- ld a,(retflg) ; Allow retry?
- or a
- jr z,error5 ; No
- xor a
- ld (retflg),a ; Reset flag <crw>
- call getch
- cp ContC ; Control-c entered?
- ret nz ; No, retry
- error5: jp RamLow+00000h ; Do warm boot
- ;
- ; Display number
- ;
- num: ld d,-1 ; Load number -1
- num1: inc d ; Increment number
- sub c ; Divide by c
- jr nc,num1 ; Not finished then loop
- add a,c ; Restore last value
- push af ; Save it
- ld a,d ; Test if "0"
- or b ; And if leading zero
- jr z,num2 ; Yes, then exit
- ld b,a ; Set no leading zero
- ld a,d ; Get number
- add a,'0' ; Make ASCII
- push bc ; Save registers
- call wrcon ; Echo number
- pop bc ; Restore registers
- num2: pop af ; Restore number
- ret ; And exit
- ;
- ; Display filename.typ
- ;
- filenm: inc hl ; Increment pointer FCB
- ld a,(hl) ; Get character from FCB
- and 07fh ; Mask it
- push hl ; Save registers
- push bc
- call wrcon ; Echo character
- pop bc ; Restore registers
- pop hl
- djnz filenm ; Repeat b times
- ret ; And exit
- ;
- ; Error messages
- ; Made more meaningful--b.h.
- ;
-
- msel: defm 'Illegal drive$'
-
- mfilro: defm 'File '
-
- mro: defm 'R/O$'
-
- mrderr: db 'Read$'
-
- mwrter: db 'Write$'
-
- mberr: defm ' error on '
- mdrive: defb 0
- defb DrvSep
- defm '$'
-
- mbfunc: defm cr,lf,'Function', tab, '$'
-
- mfile: defm cr,lf,'File', tab, tab, '$'
-
- ; END Z80DCHAR.Z80
-
-