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 ;