You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

3226 lines
206 KiB

ZMAC Relocating Macro Assembler v 1.7, page 1
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1 ;****************************************************************************
2 ; Z S D O S
3 ; A CP/M 2.2 compatible replacement Basic Disk Operating System (BDOS)
4 ;
5 ; Copyright (C) 1986,7,8 by:
6 ;
7 ; Harold F. Bower and Cameron W. Cotrill
8 ;
9 ; 7914 Redglobe Ct. 2160 N.W. 159th Place
10 ; Severn, MD 21144-1048 Beaverton, OR 97006
11 ; USA. USA.
12 ;
13 ; HalBower@worldnet.att.net ccotrill@symantec.com
14 ;
15 ; This program is free software; you can redistribute it and/or modify
16 ; it under the terms of the GNU General Public License as published by
17 ; the Free Software Foundation; either version 2 of the License, or
18 ; (at your option) any later version.
19 ;
20 ; This program is distributed in the hope that it will be useful,
21 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 ; General Public License (file LICENSE.TXT) for more details.
24 ;
25 ; You should have received a copy of the GNU General Public License
26 ; along with this program; if not, write to the Free Software
27 ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 ;---------------------------------------------------------------------------
29 ; ZSDOS is a CP/M 2.2 compatable BDOS replacement that contains numerous
30 ; enhancements. It is based on P2DOS 2.1 by HAJ Ten Brugge and revisions
31 ; to P2DOS made by Harold F. Bower, Benjamin Ho, and Cameron W. Cotrill.
32 ; Several good ideas from both CP/M Plus(tm) and ZRDOS(tm) have been added.
33 ; The authors wish to thank Bridger Mitchell of Plu*Perfect Systems for
34 ; suggesting we put our heads together, for reviewing the efforts, and for
35 ; suggesting better methods for coding some sections. Thanks also to Joe
36 ; Wright of Alpha Systems for his review and suggestions, as well as
37 ; squeezing a few more bytes for us.
39 ; Support for Plu*Perfect'a BackGrounder ii(tm) and ZDS DateStamper(tm) is
40 ; included, as well as support for ZCPR/BGii WHEEL and PATH.
41 ; ZSDOS is compatable with NZCOM by Joe Wright of Alpha Systems.
43 ; ZSDOS is designed for Z80 compatible processors ONLY!!!
44 ; ZSDOS is coded to run in Z280 protected mode and may be ROMmed.
46 ; LEGAL DEPARTMENT: P2DOS was written by H.A.J. Ten Brugge, ZSDOS
47 ; modifications were by Cameron W. Cotrill and Harold F. Bower.
48 ; ZDDOS modifications were done by Carson Wilson, Cameron W. Cotrill
49 ; and Harold F. Bower.
51 ; No author assumes responsibility or liability in the use of this
52 ; program or any of its support utilities.
54 ; P2DOS is Copyright (C) 1985 by H.A.J. Ten Brugge - All Rights Reserved
55 ; H.A.J. Ten Brugge
56 ; F. Zernikestraat 207
ZMAC Relocating Macro Assembler v 1.7, page 2
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
57 ; 7553 EC Hengelo
58 ; Netherlands
59 ; Permission to use P2DOS code in ZSDOS granted to Harold F. Bower and
60 ; Cameron W. Cotrill in letter 28 March 1988
62 ; Code sections marked (bm) are revisions suggested by Bridger Mitchell.
63 ; Code sections marked (bh) are from SUPRBDOS mods to P2DOS by Benjamin Ho.
64 ; Code sections marked (crw) are revisions to support internal datestamper
65 ; and are Copyright (C) 1988 by Carson Wilson.
67 ; NOTES: Backgrounder ii and DateStamper are trademarks of Plu*Perfect
68 ; Systems. CP/M is a trademark of Digital Research, Incorporated.
69 ; ZRDOS is a trademark of Echelon, Incorporated.
ZMAC Relocating Macro Assembler v 1.7, page 3
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
71 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
72 ; Version 1.2a, 11/04/89
73 ; Assemble with : SLR Z80ASMP or ZMAC
74 ; Revisions:
75 ; 11/04/89 Moved home call to rddir so bios hostbuf always
76 ; updated before dir read.
77 ; 07/18/89 Fixed tderr routine in ZDDOS so return codes not
78 ; CWC altered from tderr unless called from 102 or 103.
79 ; 06/20/89 Fixed bug in F10 ^R that output 256 spaces if ^R
80 ; CWC entered with tab counter =0.
81 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
83 MACLIB ZSDOS.LIB ; Get initialization code
1+ ;.....
2+ ; ZSDOS Customization. -HFB, 18 Sept 1987
3+ ; revised 07/17/88 CWC
5+ = 0000 FALSE EQU 0
6+ = FFFF TRUE EQU NOT FALSE
8+ ; Set these conditionals before assembly
10+ ;****************************************************************************
11+ ; In the General Public Release version, we have included an equate which
12+ ; controls an additional unreleased fix (which only Howard Goldstein found).
13+ ; If the following equate is set TRUE, a version 1.1 BDOS will be produced
14+ ; which will require no changes to any released utilities. If set to FALSE,
15+ ; a version 1.2 BDOS will result, and many support utility libraries and
16+ ; overlays will need to be revised to make them function properly. HFB
18+ = FFFF ZSDOS11 EQU TRUE ; Set True for Ver 1.1, False for 1.2
20+ ;****************************************************************************
22+ = FFFF ZS EQU TRUE ; Set True for ZSDOS, False for ZDDOS
24+ ;----------
25+ ; Select assembler for ZSDOS. Any modifications to source code must
26+ ; support these assemblers at minimum.
28+ = FFFF SLR EQU TRUE ; SLR Z80ASM or SLR180 Assembler, OR ZMAC
29+ = 0000 ZAS EQU FALSE ; MITEK/ECHELON ZAS Assembler (3.0 or later)
31+ IF ZAS
33+ ENDIF
35+ IF SLR
36+ .Z80
37+ NAME ('DOS')
38+ ENDIF
40+ IF ZAS AND ZS
41+ IF ZSDOS11
46+ ENDIF
47+ IF ZAS AND (NOT ZS)
48+ IF ZSDOS11
ZMAC Relocating Macro Assembler v 1.7, page 4
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
53+ ENDIF
55+ IF SLR AND ZS
56+ IF ZSDOS11
60+ ENDIF ;Zsdos11
61+ ENDIF
62+ IF SLR AND (NOT ZS)
63+ IF ZSDOS11
68+ ENDIF
70+ ;----------
71+ ; P2DOS introduced a search path feature compatible with that used in
72+ ; Richard Conn's ZCPR2 and ZCPR3. If a requested file is not located in
73+ ; the currently logged Drive/User, the SEARCH routine will sequentially
74+ ; scan along the path until either the file is found or the end of the
75+ ; path is reached.
77+ IF ZS
78+ = 0DF1' PATHAD EQU IPATH ; Set to the desired ZCPR2/3 search path.
81+ ENDIF ; in ZSDOS. ZDDOS does not use path.
83+ ;----------
84+ ; The WHEEL byte may be sensed from within ZSDOS by setting the following
85+ ; address to that of the ZCPR3 WHEEL byte. A value of 0 disables the WHEEL
86+ ; byte sensing.
88+ = 0000 WHLADR EQU 00000H ; Set WHEEL byte address (0FDFFH for SB180)
90+ ;----------
91+ ; Some systems, like the Kaypro 4, only recognize changes between single
92+ ; and double-sided disks when the system is warm booted; BDOS Function 13
93+ ; (reset disk) will not work. By adding a "hook" to the BIOS of these mach-
94+ ; ines and setting RESDSK to TRUE, BDOS functions 13 and 37 will allow changes
95+ ; between single and double-sided disks; very handy for disk housekeeping
96+ ; utilities such as NSWP, NULU, and cataloging programs.
98+ ; The "hook" is added as follows: Obtain the source to your computer's BIOS.
99+ ; Examine the code for WARM BOOT. Somewhere, there should be a call to a rou-
100+ ; tine which initializes the disk system after a warm boot, or which detects
101+ ; changes between single and double-sided disks. Call this routine DISKINT
102+ ; for purposes of discussion. Modify your BIOS's cold boot routine to ini-
103+ ; tialize 3 bytes at address SETDSK as "JP DISKINT". The location of SETDSK
104+ ; is arbitrary, it may be in your BIOS, or in a reserved spot in CP/M's page 0.
106+ = 0000 RESDSK EQU FALSE
108+ IF RESDSK
110+ ENDIF ; resdsk (bh)
112+ ;----------
113+ ; The following equate is used to produce separate code and data segments
114+ ; for blowing ZSDOS into ROM. Calling BDOS Function 0 will initialize the
115+ ; Data Segment to default values.
117+ = 0000 ROM EQU FALSE ; Separate data and code?
ZMAC Relocating Macro Assembler v 1.7, page 5
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
119+ ;----------
120+ ; Many ZSDOS features can be controlled while ZSDOS is running by altering
121+ ; the FLAG byte. Set the following equate to your desired configuration based
122+ ; on your requirements. The individual bit assignments in the FLAG byte are:
123+ ;
124+ ; Bit - 7 6 5 4 3 2 1 0
125+ ; \ \ \ \ \ \ \ \__Public File Enable (1) / Disable (0)
126+ ; \ \ \ \ \ \ \___Public/Path Write Enable (1) / Disable (0)
127+ ; \ \ \ \ \ \____Read-Only Enable (1) / Disable (0)
128+ ; \ \ \ \ \_____Fast Fixed Disk Relog Enable (1) / Disable (0)
129+ ; \ \ \ \______Disk Change Warning Enable (1) / Disable (0)
130+ ; \ \ \_______ZCPR2/3 Path Enable (1) / Disable (0)
131+ ; \ \________Path without System Enable (1) / Disable (0)
132+ ; \_________(Reserved)
134+ = 006D FLGBITS EQU 01101101B ; PUBLIC On, P/P Write Off, R/O On,
135+ ; Fast Relog On,Disk Change warning Off,
136+ ; Path On, No System path On
138+ ; The operation of Bit 6 represents a deviation from the description of PUBLIC
139+ ; Files as given in DDJ Article by Bridger Mitchell and Derek McKay of Plu*
140+ ; Perfect Systems. The PUBLIC Specification states that Public Files will NOT
141+ ; be found by any wildcard reference except when a "?" is in the FCB+0 byte.
142+ ; The code here relaxes that requirement as follows: If we are in the same
143+ ; user area as the public file, then don't report the file as PUBLIC, but find
144+ ; it. This has a nasty side effect - it allows erasing of PUBLIC files if we
145+ ; are in the same area. However, these files also show up on the directory
146+ ; (they wouldn't otherwise), so at least we should know we're blasting them.
148+ ;----------
149+ ; Equates for selecting ZSDOS or ZDDOS configurations
151+ ; Since much ZSDOS code must be deleted to embed DateStamper in ZDDOS, the
152+ ; following flags do the stripping:
153+ ; PICKEY - True = Don't save users' DE register
154+ ; CTLREN - True = Add ^R Retype line to cons read, False = No ^R
155+ ; UNROLL - True = Inline code for shifts, False = collapse into loops
156+ ; UPATH - True = Add User path from OS, False = No OS path search
158+ IF ZS
159+ = FFFF CTLREN EQU TRUE
160+ = FFFF UNROLL EQU TRUE
161+ = FFFF UPATH EQU TRUE
162+ = 0000 PICKEY EQU FALSE
168+ ENDIF
170+ ;----------
171+ ; To Use the Named-COMMON aspect of NZCOM and JETLOADER (tm), the BIOS must
172+ ; be referenced from the _BIOS_ name. If operating under this scheme, set
173+ ; the ZRL equate to TRUE. With the ZRL equate set to FALSE, a standalone
174+ ; .REL file will be produced with no external requirements.
176+ = FFFF ZRL EQU TRUE ; Set True .ZRL file with COMMON for NZCOM,
177+ ; False to produce straight .REL file
ZMAC Relocating Macro Assembler v 1.7, page 6
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
85 = 0000 RAMLOW EQU 0000H ; Start address memory
87 CSEG
88 = 0000' ZSDOS EQU $ ; Start address ZSDOS
90 IF ZRL
91 COMMON /_BIOS_/
92 0000* BIOS:
93 CSEG
96 ENDIF
98 = 0000* BOOT EQU BIOS+0000H ; Cold Boot
99 = 0003* WBOOT EQU BIOS+0003H ; Warm Boot
100 = 0006* CONST EQU BIOS+0006H ; Console Status
101 = 0009* CONIN EQU BIOS+0009H ; Console Input
102 = 000C* CONOUT EQU BIOS+000CH ; Console Output
103 = 000F* LIST EQU BIOS+000FH ; List Output
104 = 0012* PUNCH EQU BIOS+0012H ; Punch Output
105 = 0015* READER EQU BIOS+0015H ; Reader Input
106 = 0018* HOME EQU BIOS+0018H ; Home Disk
107 = 001B* SELDSK EQU BIOS+001BH ; Select Disk
108 = 001E* SETTRK EQU BIOS+001EH ; Select Track
109 = 0021* SETSEC EQU BIOS+0021H ; Select Sector
110 = 0024* SETDMA EQU BIOS+0024H ; Set DMA Address
111 = 0027* READ EQU BIOS+0027H ; Read 128 Bytes
112 = 002A* WRITE EQU BIOS+002AH ; Write 128 Bytes
113 = 002D* LISTST EQU BIOS+002DH ; List Status
114 = 0030* SECTRN EQU BIOS+0030H ; Sector Translation
116 ; Internal Definitions
117 IF ZSDOS11
118 = 0001 VERMAJ EQU 1 ; Major version number
119 = 0001 VERMIN EQU 1 ; Minor version number
123 ENDIF ;Zs
124 = 0011 VERS EQU VERMAJ*10H+VERMIN
126 = 0003 CONTC EQU 03H ; Key to generate warm boot
127 = 0008 CONTH EQU 08H ; Backspace
128 = 0009 TAB EQU 09H ; Tab
129 = 000A LF EQU 0AH ; Line feed
130 = 000D CR EQU 0DH ; Carriage return
131 = 0010 CONTP EQU 10H ; Set/reset print flag
132 = 0012 CONTR EQU 12H ; Retype line
133 = 0013 CONTS EQU 13H ; Stop console output
134 = 0018 CONTX EQU 18H ; Delete line (backspaces)
135 = 0015 CONTU EQU 15H ; Same as Control-X
136 = 007F RUBOUT EQU 7FH ; Delete last char
138 = 001F MAXEXT EQU 1FH ; Maximum extent number
139 = 003F MAXMOD EQU 3FH ; Maximum data module number
141 = 0091 TDCKSM EQU 91H ; CHECKSUM OF !!!TIME&.DAT
143 ; Attribute Bit Definitions
145 = 0002 PUBATT EQU 2 ; Public attribute offset
ZMAC Relocating Macro Assembler v 1.7, page 7
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
146 = 0007 PSFATT EQU 7 ; Public/system file (internal only)
147 = 0008 WHLATT EQU 8 ; Wheel protect attribute offset
148 = 0009 ROATT EQU 9 ; Read only attribute offset
149 = 000A SYSATT EQU 10 ; System attribute offset
150 = 000B ARCATT EQU 11 ; Archive attribute offset
152 ; FCB POSITION EQUATES
154 = 000C FCBEXT EQU 12 ; Extent number
155 = 000D FCBUSR EQU 13 ; User valid at offset 13 if set (internal)
156 = 000E FCBMOD EQU 14 ; Data module number - D7 used as unmod flag
157 = 000F FCBREC EQU 15 ; Record number
158 = 0020 NXTREC EQU 32 ; Next record number
ZMAC Relocating Macro Assembler v 1.7, page 8
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
160 ;**************************************************************
161 ;* Z S D O S P r o g r a m S t a r t *
162 ;**************************************************************
164 ; WARNING!! Do NOT change labels or sequences of ZSDOS through ZSDOS+25H
165 ; ID string added for easy identification in running system (hfb)
167 IF ZS
168 0000' 5A 53 44 4F DEFB 'ZSDOS ' ; Used in CP/M for serial number. these bytes
171 ENDIF ; still be used without problems.
173 ; ZSDOS Entry Point
175 0006' C3 009B' START: JP ENTRY ; Jump to start of program code
177 ; CP/M 2.2 Compatable Error Vector Table
179 0009' 034C STBDSC: DEFW ERROR ; Bad sector message
180 000B' 034C STSEL: DEFW ERROR ; Select error
181 000D' 034C STRO: DEFW ERROR ; Drive read only
182 000F' 034C SFILRO: DEFW ERROR ; File read only
184 ; External Path Name
186 0011' 0DF1 PATH: DEFW PATHAD ; Path address for file open, 0 if no path
188 ; Wheel Byte Pointer
190 0013' 0000 WHEEL: DEFW WHLADR ; Address of wheel byte, 0 if none
192 ; User configuration byte
194 0015' 6D FLAGS: DEFB FLGBITS ; Flag byte set in zsdos.lib
196 ; Dispatch table for time/date stamp routines
198 ; ZSDOS uses all vectors in this table as indicated. ZDDOS uses all but
199 ; STUPDV, GETSTV, and PUTSTV. STCRV is used to store the address of the
200 ; stamp for ZDDOS, thus allowing ZSCONFIG to enable and disable stamping
201 ; of Last Access and Modify.
203 0016' 0DDD GSTIME: DEFW DOTDER ; Address of get/set time/date routine (hfb)
204 IF ZS
205 0018' 0DDD STLAV: DEFW DOTDER ; Address of stamp last access routine
206 001A' 0DDD STCRV: DEFW DOTDER ; Address of stamp create routine
207 001C' 0DDD STUPDV: DEFW DOTDER ; Address of stamp modify routine
212 ENDIF
213 001E' 0DDD GETSTV: DEFW DOTDER ; Address of get stamp routine
214 0020' 0DDD PUTSTV: DEFW DOTDER ; Address of set stamp routine
215 0022' 0DDD DEFW DOTDER ; Dummy vector to disable with ZSCONFIG
216 0024' 0000 UNLOAD: DEFW 0 ; Pointer to remove Time Stamp routine
ZMAC Relocating Macro Assembler v 1.7, page 9
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
219 ;********************************************************
220 ;* Z S D O S L o w R A M D a t a *
221 ;********************************************************
223 ; RAM has been moved down here to an area that is compatable with ZRDOS per
224 ; suggestion by Hal Bower. The actual addresses used are NOT compatable with
225 ; ZRDOS.
227 ; Due to ZSDOS's smaller RAM area, any program that saves RAM in accordance
228 ; with ZRDOS's specifications for re-entry into BDOS should work under ZSDOS
229 ; without problems. Some code will be saved also, as well as the Flag Byte,
230 ; but this should be no problem for IOP'S.
232 ; The Write Protect, Login, and Hard Disk Login Vectors are kept at the top of
233 ; ZSDOS, as they must reflect the current status of the Disk System and hence
234 ; should NOT be saved with other system variables Under ANY Circumstance!
236 IF ROM
238 ENDIF
239 0026' BGLORAM:
240 ;--------------------------------------------------------------------
241 ; The following locations MUST remain in EXACTLY this order
243 0026' 00 TABCNT: DEFB 0 ; Tab counter
244 0027' 00 TABCX1: DEFB 0 ; Temporary Tab counter (used by RDBUF)
245 ;--------------------------------------------------------------------
247 0028' 00 FCONTP: DEFB 0 ; List enable flag (Control-P) - used by BGii
248 0029' 00 LASTCH: DEFB 0 ; Last character - used by BGii
250 ;--------------------------------------------------------------------
251 ; The following locations MUST remain in EXACTLY this order
253 002A' 00 USER: DEFB 0 ; User number - used by BGii
254 002B' 00 DEFDRV: DEFB 0 ; Default drive number - used by BGii and DS
255 002C' 00 DRIVE: DEFB 0 ; Drive number
256 ;--------------------------------------------------------------------
258 002D' 00 FCB0: DEFB 0 ; FCB byte 0
260 002E' BGHIRAM:
261 002E' 0080 DMA: DEFW 0080H ; DMA address
263 0030' 0000 TRANS: DEFW 0 ; Translation vector
264 0032' 0000 TEMP0: DEFW 0 ; Number of files on drive
267 0034' 0000 DIRBUF: DEFW 0 ; Directory buffer pointer - used by bgii
268 0036' 0000 IXP: DEFW 0 ; Disk parameter block
269 0038' 0000 CSV: DEFW 0 ; Check sum pointer
270 003A' 0000 ALV: DEFW 0 ; Allocation vector pointer
272 ;--------------------------------------------------------------------
273 ; The following locations MUST remain in EXACTLY this order
274 ; Copy of DPB for Current Drive
ZMAC Relocating Macro Assembler v 1.7, page 10
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
276 = 003C DPBOF EQU $-ZSDOS ; Value needed by ZSDOS
278 003C' 0000 MAXSEC: DEFW 0 ; Number of sectors/track
279 003E' 00 NBLOCK: DEFB 0 ; Block shift
280 003F' 00 NMASK: DEFB 0 ; Mask number of blocks
281 0040' 00 NEXTND: DEFB 0 ; Extent mask
282 0041' 0000 MAXLEN: DEFW 0 ; Maximum block number-1
283 0043' 0000 NFILES: DEFW 0 ; Maximum number of files-1
284 0045' 00 NDIR0: DEFB 0 ; First two entries ALV buffer
285 0046' 00 DEFB 0 ; ..(NDIR1)
286 0047' 0000 NCHECK: DEFW 0 ; Number of checksum entries
287 0049' 0000 NFTRK: DEFW 0 ; First track number
288 ;--------------------------------------------------------------------
289 004B' 00 FUNCT: DEFB 0 ; Function number
290 004C' 0000 PEXIT: DEFW 0 ; Exit code
291 ;--------------------------------------------------------------------
292 ; The following locations MUST remain in EXACTLY this order
294 004E' 00 FLDRV: DEFB 0 ; Drive select used flag
295 004F' 00 RDWR: DEFB 0 ; Read/write flag
296 0050' 00 SEARQU: DEFB 0 ; Search question mark used
297 0051' 00 SEARPU: DEFB 0 ; Search public file
298 ;--------------------------------------------------------------------
299 0052' 0000 RECDIR: DEFW 0 ; Record directory (checksum)
300 0054' 0000 FILCNT: DEFW 0 ; File counter
301 0056' 00 SECPNT: DEFB 0 ; Sector pointer
302 0057' 00 SUBFLG: DEFB 0 ; Submit flag (reset disk command)
304 0058' 0000 DCOPY: DEFW 0 ; Copy address FCB
305 005A' 00 SEAREX: DEFB 0 ; Exit code search
306 005B' 00 SEARNB: DEFB 0 ; Search number of bytes
307 005C' 00 ERMODE: DEFB 0 ; BDOS error mode
309 005D' 0000 ARWORD: DEFW 0 ; De argument on entry - used for BGii
310 005F' 0000 DEVAL: DEFW 0 ; Return value for DE reg
311 0061' 0000 SPSAVE: DEFW 0 ; Stack pointer location
312 IF ZS
313 0063' 5A 53 44 4F DEFB 'ZSDOS 1.1 Copyri'
316 ENDIF
317 0073' 67 68 74 20 DEFB 'ght (c) 1987,88 '
318 0083' 20 43 2E 57 DEFB ' C.W.Cotrill & H'
319 0093' 2E 46 2E 42 DEFB '.F.Bow'
320 0099' 65 72 IXSAVE: DEFB 'er' ; User's IX register
321 009B' ZSDOSS: ; ZSDOS stack
323 = 009B' BGRAMTOP EQU ZSDOSS
ZMAC Relocating Macro Assembler v 1.7, page 11
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
325 CSEG
326 ;**********************************************************************
327 ;* Z S D O S e n t r y p o i n t *
328 ;**********************************************************************
330 009B' AF ENTRY: XOR A ; Clear A
331 009C' 47 LD B,A ; For later 16 bit adds
332 009D' 6F LD L,A
333 009E' 67 LD H,A ; Set HL to zero
334 009F' 22 004C' LD (PEXIT),HL ; Clear exit code
335 00A2' 22 004E' LD (FLDRV),HL ; Reset drive select and R/W flags
336 00A5' ED73 0061' LD (SPSAVE),SP ; Save stack pointer
337 00A9' 31 009B' LD SP,ZSDOSS ; Get internal stack pointer
338 00AC' DDE5 PUSH IX ; Save index register on our stack
339 00AE' D5 PUSH DE ; Save parameter register
340 00AF' DDE1 POP IX ; Get it back in IX
341 00B1' DD22 005D' LD (ARWORD),IX ; Save in memory for BGii
342 IF NOT PICKEY
343 00B5' DD22 005F' LD (DEVAL),IX ; ..and for non-file access returns
344 ENDIF
345 00B9' 21 03E6' LD HL,DOSEXIT ; Get exit address ZSDOS
346 00BC' E5 PUSH HL ; Save it on stack to return from ZSDOS
347 00BD' 79 LD A,C ; Get function code - B reg = 0
348 00BE' 32 004B' LD (FUNCT),A ; Save it for later use
349 00C1' FE 0C CP 12 ; Is it a non-disk function?
350 00C3' 38 0D' JR C,ENTRY0 ; ..jump if so
351 00C5' FE 31 CP MAXCMD ; Cmnd < Maximum Command Number (48)?
352 00C7' 38 0D' JR C,ENTRY1 ; ..jump if disk function
354 ; Extended function scanner for added functions
356 00C9' FE 62 CP 98 ; Is it less than Cmd98?
357 00CB' D8 RET C ; ..return if so
358 00CC' FE 68 CP 103+1 ; Is it greater than Cmd103?
359 00CE' D0 RET NC ; ..quit if so
360 00CF' D6 31 SUB 98-MAXCMD ; Rework so 98-->49..103-->54
361 00D1' 4F LD C,A ; Save reworked function #
362 ; ..fall thru to entry0..
364 ; If Non-disk Function (ie Function # less than 12), push the address of
365 ; the SAVEA routine on the Stack (save A reg as return code). Saves
366 ; code in Console Routines, as simple RET can be used in most cases.
368 00D2' 21 04BB' ENTRY0: LD HL,SAVEA
369 00D5' E5 PUSH HL ; Vector return thru A reg save
370 00D6' 21 00E2' ENTRY1: LD HL,CTABLE ; Load table
371 00D9' 09 ADD HL,BC ; Add
372 00DA' 09 ADD HL,BC ; Add twice to get word value
373 00DB' 7E LD A,(HL) ; Get LSB
374 00DC' 23 INC HL ; Pointer to MSB
375 00DD' 66 LD H,(HL) ; Get MSB
376 00DE' 6F LD L,A ; Save LSB in L
378 ; Copy byte argument into A and C to simplify Function calls. This allows
379 ; direct BIOS jumps for several functions with resulting code savings.
ZMAC Relocating Macro Assembler v 1.7, page 12
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
381 00DF' 4B LD C,E ; Place arg in C for BIOS
382 00E0' 7B LD A,E ; And in A for others
383 00E1' E9 JP (HL) ; Jump to routine
ZMAC Relocating Macro Assembler v 1.7, page 13
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
386 ;******************************************************
387 ;* C O M M A N D T A B L E *
388 ;******************************************************
389 00E2' CTABLE:
390 IF ROM
392 ELSE
393 00E2' 03CA DEFW ERROR5 ; Warm boot (BIOS) with ERMODE clear
394 ENDIF
395 00E4' 0150 DEFW CMND01 ; Console input
396 00E6' 0264 DEFW WRCON ; Console output
397 00E8' 0015 DEFW READER ; Reader input (BIOS)
398 00EA' 0012 DEFW PUNCH ; Punch output (BIOS)
399 00EC' 000F DEFW LIST ; List output (BIOS)
400 00EE' 015A DEFW CMND06 ; Direct console I/O
401 00F0' 0191 DEFW CMND07 ; Get I/O byte
402 00F2' 018E DEFW CMND08 ; Set I/O byte
403 00F4' 02D5 DEFW CMND09 ; Print string
404 00F6' 0195 DEFW CMND10 ; Read console buffer
405 00F8' 02B7 DEFW CMND11 ; Get console status
406 00FA' 04CF DEFW CMND12 ; Return version number
407 00FC' 040A DEFW CMND13 ; Reset disk system
408 00FE' 057A DEFW CMND14 ; Select disk
409 0100' 0AB4 DEFW CMND15 ; Open file
410 0102' 07A8 DEFW CMND16 ; Close file
411 0104' 046E DEFW CMND17 ; Search for first
412 0106' 0495 DEFW CMND18 ; Search for next
413 0108' 04A5 DEFW CMND19 ; Delete file
414 010A' 0BBE DEFW CMND20 ; Read sequential
415 010C' 0BFF DEFW CMND21 ; Write sequential
416 010E' 0B02 DEFW CMND22 ; Make file
417 0110' 04B0 DEFW CMND23 ; Rename file
418 0112' 04E8 DEFW CMND24 ; Return login vector
419 0114' 04B8 DEFW CMND25 ; Return current disk
420 0116' 0833 DEFW CMND26 ; Set DMA address
421 0118' 04E4 DEFW CMND27 ; Get address allocation vector
422 011A' 0703 DEFW CMND28 ; Write protect disk
423 011C' 04DC DEFW CMND29 ; Get R/O vector
424 011E' 04C7 DEFW CMND30 ; Set file attributes
425 0120' 04EC DEFW CMND31 ; Get address disk parameter header (DPH)
426 0122' 04FB DEFW CMND32 ; Get/set user code
427 0124' 0BB4 DEFW CMND33 ; Read random
428 0126' 0BF4 DEFW CMND34 ; Write random
429 0128' 0507 DEFW CMND35 ; Compute file size
430 012A' 050F DEFW CMND36 ; Set random record
431 012C' 041A DEFW CMND37 ; Reset multiple drive
432 012E' 04BE DEFW DUMMY ; Function 38 (unused)
433 0130' 04E0 DEFW CMND39 ; Return fixed disk login vector
434 0132' 0BF4 DEFW CMND40 ; Write random with zero fill
435 0134' 04BE DEFW DUMMY ; Function 41 (unused)
436 0136' 04BE DEFW DUMMY ; Function 42 (unused)
437 0138' 04BE DEFW DUMMY ; Function 43 (unused)
438 013A' 04BE DEFW DUMMY ; Function 44 (unused)
439 013C' 04F7 DEFW CMND45 ; Set Error Mode
440 013E' 04BE DEFW DUMMY ; Function 46 (unused)
441 0140' 04F0 DEFW CMND47 ; Return DMA
442 0142' 04D8 DEFW CMND48 ; Return DOS version
ZMAC Relocating Macro Assembler v 1.7, page 14
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
444 = 0031 MAXCMD EQU ($-CTABLE)/2 ; Jww
446 0144' 0DD7 DEFW CMD98 ; Get Time ; 49
447 0146' 0DD4 DEFW CMD99 ; Set Time ; 50
448 0148' 04C2 DEFW CMD100 ; Get Flags ; 51
449 014A' 04BF DEFW CMD101 ; Set Flags ; 52
450 014C' 0DA4 DEFW CMD102 ; Get Stamp ; 53
451 014E' 0DA4 DEFW CMD103 ; Put Stamp ; 54
ZMAC Relocating Macro Assembler v 1.7, page 15
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
454 ;******************************************************
455 ;* N o n - D i s k F u n c t i o n s *
456 ;******************************************************
458 IF ROM
468 IF ZS ; Need Internal path if ZSDOS
483 ENDIF ; Rom
485 ;.....
486 ; I/O Routines
488 ; ZSDOS Console Input. Read character from Console and Echo
489 ; If Char=CR,LF,TAB,CONTH or >=Space
491 0150' CD 0175' CMND01: CALL GETCH ; Get character (and test it jww)
492 0153' D8 RET C ; Less than space, exit
493 0154' E5 PUTCH: PUSH HL ; Save regs for other calls
494 0155' CD 0264' CALL WRCON ; Echo character
495 0158' E1 POP HL
496 0159' C9 RET
498 ; Direct Console Input/Output
499 ; Call with Char in C and E - Enhanced to CP/M-3 Spec
500 ; Checks ZSDOS typeahead for reliable console I/O under all conditions
501 ; as per a suggestion by Bridger Mitchell.
503 015A' 1C CMND06: INC E ; Test if get char if avail
504 015B' 28 14' JR Z,DCIO1 ; Yes do input
505 015D' 1C INC E ; Test for 0FEH
506 015E' 28 06' JR Z,DCIO2 ; Yes, get status
507 0160' 1C INC E ; Test for 0FDH
508 0161' 28 12' JR Z,GETCH ; Yes, wait for input char
509 0163' C3 000C* JP CONOUT ; Else print char
511 0166' 3A 0029' DCIO2: LD A,(LASTCH) ; Check for buffered char
512 0169' B7 OR A
513 016A' 3E 01 LD A,0001B ; ..preset ready
514 016C' CC 0006* CALL Z,CONST ; Get console status
515 016F' A7 AND A ; Test it
516 0170' C9 RET ; And return it to caller
518 0171' CD 0166' DCIO1: CALL DCIO2 ; Get console status
519 0174' C8 RET Z ; Exit if no character present
520 ; Else fall thru
521 ; Get Character from Console
523 0175' 21 0029' GETCH: LD HL,LASTCH ; Check ZSDOS type ahead for char
524 0178' 7E LD A,(HL)
525 0179' 36 00 LD (HL),0 ; Reset last character
526 017B' B7 OR A ; ..set flags
527 017C' CC 0009* CALL Z,CONIN ; Get character (and test it jww)
529 ; Test Character
530 ; Exit Carry=0: CR,LF,TAB,CONTH or >= Space
531 ; Carry=1: All other Characters
ZMAC Relocating Macro Assembler v 1.7, page 16
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
533 017F' FE 0D CP CR ; Is it a carriage return?
534 0181' C8 RET Z ; ..return if so
535 0182' FE 0A CP LF ; Is it a line feed?
536 0184' C8 RET Z ; ..return if so
537 0185' FE 09 CP TAB ; Is it a tab?
538 0187' C8 RET Z ; ..return if so
539 0188' FE 08 CP CONTH ; Is it a backspace?
540 018A' C8 RET Z ; ..return if so
541 018B' FE 20 CP ' ' ; Test >=space
542 018D' C9 RET ; ..and return to caller
544 ; Set I/O Status Byte
546 018E' 32 0003 CMND08: LD (RAMLOW+0003H),A ; And save it in RAM and fall through
548 ; Get I/O Status Byte
550 0191' 3A 0003 CMND07: LD A,(RAMLOW+0003H) ; Get I/O byte from RAM
551 0194' C9 RET
553 ; Buffered Console Read
555 0195' 3A 0026' CMND10: LD A,(TABCNT)
556 0198' 32 0027' LD (TABCX1),A ; Save start tab position
557 019B' 13 INC DE
558 019C' AF XOR A
559 019D' 12 LD (DE),A ; Set char count to zero
560 019E' 13 INC DE ; Point to actual buffer start
562 019F' D5 RDBUF1: PUSH DE ; Save buffer pointer
563 01A0' CD 0175' CALL GETCH ; Get next byte from user
564 01A3' D1 POP DE
565 01A4' 21 019F' LD HL,RDBUF1
566 01A7' E5 PUSH HL ; Return address to stack
567 01A8' 2A 005D' LD HL,(ARWORD)
568 01AB' 4E LD C,(HL) ; Put buffer length in C
569 01AC' 23 INC HL ; And point to current length
571 01AD' FE 0D CP CR
572 IF CTLREN
573 01AF' 28 02' JR Z,JZRBX ; Exit if CR
576 ENDIF ;Ctlren
578 01B1' FE 0A CP LF
579 IF CTLREN
580 01B3' CA 024E' JZRBX: JP Z,RDBUFX ; ..or LF
583 ENDIF ;Ctlren
584 ;..Not CR or LF, so fall thru to next test
586 ; Delete Character from Buffer
587 ; RUB, Backspace, CR, LF are NEVER in the Buffer
589 01B6' FE 7F RDBUF2: CP RUBOUT ; Delete char?
590 01B8' 28 04' JR Z,DOBACK ; ..jump if so
591 01BA' FE 08 CP CONTH ; Control-H also deletes
592 01BC' 20 36' JR NZ,RDBUF3 ; Skip to next test if no delete
ZMAC Relocating Macro Assembler v 1.7, page 17
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
594 01BE' 7E DOBACK: LD A,(HL)
595 01BF' A7 AND A ; Test if attempting del from empty line
596 01C0' C8 RET Z ; ..Exit if so
597 01C1' 1B DOBAK0: DEC DE ; Back up to last character
598 01C2' 35 DEC (HL) ; Erase from buffer
599 01C3' D5 PUSH DE ; Save buffer pointer
600 01C4' 46 LD B,(HL) ; Get new char count
601 01C5' 23 INC HL ; Point to first char
602 01C6' EB EX DE,HL
603 01C7' 21 0026' LD HL,TABCNT
604 01CA' 4E LD C,(HL) ; Save current Tab count
605 01CB' 23 INC HL
606 01CC' 7E LD A,(HL) ; Get starting Tab position
607 01CD' 2B DEC HL
608 01CE' 77 LD (HL),A ; Init the counter
609 01CF' 04 INC B ; Insure non-zero
610 01D0' 18 05' JR DOBAK2 ; Jump to done test
612 01D2' 1A DOBAK1: LD A,(DE) ; Get char from buffer
613 01D3' CD 0293' CALL WRCON2 ; Counts chars
614 01D6' 13 INC DE
615 01D7' 10 F9' DOBAK2: DJNZ DOBAK1 ; Continue count until done
616 01D9' 79 LD A,C ; Get prior tab count
617 01DA' 96 SUB (HL) ; Get diff between new and old
618 01DB' 47 LD B,A ; Set up as count
619 01DC' 71 LD (HL),C ; Restore prior count
620 01DD' D1 POP DE ; Restore buffer pointer
622 ; Delete B Characters from Console
624 01DE' D5 PUSH DE ; Save pointer
625 01DF' 0E 08 DOBAK5: LD C,CONTH
626 01E1' C5 PUSH BC ; Save counter from destruction
627 01E2' CD 000C* CALL CONOUT
628 01E5' 0E 20 LD C,' '
629 01E7' CD 000C* CALL CONOUT ; Output backspace,space to CON: only
630 01EA' 3E 08 LD A,CONTH
631 01EC' CD 0264' CALL WRCON ; Now backspace CON:, counter, and printer
632 01EF' C1 POP BC ; Restore counter
633 01F0' 10 ED' DJNZ DOBAK5 ; Loop until all done
634 01F2' D1 POP DE ; Restore pointer
635 01F3' C9 RET
637 ; Erase Buffer
639 01F4' FE 15 RDBUF3: CP CONTU ; Test erase line
640 01F6' 28 04' JR Z,ERALIN ; Do it if so
641 01F8' FE 18 CP CONTX
642 01FA' 20 0A' JR NZ,RDBUF4 ; Skip to next test if no erase line
644 01FC' AF ERALIN: XOR A
645 01FD' B6 OR (HL) ; Line empty?
646 01FE' C8 RET Z ; Exit if so
647 01FF' E5 PUSH HL
648 0200' CD 01C1' CALL DOBAK0 ; Else delete another (skip empty check)
ZMAC Relocating Macro Assembler v 1.7, page 18
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
649 0203' E1 POP HL
650 0204' 18 F6' JR ERALIN
652 0206' RDBUF4: ; If CTL-R=True, do following code, else bypass
653 IF CTLREN
654 0206' FE 12 CP CONTR ; If ^R, type clean buffer version on console
655 0208' 20 24' JR NZ,RDBUF5
656 020A' E5 PUSH HL ; Save pointer to buffer length
657 020B' CD 02D2' CALL CROUT ; Do CR/LF
658 020E' 21 0026' LD HL,TABCNT
659 0211' 36 00 LD (HL),0 ; Init Tab count
660 0213' 23 INC HL
661 0214' 46 LD B,(HL) ; And get Tab offset count
662 0215' 3E 20 LD A,' '
663 0217' 04 inc b ; [1.1] insure nz value
664 0218' 18 03' jr rety1a ; [1.1] so case of lh side of screen ok
665 021A' CD 0264' RETYP1: CALL WRCON ; Space off start of line
666 021D' 10 FB' rety1a: DJNZ RETYP1
667 021F' E1 POP HL ; Point to buffer length
668 0220' 46 LD B,(HL) ; Get how many chars to print
669 0221' 23 INC HL ; Restore buffer pointer
670 0222' EB EX DE,HL ; Put buffer pointer in DE
671 0223' 04 INC B ; Comp for first DJNZ
672 0224' 18 05' JR RETYP3 ; Skip to done test
673 0226' 1A RETYP2: LD A,(DE) ; Get char from buffer
674 0227' CD 0253' CALL WRCTL ; Output it
675 022A' 13 INC DE ; Bump pointer
676 022B' 10 F9' RETYP3: DJNZ RETYP2 ; Loop until done
677 022D' C9 RET
678 ENDIF ; Ctlren
680 ; Toggle Line Printer Echo
682 022E' FE 10 RDBUF5: CP CONTP ; Toggle printer?
683 0230' 20 07' JR NZ,RDBUF6 ; Next test if not
684 0232' 21 0028' LD HL,FCONTP
685 0235' 7E LD A,(HL) ; Get printer echo flag
686 0236' 2F CPL ; Toggle it
687 0237' 77 LD (HL),A ; Put back
688 0238' C9 RET
690 ; Check if Control-C is First char in BUFF and Exit if so
692 0239' 12 RDBUF6: LD (DE),A ; Put character in buffer
693 023A' E5 PUSH HL
694 023B' CD 0253' CALL WRCTL ; Echo the character
695 023E' E1 POP HL
696 023F' 34 INC (HL) ; Increment the character count
698 0240' 7E LD A,(HL) ; Get current length
699 0241' B9 CP C ; Test against buffer size
700 0242' 28 0A' JR Z,RDBUFX
701 0244' 3D DEC A ; Set Z flag for first character
702 0245' 1A LD A,(DE) ; Get the character back
703 0246' 13 INC DE ; ..and bump the pointer
704 0247' C0 RET NZ ; Return if not the first character
ZMAC Relocating Macro Assembler v 1.7, page 19
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
705 0248' FE 03 CP CONTC ; Possible user abort?
706 024A' C0 RET NZ ; ..return if not
707 024B' C3 03CA' JP ERROR5 ; Else jump to error reset exit
709 ; Done with Read Console Buffer Function
711 024E' E1 RDBUFX: POP HL ; Clear RDBUF1 return address
712 024F' 3E 0D LD A,CR
713 0251' 18 11' JR WRCON ; ..and echo a CR
715 ; Print Control Character as '^X'
717 0253' FE 20 WRCTL: CP ' ' ; Test if control char
718 0255' 30 0D' JR NC,WRCON ; Not, send it out
719 0257' FE 09 CP TAB ; Test if Tab
720 0259' 28 0D' JR Z,WRCON0 ; It is, so expand with spaces
721 025B' F5 PUSH AF ; Save char
722 025C' 3E 5E LD A,'^' ; Output a karet
723 025E' CD 0277' CALL WRCON1 ; No need for Tab test here
724 0261' F1 POP AF
725 0262' C6 40 ADD A,40H ; Convert to printable
726 ; And fall thru to WRCON
728 ; Output char with List Echo, Tab Expansion (Function 2)
730 0264' FE 09 WRCON: CP TAB ; Is it a Tab?
731 0266' 20 0F' JR NZ,WRCON1 ; ..jump if not
732 0268' 3E 20 WRCON0: LD A,' ' ; Expand Tab with spaces
733 026A' CD 0277' CALL WRCON1 ; Write space
734 026D' 3A 0026' LD A,(TABCNT) ; Get Tab count
735 0270' E6 07 AND 7 ; Test if done
736 0272' 20 F4' JR NZ,WRCON0 ; No then repeat
737 0274' 3E 09 LD A,TAB ; Return Tab
738 0276' C9 RET ; Return to caller
740 0277' C5 WRCON1: PUSH BC
741 0278' D5 PUSH DE ; Save pointers
742 0279' 4F LD C,A
743 027A' C5 PUSH BC ; Save character
745 = 027C' BGPTCH0 EQU $+1 ;<-- BGii patches this address
747 027B' CD 02B7' CALL CMND11 ; Test status and CONTS/CONTC
748 027E' C1 POP BC ; Get character back
749 027F' C5 PUSH BC ; Save it again
750 0280' CD 000C* CALL CONOUT ; Output it
751 0283' C1 POP BC ; Get character back
752 0284' C5 PUSH BC ; Save it again
753 0285' 3A 0028' LD A,(FCONTP) ; Get printer echo flag
754 0288' B7 OR A ; Test it
755 0289' C4 000F* CALL NZ,LIST ; Non zero => output char to printer
756 028C' C1 POP BC ; Restore character
757 028D' 79 LD A,C ; Fall through to count routine
758 028E' D1 POP DE
759 028F' C1 POP BC ; Restore pointers
ZMAC Relocating Macro Assembler v 1.7, page 20
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
761 ; Count Characters in line as shown by f10
763 0290' 21 0026' LD HL,TABCNT ; Get pointer to Tab counter
764 0293' 34 WRCON2: INC (HL) ; Increment Tab counter
765 0294' FE 7F CP RUBOUT ; Test if character = Rubout
766 0296' 28 15' JR Z,WRCON3 ; Treat like Backspace
767 0298' FE 20 CP ' '
768 029A' D0 RET NC ; Ok if not Control
769 029B' FE 09 CP TAB ; Only DOBACK ever gets Tabs through here
770 029D' 28 11' JR Z,WRCON4 ; Handle differently if Tab
771 029F' FE 08 CP CONTH
772 02A1' 28 0A' JR Z,WRCON3 ; Or Backspace
773 02A3' 34 INC (HL) ; Must have been echoed as two chars
774 02A4' FE 0A CP LF
775 02A6' 28 05' JR Z,WRCON3 ; ..unless it's LF
776 02A8' FE 0D CP CR ; ..or CR
777 02AA' C0 RET NZ
778 02AB' 36 02 LD (HL),2 ; Reset Tab count
779 02AD' 35 WRCON3: DEC (HL) ; Decrement Tab counter
780 02AE' 35 DEC (HL)
781 02AF' C9 RET ; And exit
783 02B0' 3E 07 WRCON4: LD A,7 ; Bumped by one already
784 02B2' 86 ADD A,(HL) ; Tabs are every 8 spaces
785 02B3' E6 F8 AND 0F8H ; ...mod 8
786 02B5' 77 LD (HL),A ; Save updated Tab count
787 02B6' C9 RET ; ..and continue
789 ; Get Console Status - BGII uses this routine
791 02B7' BGCONST:
792 02B7' CD 0166' CMND11: CALL DCIO2 ; Get character present status
793 02BA' C8 RET Z ; ..exit if none
794 02BB' CD 0175' CALL GETCH ; Get next console char
795 02BE' FE 13 CP CONTS ; Is it stop char?
796 02C0' 20 0A' JR NZ,GCONS2 ; ..jump if Not
797 02C2' CD 0009* CALL CONIN ; Get next character
798 02C5' FE 03 CP CONTC ; Does the user want to exit (^C)?
799 02C7' 20 EE' JR NZ,CMND11 ; ..check for another character if not
800 02C9' C3 03CA' JP ERROR5 ; Else jump to warm boot & clear ERMODE
802 02CC' 32 0029' GCONS2: LD (LASTCH),A ; Save character
803 02CF' 3E 01 LD A,1 ; Character present code
804 02D1' C9 RET ; Return to caller
806 ; Echo CR,LF
808 02D2' 11 0349' CROUT: LD DE,MCRLF ; Fall through to output routine
810 ; Output Message
812 02D5' 1A CMND09: LD A,(DE) ; Get byte from buffer
813 02D6' FE 24 CP '$' ; Test last byte
814 02D8' C8 RET Z ; Yes, then return to caller
815 02D9' 13 INC DE ; Point to next byte
816 02DA' CD 0264' CALL WRCON ; Output character
ZMAC Relocating Macro Assembler v 1.7, page 21
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
817 02DD' 18 F6' JR CMND09 ; And test again
ZMAC Relocating Macro Assembler v 1.7, page 22
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
820 ;**********************************************
821 ;* E r r o r R o u t i n e s *
822 ;**********************************************
824 02DF' 01 0064 PRDEC: LD BC,100
825 02E2' CD 02ED' CALL NUM
826 02E5' 0E 0A LD C,10
827 02E7' CD 02ED' CALL NUM
828 02EA' 01 0101 LD BC,101H
830 ; Display Number
832 02ED' 16 FF NUM: LD D,-1 ; Load number -1
833 02EF' 14 NUM1: INC D ; Increment number
834 02F0' 91 SUB C ; Divide by C
835 02F1' 30 FC' JR NC,NUM1 ; Not finished then loop
836 02F3' 81 ADD A,C ; Restore last value
837 02F4' F5 PUSH AF ; Save it
838 02F5' 7A LD A,D ; Test if "0"
839 02F6' B0 OR B ; And if leading zero
840 02F7' 28 07' JR Z,NUM2 ; Yes, then exit
841 02F9' 47 LD B,A ; Set no leading zero
842 02FA' 7A LD A,D ; Get number
843 02FB' C6 30 ADD A,'0' ; Make ASCII
844 02FD' CD 0154' CALL PUTCH ; Echo number preserving BC
845 0300' F1 NUM2: POP AF ; Restore number
846 0301' C9 RET ; And exit
848 ; Error Messages
850 0302' 43 68 61 6E MDSKCH: DEFB 'Changed$'
852 030A' 42 61 64 20 MBADSC: DEFB 'Bad Sector$'
854 0315' 4E 6F 20 44 MSEL: DEFB 'No Drive$'
856 031E' 46 69 6C 65 MFILRO: DEFB 'File '
858 0323' 57 2F 50 24 MRO: DEFB 'W/P$'
859 IF ZS
860 0327' 5A 53 44 4F MBERR: DEFB 'ZSDOS'
863 ENDIF
864 032C' 20 65 72 72 DEFB ' error on $'
865
866 0337' 0D 0A 43 61 MBFUNC: DEFB CR,LF,'Call'
867 033D' 3A 20 24 MDRIVE: DEFB ': $'
869 0340' 20 20 46 69 MFILE: DEFB ' File: $'
871 0349' 0D 0A 24 MCRLF: DEFB CR,LF,'$'
873 ; New ZSDOS error handler - enter w/ error code in B and message pointer
874 ; in DE
876 034C' 3A 005C' ERROR: LD A,(ERMODE)
877 034F' 4F LD C,A ; Save error mode
ZMAC Relocating Macro Assembler v 1.7, page 23
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
878 0350' 0F RRCA ; Test supress print
879 0351' 38 5C' JR C,ERROR3 ; Suppressed, so skip dsp
881 ; Print ZSDOS Error on X: Explanation
883 0353' C5 PUSH BC
884 0354' D5 PUSH DE ; Save params
885 0355' CD 02D2' CALL CROUT ; Output CR/LF
886 0358' 11 0327' LD DE,MBERR
887 035B' CD 02D5' CALL CMND09 ; Output ZSDOS error on
888 035E' 3A 002B' LD A,(DEFDRV) ; Get current default drive
889 0361' C6 41 ADD A,'A' ; Convert to ascii
890 0363' CD 0264' CALL WRCON ; Output it to console
891 0366' 11 033D' LD DE,MDRIVE ; Point to drive tag
892 0369' CD 02D5' CALL CMND09 ; Put it also
893 036C' D1 POP DE ; Restore error message pointer
894 036D' CD 02D5' CALL CMND09 ; Send message
896 ; Now print CALL: XXX [FILE: XXXXXXXX.XXX]
898 0370' 11 0337' LD DE,MBFUNC
899 0373' CD 02D5' CALL CMND09 ; Display 'call: '
900 0376' 3A 004B' LD A,(FUNCT) ; Get function number
901 0379' CD 02DF' CALL PRDEC ; Output it
902 037C' 3A 004E' LD A,(FLDRV)
903 037F' A7 AND A ; Was FCB used?
904 0380' 28 29' JR Z,ERROR2 ; ..Skip file name display if not
905 0382' C1 POP BC
906 0383' C5 PUSH BC ; Get error type
907 0384' DDE5 PUSH IX ; Save FCB pointer
908 0386' 3A 004B' LD A,(FUNCT) ; ARE WE ERASING A FILE?
909 0389' FE 13 CP 19 ; IF SO, GET NAME FROM DIRBUF AS
910 038B' 20 04' JR NZ,ERROR0 ; AMBIG NAME MAY HAVE BEEN USED
911 038D' CD 06F1' CALL CALDIR ; Get DIR buffer pointer
912 0390' E3 EX (SP),HL ; To show what we really gagged on
913 0391' 11 0340' ERROR0: LD DE,MFILE
914 0394' CD 02D5' CALL CMND09 ; Output 'file: '
915 0397' E1 POP HL ; Point to FCB
916 0398' 06 0B LD B,11 ; Output this many chars
917 039A' 23 ERROR1: INC HL
918 039B' 3E 03 LD A,3
919 039D' B8 CP B ; Time to send '.'?
920 039E' 3E 2E LD A,'.' ; Get ready for it
921 03A0' CC 0154' CALL Z,PUTCH ; Send it if time
922 03A3' 7E LD A,(HL) ; Get char
923 03A4' E6 7F AND 7FH ; Mask attributes
924 03A6' CD 0154' CALL PUTCH ; Output it
925 03A9' 10 EF' DJNZ ERROR1
926 03AB' CD 02D2' ERROR2: CALL CROUT ; Send CR,LF
927 03AE' C1 POP BC ; Get error mode back
928 03AF' 3E 04 ERROR3: LD A,4
929 03B1' 90 SUB B ; Test if select error
930 03B2' 20 0D' JR NZ,ERROR4 ; Skip if not
931 03B4' 21 002C' ld hl,drive ; point to old default
932 03B7' 7E ld a,(hl) ; get it
933 03B8' 2B dec hl ; point to bad drive
ZMAC Relocating Macro Assembler v 1.7, page 24
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
934 03B9' BE cp (hl) ; same?
935 03BA' 28 05' jr z,error4 ; if so, skip relog
936 03BC' C5 PUSH BC
937 03BD' CD 0581' CALL SELDK ; Get BIOS back in step
938 03C0' C1 POP BC
939 03C1' CB49 ERROR4: BIT 1,C ; Test if return error mode
940 03C3' 20 18' JR NZ,ERROR7 ; Go if return error
941 03C5' 3E 01 LD A,1
942 03C7' 90 SUB B ; Test if fatal error
943 03C8' 30 05' JR NC,ERROR6 ; If not a fatal error
944 03CA' AF ERROR5: XOR A
945 03CB' 32 005C' LD (ERMODE),A ; Set DOS error mode to default CP/M
946 03CE' C7 RST 0 ; ..and leave
948 03CF' CD 0171' ERROR6: CALL DCIO1 ; Get console char if present
949 03D2' A7 AND A ; Test if any
950 03D3' 20 FA' JR NZ,ERROR6 ; Keep getting them until typeahead eaten
951 03D5' CD 0175' CALL GETCH ; Now get operator's response
952 03D8' FE 03 CP CONTC ; Test if abort
953 03DA' C0 RET NZ ; If operator said ignore error
954 03DB' 18 ED' JR ERROR5 ; Else boot
956 03DD' 78 ERROR7: LD A,B ; Get error
957 03DE' 67 LD H,A ; Save code in H reg for return
958 03DF' A7 AND A ; Test if disk changed warning
959 03E0' C8 RET Z ; Continue relog if so
960 03E1' 2E FF LD L,0FFH ; Set extended error code
961 03E3' 22 004C' LD (PEXIT),HL ; Save as return code
962 ; ..and fall thru to DOS exit
ZMAC Relocating Macro Assembler v 1.7, page 25
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
964 ;******************************************************
965 ;* D O S E x i t R o u t i n e *
966 ;******************************************************
968 03E6' 3A 004E' DOSEXIT: LD A,(FLDRV) ; Test drive select used flag
969 03E9' B7 OR A
970 03EA' 28 0C' JR Z,DOSEXT0 ; No then exit
971 03EC' 3A 002D' LD A,(FCB0) ; Get FCB byte 0
972 03EF' DD77 00 LD (IX+0),A ; Save it
973 03F2' 3A 002C' LD A,(DRIVE) ; Get old drive number
974 03F5' CD 0581' CALL SELDK ; Select disk
975 IF PICKEY
977 ENDIF
979 ; If the error handler was invoked, the stack is in an undefined
980 ; condition at this point. We therefore have to restore the user's
981 ; IX register independent of stack position. Thanks to Joe Wright's
982 ; eagle eye for catching this one!
984 03F8' ED7B 0061' DOSEXT0: LD SP,(SPSAVE) ; Restore user stack
985 03FC' DD2A 0099' LD IX,(IXSAVE) ; Restore IX (stack is don't care)
986 0400' 2A 004C' LD HL,(PEXIT) ; Get exit code
987 IF NOT PICKEY
988 0403' ED5B 005F' LD DE,(DEVAL) ; And DE reg for DateStamper
989 ENDIF
990 0407' 7D LD A,L ; Copy function code
991 0408' 44 LD B,H
992 0409' C9 RET ; And return to caller
ZMAC Relocating Macro Assembler v 1.7, page 26
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
994 ;******************************************************
995 ;* D i s k F u n c t i o n s *
996 ;******************************************************
998 ; Reset Disk System
1000 040A' 21 0080 CMND13: LD HL,RAMLOW+0080H ; Set up DMA address
1001 040D' 22 002E' LD (DMA),HL ; And save it
1002 0410' CD 0837' CALL STDMA ; Do BIOS call
1003 0413' AF XOR A ; Set default drive = 'A'
1004 0414' 32 002B' LD (DEFDRV),A ; Save it
1005 0417' 11 FFFF LD DE,0FFFFH ; Reset all drives
1007 ; Reset Multiple Login Drive - DE = Reset mask
1008 ; Fixed Disk Login vector is also altered by this call
1010 041A' CD 045D' CMND37: CALL UNLOG ; Clear selected drives in DE from login
1011 041D' 3A 0015' LD A,(FLAGS)
1012 0420' CB57 BIT 2,A ; Test hard R/O enabled
1013 0422' 20 06' JR NZ,UNWPT1 ; If enabled
1014 0424' 21 0DFC' LD HL,DSKWP ; Get drive W/P vector
1015 0427' CD 0466' CALL ANDDEM ; Reset W/P stat only of requested drvs
1016 042A' 3A 004B' UNWPT1: LD A,(FUNCT)
1017 042D' FE 0D CP 13 ; Skip hard disk login change?
1018 042F' 21 0DFE' LD HL,HDLOG
1019 0432' C4 0466' CALL NZ,ANDDEM ; Clear HD Login Vector if Fcn 37
1020 0435' RELOG1:
1021 IF ZS
1022 0435' 2A 0DFE' LD HL,(HDLOG)
1023 0438' CD 0658' CALL HLORDE ; Don't clear fixed disks from T/D
1024 043B' EB EX DE,HL ; Place modified logout in DE
1025 043C' 21 0DF8' LD HL,TDFVCT
1026 043F' CD 0466' CALL ANDDEM ; Clear T/D vector as needed
1027 ENDIF
1029 0442' 3A 002B' LD A,(DEFDRV) ; Get default drive
1030 0445' F5 PUSH AF
1031 0446' RELOG2:
1032 IF RESDSK ; (bh)
1034 ELSE
1035 0446' 00 00 00 DEFB 0,0,0 ; Make 3 NOP's to keep constant code (hfb)
1036 ENDIF ; (bh)
1037 0449' F1 POP AF
1038 044A' CD 0581' CALL SELDK ; Select default drive
1040 ; ZSDOS watches for any $*.* in any user on any drive during re-log,
1041 ; make, and delete. In this manner, SUBFLG will always be valid -
1042 ; even under fast relog and NZCOM! Thanks to Joe Wright for suggesting
1043 ; the need for this, and suggesting ways to do it.
1045 044D' 3A 0057' SUBEXT: LD A,(SUBFLG) ; Get submit flag
1046 0450' 18 69' JR SAVEA ; Exit
1048 ; Check for possible existance of submit file by checking first
1049 ; byte of dir entry or FCB for '$'. Pointer to dir or FCB passed
1050 ; to routine in HL.
ZMAC Relocating Macro Assembler v 1.7, page 27
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1052 0452' 23 CKSUB: INC HL ; Point to file name
1053 0453' 7E LD A,(HL) ; Get first char filename
1054 0454' 2B DEC HL
1055 0455' D6 24 SUB '$' ; Test if '$'
1056 0457' C0 RET NZ ; Not then exit
1057 0458' 3D DEC A ; Load a with 0FFH
1058 0459' 32 0057' LD (SUBFLG),A ; Save it in subflg
1059 045C' C9 RET
1061 ; Unlog Drive mask in DE
1063 045D' 7B UNLOG: LD A,E ; Get LSB
1064 045E' 2F CPL ; Complement it
1065 045F' 5F LD E,A
1066 0460' 7A LD A,D ; Get MSB
1067 0461' 2F CPL ; Complement it
1068 0462' 57 LD D,A ; DE = not reset
1069 0463' 21 0DFA' LD HL,LOGIN ; Get addr of login vector
1070 0466' 7B ANDDEM: LD A,E ; Clear login bits of reset drives
1071 0467' A6 AND (HL) ; ..a byte at a time
1072 0468' 77 LD (HL),A ; Put to memory
1073 0469' 23 INC HL
1074 046A' 7A LD A,D
1075 046B' A6 AND (HL)
1076 046C' 77 LD (HL),A
1077 046D' C9 RET
1079 ; Search for File
1081 046E' CD 051F' CMND17: CALL SELDRV ; Select drive from FCB
1082 0471' DD7E 00 LD A,(IX+0)
1083 0474' D6 3F SUB '?' ; Test if '?'
1084 0476' 28 0D' JR Z,CMD17B ; If so all entries match
1085 0478' DD7E 0E LD A,(IX+FCBMOD) ; Get system byte
1086 047B' FE 3F CP '?' ; Test if '?'
1087 047D' 28 04' JR Z,CMD17A ; Yes, jump
1088 047F' DD36 000E LD (IX+FCBMOD),0 ; Load system byte with Zero
1089 0483' 3E 0F CMD17A: LD A,15 ; Test first 15 items in FCB
1090 0485' CD 08F3' CMD17B: CALL SEARCH ; Do search
1091 0488' 2A 0034' CMD17C: LD HL,(DIRBUF) ; Copy directory buffer
1092 048B' 01 0080 LD BC,128 ; Directory=128 bytes
1093 048E' ED5B 002E' MV2DMA: LD DE,(DMA) ; To DMA address
1094 0492' EDB0 LDIR
1095 0494' C9 RET ; Exit
1097 ; Search for Next Occurence of File
1099 0495' DD2A 0058' CMND18: LD IX,(DCOPY) ; Get last FCB used by search
1100 0499' DD22 005D' LD (ARWORD),IX ; Save FCB pointer for BGii
1101 049D' CD 051F' CALL SELDRV ; Select drive from FCB
1102 04A0' CD 090A' CALL SEARCN ; Search next file match
1103 04A3' 18 E3' JR CMD17C ; And copy directory to DMA address
1105 ; Delete File
ZMAC Relocating Macro Assembler v 1.7, page 28
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1107 04A5' CD 051F' CMND19: CALL SELDRV ; Select drive from FCB
1108 04A8' CD 086D' CALL DELETE ; Delete file
1109 04AB' 3A 005A' CMD19A: LD A,(SEAREX) ; Get exit byte 00=file found, 0FFH=Not
1110 04AE' 18 0B' JR SAVEA ; And exit
1112 ; Rename File
1114 04B0' CD 051F' CMND23: CALL SELDRV ; Select drive from FCB
1115 04B3' CD 09D7' CALL RENAM ; Rename file
1116 04B6' 18 F3' JR CMD19A ; And exit
1118 ; Return Current Drive
1120 04B8' 3A 002B' CMND25: LD A,(DEFDRV) ; Get current drive
1121 04BB' 32 004C' SAVEA: LD (PEXIT),A ; Return character
1122 04BE' C9 DUMMY: RET ; ..and exit ZSDOS
1124 ; Set flags
1126 04BF' 32 0015' CMD101: LD (FLAGS),A ; Set ZSDOS flags
1127 ; ..and fall thru
1128 ; Get flags
1130 04C2' 3A 0015' CMD100: LD A,(FLAGS) ; Get ZSDOS flags
1131 04C5' 18 F4' JR SAVEA ; ..and exit
1133 ; Change Status
1135 04C7' CD 051F' CMND30: CALL SELDRV ; Select drive from FCB
1136 04CA' CD 0A02' CALL CSTAT ; Change status
1137 04CD' 18 DC' JR CMD19A ; And exit
1139 ; Return CP/M Version Number
1141 04CF' ZDPCH1:
1142 04CF' 21 0022 CMND12: LD HL,22H ; Set CP/M compatable version number
1143 IF NOT ZS ; (crw)
1152 ENDIF
1153 IF NOT PICKEY
1154 04D2' ED53 005F' LD (DEVAL),DE ; In case DS gave us a clock addr
1155 ENDIF
1156 04D6' 18 1B' JR SAVHL ; For speed
1158 ; Following commands return status in like manner and are consolidated here
1159 ; in selected order with least-accessed commands taking longest to traverse
1160 ; string, and frequently accessed/time critical exitting quickest.
1162 ; The code in this section is a bit obscure, as it depends on burying
1163 ; instructions within other instructions. 6502 users have long used the
1164 ; 'BIT' trick to skip instructions - this inspired me to see if similar
1165 ; things could be done with the Z80. Indeed they can, as this demonstrates.
1166 ; When the Z80 jumps in at a label, it executes the LD HL instruction. The
1167 ; DEFB 0DDH turns the LD HL instructions that follow into LD IX. In effect,
1168 ; this turns the DEFB 0DDH into a one byte relative jump to SAVHL. As IX
1169 ; is never used by these calls, its loss is of no consequence.
1170 ; A similar trick is used in SEAR15, resulting in a useless LD HL but
ZMAC Relocating Macro Assembler v 1.7, page 29
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1171 ; saving a byte.
1173 ; New Universal Return Version FUNCTION 48
1175 04D8' CMND48:
1176 IF ZS
1177 04D8' 21 5311 LD HL,'S' SHL 8 + VERS ;"S" indicates ZSDOS - ZRDOS returns 0
1180 ENDIF
1181 04DB' DD DEFB 0DDH ; Trash IX and fall through
1183 ; Return Disk W/P Vector
1185 04DC' 2A 0DFC' CMND29: LD HL,(DSKWP) ; Get disk W/P vector
1186 04DF' DD DEFB 0DDH ; Trash IX and fall through
1188 ; Return Fixed Disk Login Vector
1190 04E0' 2A 0DFE' CMND39: LD HL,(HDLOG) ; Return fixed disk login vector
1191 04E3' DD DEFB 0DDH ; Trash IX and fall through
1193 ; Return ALV Vector
1195 04E4' 2A 003A' CMND27: LD HL,(ALV) ; Get allocation vector
1196 04E7' DD DEFB 0DDH ; Trash IX and fall through
1198 ; Return Login Vector
1200 04E8' 2A 0DFA' CMND24: LD HL,(LOGIN) ; Get login vector
1201 04EB' DD DEFB 0DDH ; Trash IX and fall through
1203 ; Return Drive Table
1205 04EC' 2A 0036' CMND31: LD HL,(IXP) ; Get drive table
1206 04EF' DD DEFB 0DDH ; Trash IX and fall through
1208 ; Return Current DMA
1210 04F0' 2A 002E' CMND47: LD HL,(DMA) ; Return current DMA addr
1211 04F3' 22 004C' SAVHL: LD (PEXIT),HL ; Save it
1212 04F6' C9 RET ; And exit
1214 ; Set BDOS Error Mode
1216 04F7' 32 005C' CMND45: LD (ERMODE),A ; Save error mode
1217 04FA' C9 RET ; And exit
1219 ; Set/Get User Code
1221 04FB' 21 002A' CMND32: LD HL,USER ; Point to user byte location
1222 04FE' 3C INC A ; Test if 0FFH
1223 04FF' 7E LD A,(HL) ; Get old user code
1224 0500' 28 B9' JR Z,SAVEA ; If 0FFH then exit
1225 0502' 7B LD A,E ; Get new user code
1226 0503' E6 1F AND 01FH ; Mask it
1227 0505' 77 LD (HL),A ; Save it
1228 0506' C9 RET ; And exit
ZMAC Relocating Macro Assembler v 1.7, page 30
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1230 ; Compute File Size Command
1232 0507' CD 052D' CMND35: CALL SELDR1 ; Select drive from FCB
1233 050A' CD 0A2B' CALL FILSZ ; Compute file size
1234 050D' 18 9C' JR CMD19A ; And exit
1236 ; Set Random Record Count
1238 050F' 21 0020 CMND36: LD HL,32 ; Set pointer to next record
1239 0512' CD 0D7F' CALL CALRRC ; Calculate random record count
1240 0515' DD72 21 LDRRC: LD (IX+33),D ; And save random record count
1241 0518' DD71 22 LD (IX+34),C
1242 051B' DD70 23 LD (IX+35),B
1243 051E' C9 RET ; And exit
1245 ; Select Disk From FCB
1247 051F' BGSELDRV:
1248 051F' 3A 005C' SELDRV: LD A,(ERMODE) ; Are we in modified user mode?
1249 0522' A7 AND A
1250 0523' 20 08' JR NZ,SELDR1 ; Jump if so, else..
1251 0525' 2A 005D' LD HL,(ARWORD) ;
1252 0528' 01 000D LD BC,FCBUSR ; Point to user number
1253 052B' 09 ADD HL,BC ;
1254 052C' 77 LD (HL),A ; Clear user flag
1255 052D' 3E FF SELDR1: LD A,0FFH ; Set disk select done flag
1256 052F' 32 004E' LD (FLDRV),A
1257 0532' 3A 002B' LD A,(DEFDRV) ; Get current drive
1258 0535' 5F LD E,A ; Save it in register E
1259 0536' 2A 005D' LD HL,(ARWORD)
1260 0539' 7E LD A,(HL) ; Get drive from FCB
1261 053A' 32 002D' LD (FCB0),A ; Save it
1262 053D' FE 3F CP '?' ; Test if '?'
1263 053F' 28 39' JR Z,CMND14 ; Yes, then select drive from register E
1264 0541' DDE5 PUSH IX ; Save BGii's IX register
1265 ; IX won't be altered on cmnd14
1266 0543' DD2A 005D' LD IX,(ARWORD) ; Get FCB pointer
1267 ;1.1a Changed to allow proper access to Drive P:
1268 ;1.2a AND 0FH ; Mask drive
1269 0547' E6 1F AND 1FH ;1.2a Mask Drive
1270 0549' E5 PUSH HL
1271 054A' 28 02' JR Z,SELDR0 ; Select drive from register E
1272 054C' 5E LD E,(HL) ; Get drive from FCB
1273 054D' 1D DEC E ; Decrement drive number so A=0
1274 054E' CD 057A' SELDR0: CALL CMND14 ; - do select of drive
1275 0551' E1 POP HL ; Restore FCB pointer
1277 ; Resolve User for FCB - FCBPTR in IX, Returns User in A
1279 0552' DD7E 0D LD A,(IX+FCBUSR) ; ..get potential user in case
1280 0555' CB7F BIT 7,A ; Is this a valid user?
1281 0557' 20 07' JR NZ,RESUS1 ; Skip if there is
1282 0559' 3A 002A' LD A,(USER) ; Get user number
1283 055C' 18 02' JR RESUS1 ; ..and bypass push IX
ZMAC Relocating Macro Assembler v 1.7, page 31
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1285 ; Set User in FCB to Value passed in A
1287 055E' DDE5 RESUSR: PUSH IX ; Preserve IX
1288 0560' DD2A 005D' RESUS1: LD IX,(ARWORD)
1289 0564' E6 1F AND 1FH ; User number in A
1290 0566' DD77 00 LD (IX+0),A ; Save in FCB 0 byte
1291 0569' F6 80 OR 80H ; Set valid DOS user flag
1292 056B' DD77 0D LD (IX+FCBUSR),A ; ..and in FCB 13 byte
1293 056E' DDE1 POP IX ; Restore caller's IX
1294 0570' C9 RET
1296 ; Select Disk Error Exit - The stack is off by one level here, but
1297 ; this is a one way trip anyway.
1299 0571' 2A 000B' SELDK3: LD HL,(STSEL) ; Load error message address
1300 0574' 06 04 LD B,4 ; Select error
1301 0576' 11 0315' LD DE,MSEL ; Load select error message
1302 0579' E9 JP (HL) ; And display error
1304 ; Select Disk from E register
1306 057A' 3A 002B' CMND14: LD A,(DEFDRV) ; Get current drive
1307 057D' 32 002C' LD (DRIVE),A ; Save it in memory
1308 0580' 7B LD A,E ; Copy drive number
1310 ; Select Disk
1311 ; Call w/ A = Drive Number (0..15 = A..P)
1313 0581' 2A 0DFA' SELDK: LD HL,(LOGIN) ; Get login vector
1314 0584' E6 0F AND 0FH ; Mask drive number
1315 0586' 47 LD B,A ; Save counter
1316 0587' C4 0661' CALL NZ,SHRHLB ; ..and rotate into position
1317 058A' EB SELDK0: EX DE,HL ; Put drive bit mask in DE
1318 058B' 21 002B' LD HL,DEFDRV ; Get pointer last drive
1319 058E' CB43 BIT 0,E ; Test if drive logged in
1320 0590' 28 02' JR Z,SELDK2 ; No, login drive
1321 0592' BE CP (HL) ; Test same drive
1322 0593' C8 RET Z ; Yes then exit
1324 ; NOTE: A long standing DOS bug concerns the SELECT function. If a
1325 ; function 14 call is made and the drive doesn't exist, the default
1326 ; will still point to the bad drive unless we fix it in the error
1327 ; routine. It is for this reason that drive is saved above. We must
1328 ; allow default to assume the illegal drive value long enough for the
1329 ; error handler to print it, then re-select the old default.
1331 0594' 77 SELDK2: LD (HL),A ; Save new current drive
1332 0595' D5 PUSH DE ; Save drive logged in flag
1333 0596' 4F LD C,A ; Copy drive number
1334 0597' CD 001B* CALL SELDSK ; Do BIOS select
1335 059A' 7C LD A,H ; Test if error
1336 059B' B5 OR L
1337 059C' 28 D3' JR Z,SELDK3 ; Yes, illegal drive number
1338 059E' 11 0030' LD DE,TRANS ; Point to local translation store
1339 05A1' 01 0002 LD BC,2 ; ..and move 2-byte ptr in
1340 05A4' EDB0 LDIR
ZMAC Relocating Macro Assembler v 1.7, page 32
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1341 05A6' 22 0032' LD (TEMP0),HL ; Save address temp0
1342 05A9' 0E 06 LD C,6 ; Advance to dirbuf part of DPH
1343 05AB' 09 ADD HL,BC ; As TEMP1 and TEMP2 unused in P?DOS
1344 05AC' 11 0034' LD DE,DIRBUF ; Load DIRBUF pointer
1345 05AF' 0E 08 LD C,8 ; Copy 8 bytes
1346 05B1' EDB0 LDIR
1347 05B3' 2A 0036' LD HL,(IXP) ; Get drive parameter address
1348 05B6' 0E 0F LD C,15 ; Copy 15 bytes
1349 05B8' EDB0 LDIR
1350 05BA' D1 POP DE ; Get drive logged in flag
1351 05BB' CB43 BIT 0,E ; Test it
1352 05BD' C0 RET NZ ; Drive logged in so return
1353 05BE' CD 0647' CALL GETCDM
1354 05C1' EB EX DE,HL ; Drive mask in DE
1355 05C2' 2A 0DFA' LD HL,(LOGIN) ; Get login vector
1356 05C5' CD 0658' CALL HLORDE ; Set drive bit in login vector
1357 05C8' 22 0DFA' LD (LOGIN),HL ; Save login vector
1358 05CB' 3A 0015' LD A,(FLAGS) ; Get flags
1359 05CE' CB5F BIT 3,A ; Fast relog enabled?
1360 05D0' 28 2A' JR Z,INITDR ; Skip if disabled
1362 ; The following code checks the WACD size to determine if the drive
1363 ; being selected is a fixed disk. If the WACD size is 0, the disk
1364 ; is Non-Removable. However, several BIOSes support remapping of
1365 ; logical drives. This complicates matters because BDOS must catch
1366 ; the swap and clear the Hard Disk Allocation Vector and allow the
1367 ; allocation bitmaps to be rebuilt. Thus, every disk that is being
1368 ; selected for the first time traverses this code. If a disk was
1369 ; logged as a fixed disk and all of the sudden has a WACD buffer,
1370 ; the Fixed Disk Login Vector is cleared. Thus, for Bug-free
1371 ; operation of Fast Fixed Disk Logging, if drives are swapped
1372 ; NEVER SWAP TWO FIXED DRIVES!
1374 05D2' 2A 0047' LD HL,(NCHECK) ; Is this a fixed drive?
1375 05D5' 7C LD A,H
1376 05D6' B5 OR L
1377 05D7' 4F LD C,A ; Save fixed disk flag (Z=true)
1378 05D8' 2A 0DFE' LD HL,(HDLOG)
1379 05DB' 7B LD A,E ; See if logged as fixed disk
1380 05DC' A5 AND L
1381 05DD' 6F LD L,A
1382 05DE' 7A LD A,D
1383 05DF' A4 AND H ; MSB
1384 05E0' B5 OR L ; Z flag set if HL and DE = 0
1385 05E1' 3E FF LD A,0FFH ; Don't alter flags
1386 05E3' 28 01' JR Z,SELDK4 ; If not logged as fixed disk
1387 05E5' 3C INC A ; Else flag as logged
1388 05E6' 47 SELDK4: LD B,A ; Save logged as fixed disk flag (Z=true)
1389 05E7' B1 OR C ; Test if still fixed disk
1390 05E8' C8 RET Z ; Skip re-map if logged and not swapped
1391 05E9' AF XOR A
1392 05EA' 67 LD H,A
1393 05EB' 6F LD L,A ; Null vector
1394 05EC' B0 OR B ; Was it logged as a fixed disk?
1395 05ED' 28 0A' JR Z,SELDK5 ; Invalidate HDLOG vector - drive no longer
1396 ; Fixed disk
ZMAC Relocating Macro Assembler v 1.7, page 33
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1397 05EF' 79 LD A,C
1398 05F0' B7 OR A ; Wasn't fixed disk before - is it now?
1399 05F1' 20 09' JR NZ,INITDR ; Skip vector update if it isn't
1400 05F3' 2A 0DFE' LD HL,(HDLOG)
1401 05F6' CD 0658' CALL HLORDE ; Else add this drive to fixed disk vector
1402 05F9' 22 0DFE' SELDK5: LD (HDLOG),HL ; Update fixed disk vector
1403 ;..fall thru to INITDR
1405 ; Init Drive
1406 ; Clear ALV Bit Buffer after Drive reset
1408 05FC' 2A 0041' INITDR: LD HL,(MAXLEN) ; Get length ALV buffer-1 (bits)
1409 05FF' CD 065F' CALL SHRHL3 ; Divide by 8 to get bytes
1410 0602' 44 LD B,H
1411 0603' 4D LD C,L ; Counter to BC (will be count+1 cleared)
1412 0604' 2A 003A' LD HL,(ALV) ; Get pointer ALV buffer
1413 0607' E5 PUSH HL
1414 0608' 54 LD D,H
1415 0609' 5D LD E,L
1416 060A' 13 INC DE ; ALV buffer +1 in DE
1417 060B' AF XOR A
1418 060C' 77 LD (HL),A ; Clear first 8 bits
1419 060D' EDB0 LDIR ; And remainder of buffer
1420 060F' E1 POP HL ; Get ALV pointer
1421 0610' ED5B 0045' LD DE,(NDIR0) ; Get first two bytes ALV buffer
1422 0614' 73 LD (HL),E ; Save LSB
1423 0615' 23 INC HL ; Increment pointer
1424 0616' 72 LD (HL),D ; Save MSB
1425 0617' 2A 0032' LD HL,(TEMP0) ; Clear number of files on this drive
1426 061A' 77 LD (HL),A ; Clear LSB (A still has 0)
1427 061B' 23 INC HL ; Increment pointer
1428 061C' 77 LD (HL),A ; Clear MSB
1430 = 061D' ZDPCH2 EQU $ ;<-- Intercept first scan (ZDS Patch)
1431 061D' CD 06FC' CALL SETFCT ; Set file count
1432 0620' 3E FF INITD2: LD A,0FFH ; Update directory checksum
1433 0622' CD 0730' CALL RDDIR ; Read FCB's from directory
1434 0625' CD 071C' CALL TSTFCT ; Test last FCB
1435 0628' CA 044D' JP Z,SUBEXT ; Return subflg for strict CP/M compat (hfb)
1436 062B' CD 06F1' CALL CALDIR ; Calculate entry point FCB
1437 062E' 7E LD A,(HL) ; Get first byte FCB
1438 062F' FE E5 CP 0E5H ; Test empty directory entry
1439 0631' 28 ED' JR Z,INITD2 ; Yes then get next FCB
1440 0633' FE 21 CP 021H ; Test time stamp
1441 0635' 28 E9' JR Z,INITD2 ; Yes then get next FCB
1443 = 0637' ZDPCH3 EQU $ ;<-- Test for T&D if first time (ZDS Patch)
1444 0637' CD 0452' CALL CKSUB ; Test for submit file
1445 063A' 0E 01 LD C,1 ; Set bit in ALV buffer
1446 063C' CD 0883' CALL FILLBB ; Set bits from FCB in ALV buffer
1447 063F' CD 0723' CALL TSTLF ; Test for last file
1448 0642' D4 0714' CALL NC,SETLF0 ; ..and update the last file count if so
1449 0645' 18 D9' JR INITD2 ; And get next FCB
1451 ; Return Mask for Current Drive in HL
ZMAC Relocating Macro Assembler v 1.7, page 34
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1453 0647' 21 0000 GETCDM: LD HL,0 ; No drives to Or
1455 ; Set Drive bit in HL
1457 064A' EB SDRVB: EX DE,HL ; Copy HL=>DE
1458 064B' 21 0001 LD HL,1 ; Get mask drive "A"
1459 064E' 3A 002B' LD A,(DEFDRV) ; Get current drive
1460 0651' B7 OR A ; Test if drive "A"
1461 0652' 28 04' JR Z,HLORDE ; Yes then done
1462 0654' 29 SDRVB0: ADD HL,HL ; Get next mask
1463 0655' 3D DEC A ; Decrement drive counter
1464 0656' 20 FC' JR NZ,SDRVB0 ; And test if done
1465 0658' 7A HLORDE: LD A,D ; HL=HL or DE
1466 0659' B4 OR H
1467 065A' 67 LD H,A
1468 065B' 7B LD A,E
1469 065C' B5 OR L
1470 065D' 6F LD L,A
1471 065E' C9 RET ; Exit
1473 065F' 06 03 SHRHL3: LD B,3 ; Used in a few places
1475 ; Shift HL right logical B bits
1477 0661' CB3C SHRHLB: SRL H
1478 0663' CB1D RR L ; Shift HL right one bit (divide by 2)
1479 0665' 10 FA' DJNZ SHRHLB
1480 0667' C9 RET
1482 ; Calculate Sector/Track Directory
1484 0668' 2A 0054' STDIR: LD HL,(FILCNT) ; Get FCB counter directory
1485 IF UNROLL
1486 066B' CB3C SRL H
1487 066D' CB1D RR L
1488 066F' CB3C SRL H ; (net cost: 3)
1489 0671' CB1D RR L ; Divide by 4 (inline for speed)
1493 ENDIF
1494 0673' 22 0052' LD (RECDIR),HL ; Save value (used by checksum)
1495 0676' EB STDIR2: EX DE,HL ; Copy it to DE
1496 0677' 21 0000 STDIR1: LD HL,0 ; Clear HL
1498 ; Calculate Sector/Track
1499 ; Entry: HL,DE=Sector Number (128 byte sector)
1500 ; Result Set Track =HL,DE / MAXSEC
1501 ; Set Sector =HL,DE MOD MAXSEC
1503 067A' ED4B 003C' CALST: LD BC,(MAXSEC) ; Get sectors/track
1504 067E' 3E 11 LD A,17 ; Set up loop counter
1505 0680' B7 CALST0: OR A
1506 0681' ED42 SBC HL,BC ; HL > BC?
1507 0683' 3F CCF
1508 0684' 38 02' JR C,CALST1 ; Yes then jump
1509 0686' 09 ADD HL,BC ; No then restore HL
1510 0687' B7 OR A ; Clear Carry
1511 0688' CB13 CALST1: RL E ; Shift result in DE
ZMAC Relocating Macro Assembler v 1.7, page 35
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1512 068A' CB12 RL D
1513 068C' 3D DEC A ; Test last bit done
1514 068D' 28 04' JR Z,CALST2 ; Yes then exit
1515 068F' ED6A ADC HL,HL ; Shift next bit in HL
1516 0691' 18 ED' JR CALST0 ; Continue
1518 0693' E5 CALST2: PUSH HL ; Save sector number
1519 0694' 2A 0049' LD HL,(NFTRK) ; Get first track
1520 0697' 19 ADD HL,DE ; Add track number
1521 0698' 44 LD B,H ; Copy it to BC
1522 0699' 4D LD C,L
1523 069A' CD 001E* CALL SETTRK ; CBIOS call Set Track
1524 069D' C1 POP BC ; Restore sector number
1525 069E' ED5B 0030' LD DE,(TRANS) ; Get translation table address
1526 06A2' CD 0030* CALL SECTRN ; CBIOS call sector translation
1527 06A5' 44 LD B,H ; Copy result to BC
1528 06A6' 4D LD C,L
1529 06A7' C3 0021* JP SETSEC ; BIOS call Set Sector
1531 ; Get Disk Map Block Number from FCB (Squeezed by Joe Wright)
1532 ; Exit HL=Address FCB
1533 ; DE=DM
1534 ; BC=Offset in DM
1535 ; Zero Flag Set (Z) if DM=0, Else reset (NZ)
1537 06AA' DD6E 20 GETDM: LD L,(IX+NXTREC) ; Get record number in L
1538 06AD' CB15 RL L ; Shift it left once
1539 06AF' 3A 0040' LD A,(NEXTND) ; Get EXM
1540 06B2' DDA6 0C AND (IX+FCBEXT) ; And the extent number
1541 06B5' 67 LD H,A ; To H
1542 06B6' 3A 003E' LD A,(NBLOCK) ; Get BSH
1543 06B9' 47 LD B,A ; To B
1544 06BA' 04 INC B ; +1
1545 06BB' CD 0661' CALL SHRHLB ; Shift HL right B times
1546 06BE' 50 LD D,B ; Zero to D
1547 06BF' 7D LD A,L ; Result to A
1549 06C0' 2A 005D' GETDM4: LD HL,(ARWORD)
1550 06C3' 0E 10 LD C,16 ; Add offset 16 to point to DM
1551 06C5' 09 ADD HL,BC
1552 06C6' 4F LD C,A ; Add entry FCB
1553 06C7' 09 ADD HL,BC
1554 06C8' 3A 0042' LD A,(MAXLEN+1) ; Test 8 bits/16 bits FCB entry
1555 06CB' B7 OR A
1556 06CC' 5E LD E,(HL) ; Get 8 bit value
1557 06CD' 28 05' JR Z,GETDMX ; ..and exit if 8-bit entries
1559 06CF' 09 ADD HL,BC ; Add twice (16 bit values)
1560 06D0' 5E LD E,(HL) ; Get LSB
1561 06D1' 23 INC HL ; Increment pointer
1562 06D2' 56 LD D,(HL) ; Get MSB
1563 06D3' 2B DEC HL ; Decrement pointer
1564 06D4' 7A GETDMX: LD A,D ; Check for zero DM value
1565 06D5' B3 OR E
1566 06D6' C9 RET ; And exit
ZMAC Relocating Macro Assembler v 1.7, page 36
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1568 ; Calculate Sector Number
1569 ; Entry: DE=Block Number from FCB
1571 06D7' 21 0000 CALSEC: LD HL,0 ; Clear MSB sector number
1572 06DA' 3A 003E' LD A,(NBLOCK) ; Get loop counter
1573 06DD' 47 LD B,A ; Save it in B
1574 06DE' EB EX DE,HL
1575 06DF' 29 CALSC0: ADD HL,HL ; Shift L,D,E
1576 06E0' CB13 RL E
1577 06E2' 10 FB' DJNZ CALSC0 ; B times
1578 06E4' EB EX DE,HL
1579 06E5' 3A 003F' LD A,(NMASK) ; Get sector mask
1580 06E8' DDA6 20 AND (IX+NXTREC) ; And with next record
1581 06EB' B3 OR E ; Set up LSB sector number
1582 06EC' 5F LD E,A
1583 06ED' C9 RET ; And exit
1585 ; Check for File Read-Only status, then fall thru to CALDIR
1587 06EE' CD 08AC' CKRODI: CALL CHKFRO ; Abort if the file is R/O
1588 ; ..fall thru..
1590 ; Calculate DIRBUF Entry Point
1592 06F1' 3A 0056' CALDIR: LD A,(SECPNT) ; Get sector pointer
1593 06F4' CALDIR1: ; New label for DS (crw)
1594 06F4' 2A 0034' LD HL,(DIRBUF) ; Get start address dirbuf
1595 06F7' 85 CALDI0: ADD A,L ; Add L=L+A
1596 06F8' 6F LD L,A
1597 06F9' D0 RET NC ; No carry exit
1598 06FA' 24 INC H ; Increment H
1599 06FB' C9 RET ; And exit
1601 ; Init File Count
1603 06FC' 21 FFFF SETFCT: LD HL,-1 ; Set up file count
1604 06FF' 22 0054' LD (FILCNT),HL ; Save it
1605 0702' C9 RET ; And exit
1607 ; Set Write Protect Disk Command (relocated & compressed hfb)
1609 0703' CMND28: ; Set read only disk
1610 0703' 2A 0DFC' LD HL,(DSKWP) ; Get disk W/P vector
1611 0706' CD 064A' CALL SDRVB ; Include drive bit
1612 0709' 22 0DFC' LD (DSKWP),HL ; Save disk W/P vector
1613 070C' ED5B 0043' LD DE,(NFILES) ; Get max number of files-1 (bumped below)
1614 0710' 2A 0032' LD HL,(TEMP0) ; Get pointer to disk parameter block
1615 0713' 23 INC HL ; Correct pointer..
1616 ; Setlf0 relocated in-line here (hfb)
1617 0714' 13 SETLF0: INC DE ; Increment last file
1618 0715' 72 LD (HL),D ; Save it in TEMP0
1619 0716' 2B DEC HL
1620 0717' 73 LD (HL),E
1621 0718' C9 RET ; And exit
1623 ; Search using first 15 bytes of FCB, test if found
ZMAC Relocating Macro Assembler v 1.7, page 37
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1625 0719' CD 08F1' SRCT15: CALL SEAR15 ; Search on 15-bytes..(consolidated-hfb)
1626 ; ..fall thru to test presence..
1627 ; Test File Count
1629 071C' 2A 0054' TSTFCT: LD HL,(FILCNT) ; Test file count=0FFFFH
1630 071F' 7C LD A,H ; Get MSB
1631 0720' A5 AND L ; And LSB
1632 0721' 3C INC A ; Test if result=0FFH
1633 0722' C9 RET ; And exit
1635 ; Test Last File
1637 0723' 2A 0032' TSTLF: LD HL,(TEMP0) ; Get pointer to last file
1638 0726' ED5B 0054' LD DE,(FILCNT) ; Get file counter
1639 072A' 7B LD A,E ; Subtract DE-(HL)
1640 072B' 96 SUB (HL)
1641 072C' 23 INC HL
1642 072D' 7A LD A,D
1643 072E' 9E SBC A,(HL)
1644 072F' C9 RET ; Exit
1646 ; Get Next FCB from Drive
1647 ; Entry A=0 Check Checksum, A=0FFH Update Checksum
1649 0730' 4F RDDIR: LD C,A ; Save checksum flag
1650 0731' 2A 0054' LD HL,(FILCNT) ; Get file counter
1651 0734' 23 INC HL ; Increment it
1652 0735' 22 0054' LD (FILCNT),HL ; And save it
1653 0738' ED5B 0043' LD DE,(NFILES) ; Get maximum number of files
1654 073C' 7B LD A,E ; Is this the last file?
1655 073D' 95 SUB L
1656 073E' 7A LD A,D
1657 073F' 9C SBC A,H
1658 0740' 38 BA' JR C,SETFCT ; ..set file count to 0FFFFH if so
1659 0742' 7D LD A,L ; Get file count LSB
1660 0743' 0F RRCA ; *32 (bm/hfb-to save a byte)
1661 0744' 0F RRCA
1662 0745' 0F RRCA
1663 0746' E6 60 AND 060H ; Mask it
1664 0748' 32 0056' LD (SECPNT),A ; Save it for later use
1665 074B' C0 RET NZ ; Return if not first FCB sector
1666 074C' C5 PUSH BC ; Save checksum flag
1667 IF NOT ZSDOS11 ; (* This was NOT in released package *)
1670 IF ZS
1679 ENDIF ;~Zsdos11
1680 074D' CD 0668' RdDir0: CALL STDIR ; Calculate sector/track directory
1681 IF NOT ZS
1700 ELSE
1701 ; READDR subroutine moved in-line here
1702 0750' CD 083D' CALL DMADIR ; Set up DMA directory
1703 0753' CD 0795' CALL READR ; Read a record
1704 0756' CD 0837' CALL STDMA ; ..and set up user's DMA
1705 ENDIF
1706 0759' C1 POP BC ; Restore checksum flag
ZMAC Relocating Macro Assembler v 1.7, page 38
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1708 ; Update/Check Checksum Directory
1709 ; Entry C=0 Check Checksum, C=0FFH update Checksum
1711 075A' 2A 0047' CHKDIR: LD HL,(NCHECK) ; Get number of checked records
1712 075D' ED5B 0052' LD DE,(RECDIR) ; Get current record
1713 0761' AF XOR A ; Clear carry (bm)
1714 0762' ED52 SBC HL,DE ; Test current record
1715 0764' C8 RET Z ; Exit if zero
1716 0765' D8 RET C ; Exit if greater than ncheck
1717 0766' 2A 0034' LD HL,(DIRBUF) ; Get dirbuf
1718 0769' CD 0DE0' CALL CKS127 ; ..and checksum first 127 bytes..
1719 076C' 86 ADD A,(HL) ; ...then 128th byte (hfb)
1720 076D' 2A 0038' LD HL,(CSV) ; Get pointer checksum directory
1721 0770' 19 ADD HL,DE ; Add current record
1722 0771' 0C INC C ; Test checksum flag
1723 0772' 20 02' JR NZ,CHKDR1 ; 0FFH=> update checksum
1724 0774' 77 LD (HL),A ; Update checksum
1725 0775' C9 RET ; And exit
1727 0776' BE CHKDR1: CP (HL) ; Test checksum
1728 0777' C8 RET Z ; Exit if ok
1730 ; Checksum differs, So Disk has changed. Relog it and continue
1732 0778' 3A 0015' LD A,(FLAGS)
1733 077B' CB67 BIT 4,A ; Inform user?
1734 077D' 06 00 LD B,0 ; Disk change error code
1735 077F' 11 0302' LD DE,MDSKCH ; Disk changed message
1736 0782' C4 034C' CALL NZ,ERROR ; Inform user
1738 ; Relog Current Drive after media change detected
1740 0785' CD 0647' CALL GETCDM ; Get current drive mask in HL
1741 0788' EB EX DE,HL ; Xfer mask to DE
1742 0789' CD 045D' CALL UNLOG ; Reset login vector for logged drive
1743 078C' CD 0435' CALL RELOG1 ; Do the meat of relogging
1744 ; Caveat emptor: this call is recursive...
1745 078F' CD 06FC' CALL SETFCT ; Re-initialize search file count
1746 0792' AF XOR A ; We only get here by checking.. (bm)
1747 0793' 18 9B' JR RDDIR ; And all checking is done from rddir
1749 ; Read Sector from Drive
1751 0795' CD 0027* READR: CALL READ ; CBIOS call read sector
1752 0798' 18 03' JR WRITE0
1754 ; Write Sector on Drive
1756 079A' CD 002A* WRITER: CALL WRITE ; CBIOS call write sector
1757 079D' B7 WRITE0: OR A ; Test exit code
1758 079E' C8 RET Z ; Exit if ok
1759 079F' 06 01 LD B,1 ; Disk I/O error code
1760 07A1' 11 030A' LD DE,MBADSC ; Load bad sector message
1761 07A4' 2A 0009' LD HL,(STBDSC) ; Load bad sector vector
1762 07A7' E9 JP (HL) ; ZSDOS error on D: Bad Sector
ZMAC Relocating Macro Assembler v 1.7, page 39
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1764 ; Close File Command (relocated hfb)
1766 = 07A9' BGPTCH2 EQU $+1 ;<-- BGii patch point
1768 07A8' CD 052D' CMND16: CALL SELDR1 ; Select drive from FCB
1770 ; Close File
1772 07AB' DDCB 0E7E CLOSE: BIT 7,(IX+FCBMOD) ; Test FCB/file modified
1773 07AF' C0 RET NZ ; Not then no close required
1774 07B0' CD 08D8' CALL CHKRO ; Test disk W/P
1775 07B3' CD 0719' CALL SRCT15 ; Search file and test present
1776 07B6' C8 RET Z ; No then exit with error
1777 07B7' CD 06EE' CALL CKRODI ; Check file W/P, get directory entry
1778 07BA' 01 0010 LD BC,16 ; Offset to DM block
1779 07BD' 09 ADD HL,BC ; Add offset
1780 07BE' EB EX DE,HL ; Save DIR PTR in DE
1781 07BF' 2A 005D' LD HL,(ARWORD) ; Get FCB ptr
1782 07C2' 09 ADD HL,BC ; Add offset
1783 07C3' EB EX DE,HL
1784 07C4' 41 LD B,C ; Xfer counter
1786 ; Copy FCB (DE) to DIR (HL) if and only if DIR=0 or DIR=FCB
1788 07C5' 34 CLOSE0: INC (HL)
1789 07C6' 35 DEC (HL) ; Test DIR for 0
1790 07C7' 1A LD A,(DE) ; Get byte from FCB
1791 07C8' 28 04' JR Z,CLOSE1 ; OK to Copy if 0
1792 07CA' BE CP (HL) ; Test if same as DIR
1793 07CB' C2 0B7A' JP NZ,RETCFF ; ..if Not, abort Close and return error
1794 07CE' 77 CLOSE1: LD (HL),A ; Else save in DIR
1795 07CF' 13 INC DE
1796 07D0' 23 INC HL
1797 07D1' 10 F2' DJNZ CLOSE0 ; Bump pointers and loop until done
1798 07D3' 11 FFEC LD DE,-20 ; Add -20 to get Extent Number from DIR
1799 07D6' 19 ADD HL,DE ; HL contains pointer to extent number
1800 07D7' DD7E 0C LD A,(IX+FCBEXT) ; Get extent number FCB
1801 07DA' BE CP (HL) ; Compare with extent number directory
1802 07DB' 38 08' JR C,CLOSE3 ; FCB < directory then jump
1803 07DD' 77 LD (HL),A ; Save extent number in directory
1804 07DE' 23 INC HL ; Get pointer to next record
1805 07DF' 23 INC HL
1806 07E0' 23 INC HL
1807 07E1' DD7E 0F LD A,(IX+FCBREC) ; Get next record FCB
1808 07E4' 77 LD (HL),A ; Save next record in directory
1809 07E5' CD 0808' CLOSE3: CALL CLOSE6 ; Clear Archive Bit and Write FCB
1810 07E8' CD 0BA6' CALL GETDME ; Get Data Module and Extent
1811 IF NOT ZSDOS11 ; (* NOT in Release version *)
1814 ELSE ;Zsdos11 (* This was Release version *)
1815 07EB' 28 0D' JR Z,CLOSE4 ; ..jump to Stamp if they are both 0
1816 07ED' C5 PUSH BC ; Save prior module and Extent
1817 ENDIF ;~Zsdos11
1818 07EE' 01 0000 LD BC,0
1819 07F1' CD 0B9E' CALL SETDME ; Set FCB Data Module and Extent to 0
1820 07F4' CD 0719' CALL SRCT15 ; Find proper DIR Entry
1821 IF NOT ZSDOS11
ZMAC Relocating Macro Assembler v 1.7, page 40
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1824 ELSE ;Zsdos11
1825 07F7' C1 POP BC
1826 07F8' 28 0B' JR Z,JSETDME ; ..Exit if Extent 0 Not Found
1827 07FA' C5 CLOSE4: PUSH BC
1828 ENDIF ;~Zsdos11
1829 07FB' CD 0808' CALL CLOSE6 ; Clear Archive Bit and Write FCB
1830 07FE' 2A 001C' LD HL,(STUPDV) ; Get the update routine address
1831 IF ZS
1832 0801' CD 0DB9' CALL STAMPT ; ..and stamp it
1836 ENDIF ;ZS
1837 IF NOT ZSDOS11
1840 ELSE ;Zsdos11
1841 0804' C1 POP BC ; Get Original Module and Extent Back
1842 0805' JSETDME:
1843 ENDIF ;~Zsdos11
1844 0805' C3 0B9E' JP SETDME ; Restore to FCB and Exit
1846 0808' CD 06F1' CLOSE6: CALL CALDIR ; Get directory entry
1847 080B' 01 000B LD BC,11 ; Point to archive byte
1848 080E' 09 ADD HL,BC
1849 080F' CBBE RES 7,(HL) ; Reset archive bit
1850 0811' DDCB 0BBE RES 7,(IX+ARCATT) ; Reset bit in FCB
1851 IF ZSDOS11
1852 0815' 18 00' JR WRFCB ; Write FCB to Disk
1854 IF NOT ZS
1858 ENDIF ;NOT Zs
1859 ENDIF ;Zsdos11
1861 0817' CD 06F1' WRFCB: CALL CALDIR ; Point to dir entry to write
1862 081A' 3E 0D LD A,FCBUSR ; Offset to user byte in FCB
1863 081C' CD 06F7' CALL CALDI0 ; ..do the add here
1864 081F' 36 00 LD (HL),0 ; Prevent writing it to disk
1865 0821' CD 0668' CALL STDIR ; Calculate sector/track directory
1866 0824' 0E FF LD C,0FFH ; Update checksum directory
1867 0826' CD 075A' CALL CHKDIR
1868 0829' CD 083D' WRITD1: CALL DMADIR ; Set up dma directory (label for DS - crw)
1869 082C' 0E 01 LD C,1 ; Write directory flag
1870 082E' CD 079A' CALL WRITER ; Write record
1871 0831' 18 04' JR STDMA ; Set up DMA user
1873 IF NOT ZSDOS11
1874 IF NOT ZS
1879 ENDIF ;~Zsdos11
1881 ; Set DMA Address Command
1883 0833' ED53 002E' CMND26: LD (DMA),DE ; Save DMA address
1885 ; Set DMA Address
1887 0837' ED4B 002E' STDMA: LD BC,(DMA) ; Get DMA address
1888 083B' 18 04' JR DMADR0 ; And do BIOS call
1890 ; Set DMA Address Directory
ZMAC Relocating Macro Assembler v 1.7, page 41
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1892 083D' ED4B 0034' DMADIR: LD BC,(DIRBUF) ; Get DMA address directory
1893 0841' C3 0024* DMADR0: JP SETDMA ; Cbios call set DMA
1895 ; Get Bit from ALV Buffer
1896 ; Entry DE=Block Number
1897 ; Exit A =Bit in LSB
1898 ; B =Bit Number in A
1899 ; HL=Pointer in ALV Buffer
1901 0844' 7B GETBIT: LD A,E ; Get bit number
1902 0845' E6 07 AND 7 ; Mask it
1903 0847' 3C INC A ; Add 1
1904 0848' 4F LD C,A ; Save it
1905 IF UNROLL
1906 0849' CB3A SRL D ; Get byte number
1907 084B' CB1B RR E ; DE=DE/8
1908 084D' CB3A SRL D
1909 084F' CB1B RR E
1910 0851' CB3A SRL D
1911 0853' CB1B RR E ; ..inline for speed (net cost: 4)
1912 0855' 47 LD B,A ; Re-save bit number for next shift
1913 0856' 2A 003A' LD HL,(ALV) ; Get start address ALV buffer
1919 ENDIF ;Unroll
1920 0859' 19 ADD HL,DE ; Add byte number
1921 085A' 7E LD A,(HL) ; Get 8 bits
1922 085B' 07 GETBT0: RLCA ; Get correct bit
1923 085C' 10 FD' DJNZ GETBT0
1924 085E' 41 LD B,C ; Restore bit number
1925 085F' C9 RET ; And return to caller
1927 ; Set/Reset bit in ALV Buffer
1928 ; Entry DE=Block Number
1929 ; C =0 Reset Bit, C=1 Set Bit
1931 0860' C5 SETBIT: PUSH BC ; Save set/reset bit
1932 0861' CD 0844' CALL GETBIT ; Get bit
1933 0864' E6 FE AND 0FEH ; Mask it
1934 0866' D1 POP DE ; Get set/reset bit
1935 0867' B3 OR E ; Set/reset bit
1936 0868' 0F SETBT0: RRCA ; Rotate bit in correct position
1937 0869' 10 FD' DJNZ SETBT0
1938 086B' 77 LD (HL),A ; Save 8 bits
1939 086C' C9 RET ; And return to caller
1941 ; Delete File
1943 086D' CD 09BD' DELETE: CALL COMCOD ; Call common code w/VDEL on stack
1945 ; Delete Routine Core (relocated to save space) (hfb)
1947 0870' CD 06EE' VDEL: CALL CKRODI ; Check file W/P, get directory entry
1948 0873' 36 E5 LD (HL),0E5H ; Remove file
1949 0875' 23 INC HL
1950 0876' 7E LD A,(HL) ; Get first char
1951 0877' D6 24 SUB '$' ; See if submit file
1952 0879' 20 03' JR NZ,VDEL1 ; If not
ZMAC Relocating Macro Assembler v 1.7, page 42
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
1953 087B' 32 0057' LD (SUBFLG),A ; Clear subflg if $*.* erased
1954 087E' 23 VDEL1: INC HL
1955 087F' CBBE RES 7,(HL) ; Insure erased files are not public
1956 0881' 0E 00 LD C,0 ; Remove bits ALV buffer
1957 ; ..fall thru and return to caller..
1959 ; Fill bit buffer from FCB in DIRBUF
1960 ; Entry C=0 Reset Bit, C=1 Set Bit
1962 0883' CD 06F1' FILLBB: CALL CALDIR ; Get directory entry
1963 0886' 11 0010 LD DE,16 ; Get offset DM block
1964 0889' 19 ADD HL,DE ; Add offset
1965 088A' 43 LD B,E ; Get block counter
1966 088B' 5E FILLB0: LD E,(HL) ; Get LSB block number
1967 088C' 23 INC HL ; Increment pointer
1968 088D' 16 00 LD D,0 ; Reset MSB block number
1969 088F' 3A 0042' LD A,(MAXLEN+1) ; Test >256 blocks present
1970 0892' B7 OR A
1971 0893' 28 03' JR Z,FILLB1 ; No then jump
1972 0895' 05 DEC B ; Decrement block counter
1973 0896' 56 LD D,(HL) ; Get correct MSB
1974 0897' 23 INC HL ; Increment pointer
1975 0898' 7A FILLB1: LD A,D ; Test block number
1976 0899' B3 OR E
1977 089A' 28 0D' JR Z,FILLB2 ; Zero then get next block
1978 089C' E5 PUSH HL ; Save pointer
1979 089D' C5 PUSH BC ; Save counter and set/reset bit
1980 089E' 2A 0041' LD HL,(MAXLEN) ; Get maximum length ALV buffer
1981 08A1' B7 OR A ; Reset carry
1982 08A2' ED52 SBC HL,DE ; Test DE<=maxlen ALV buffer
1983 08A4' D4 0860' CALL NC,SETBIT ; Yes then insert bit
1984 08A7' C1 POP BC ; Get counter and set/reset bit
1985 08A8' E1 POP HL ; Get pointer
1986 08A9' 10 E0' FILLB2: DJNZ FILLB0 ; Repeat for all DM entries
1987 08AB' C9 RET ; And return to caller
1989 ; Check File W/P Bit - SEARCH called first
1991 08AC' CD 06F1' CHKFRO: CALL CALDIR ; Get directory entry
1992 08AF' 11 0008 LD DE,WHLATT ; Offset to R/O bit
1993 08B2' 19 ADD HL,DE ; Add offset
1994 08B3' ED5B 0013' LD DE,(WHEEL) ; Get wheel byte address from header
1995 08B7' 1A LD A,(DE) ; ..and retrieve the actual byte
1996 08B8' A7 AND A ; ..and check the Wheel byte
1997 08B9' 20 04' JR NZ,CHKFR4 ; We have wheel, so allow writes anyway
1998 08BB' CB7E BIT 7,(HL) ; Else check Wheel attribute
1999 08BD' 20 10' JR NZ,CHKFR2 ; Yes then error
2000 08BF' 23 CHKFR4: INC HL ; Check W/P bit (hfb)
2001 08C0' CB7E BIT 7,(HL) ; Test file W/P
2002 08C2' 20 0B' JR NZ,CHKFR2 ; If W/P
2003 08C4' DDCB 077E CHKFR3: BIT 7,(IX+PSFATT) ; Was file accessed as Public or Path?
2004 08C8' C8 RET Z ; If normal access
2005 08C9' 3A 0015' LD A,(FLAGS) ; Else test for writes allowed
2006 08CC' E6 02 AND 0010B
2007 08CE' C0 RET NZ ; Go ahead, writes are allowed
2008 08CF' 2A 000F' CHKFR2: LD HL,(SFILRO) ; Get pointer to file W/P message
ZMAC Relocating Macro Assembler v 1.7, page 43
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2009 08D2' 06 03 LD B,3 ; File W/P error code
2010 08D4' 11 031E' LD DE,MFILRO ; Load file W/P message
2011 08D7' E9 JP (HL) ; Display message
2014 ; Check Drive Write Protect
2016 08D8' BGCKDRO:
2017 08D8' CD 08E5' CHKRO: CALL CHKRO1 ; Is the disk W/P?
2018 08DB' C0 RET NZ ; ..return if disk R/W
2019 08DC' 06 02 LD B,2 ; Else set disk W/P error code
2020 08DE' 11 0323' LD DE,MRO ; Load drive W/P message
2021 08E1' 2A 000D' LD HL,(STRO) ; Get pointer to drive W/P message
2022 08E4' E9 JP (HL) ; Display message
2024 08E5' 2A 0DFC' CHKRO1: LD HL,(DSKWP) ; Get the W/P drive vector
2025 08E8' CD 064A' CALL SDRVB ; Set the bit for this drive
2026 08EB' ED52 SBC HL,DE ; See if extra bit added (Cy is clear)
2027 08ED' C9 RET
2029 ; Search using first 12 bytes of FCB (hfb)
2031 08EE' 3E 0C SEAR12: LD A,12
2032 08F0' 21 DEFB 21H ; Trash HL and fall through
2034 ; Search using first 15 bytes of FCB
2036 08F1' 3E 0F SEAR15: LD A,15
2038 ; Search for File Name
2039 ; Entry: A = Number of bytes for which to search
2041 08F3' 32 005B' SEARCH: LD (SEARNB),A ; Save number of bytes
2042 08F6' 3E FF LD A,0FFH ; Set exit code to 0FFH (not found)
2043 08F8' 32 005A' LD (SEAREX),A
2044 08FB' DD22 0058' LD (DCOPY),IX ; Copy FCB pointer to RAM (search next)
2045 08FF' CD 06FC' CALL SETFCT ; Initiate file counter
2047 ; Force directory read with a Call HOME (bh) (Only if Floppys-hfb)
2048 IF ZSDOS11 ; (* Logic moved to RDDIR if NOT Zsdos11 *)
2049 0902' 2A 0047' LD HL,(NCHECK) ; Is this a fixed media?
2050 0905' 7C LD A,H
2051 0906' B5 OR L
2052 0907' C4 0018* CALL NZ,HOME ; Invoke CBIOS Home routine if removeable
2053 ENDIF ;~Zsdos11
2055 ; Search Next File Name
2057 090A' AF SEARCN: XOR A ; Check checksum directory
2058 090B' 67 LD H,A
2059 090C' 6F LD L,A
2060 090D' 22 0050' LD (SEARQU),HL ; Clear question mark & public detected flags
2061 0910' DDCB 07BE RES 7,(IX+PSFATT) ; Reset public/system file flag
2062 0914' CD 0730' CALL RDDIR ; Get FCB from directory
2063 0917' CD 071C' CALL TSTFCT ; Test if past last entry
2064 091A' 28 0E' JR Z,JSEAR8 ; Yes then jump (note carry always clear)
ZMAC Relocating Macro Assembler v 1.7, page 44
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2065 091C' ED5B 0058' LD DE,(DCOPY) ; Get FCB pointer
2066 0920' 1A LD A,(DE) ; Get first byte
2067 0921' FE E5 CP 0E5H ; Test if searching empty directory
2068 0923' 28 07' JR Z,SEARC1 ; Yes then jump
2069 0925' D5 PUSH DE ; Save FCB pointer
2070 0926' CD 0723' CALL TSTLF ; Test last file on this drive
2071 0929' D1 POP DE ; Restore FCB pointer
2072 092A' 30 6B' JSEAR8: JR NC,SEARC8 ; Yes then jump
2073 092C' CD 06F1' SEARC1: CALL CALDIR ; Get entry in directory
2074 092F' 7E LD A,(HL) ; Get first byte directory entry
2075 0930' FE 21 CP 21H ; Test time stamp
2076 0932' 28 D6' JR Z,SEARCN ; Yes then get next directory entry
2077 0934' 0E 00 LD C,0 ; Clear counter
2078 0936' 3A 005B' LD A,(SEARNB) ; Get number of bytes to search for
2079 0939' 47 LD B,A ; Save it in counter
2080 093A' 78 SEARC2: LD A,B ; Test if counter is zero
2081 093B' B7 OR A
2082 093C' 28 5F' JR Z,SEARC9 ; Yes then jump
2083 093E' 1A LD A,(DE) ; Get byte from FCB
2084 093F' EE 3F XOR '?' ; Test if question mark
2085 0941' E6 7F AND 7FH ; Mask it
2086 0943' 28 3B' JR Z,SEARC6 ; Yes then jump
2087 0945' 79 LD A,C ; Get FCB counter
2088 0946' B7 OR A ; Test first byte
2089 0947' 20 22' JR NZ,SEARC3 ; No then jump
2090 0949' 3A 0015' LD A,(FLAGS) ; Get flag byte
2091 094C' 1F RRA ; Test public file enable
2092 094D' 30 1C' JR NC,SEARC3 ; ..jump if not
2093 094F' 23 INC HL ; Get pointer to Public Bit
2094 0950' 23 INC HL
2095 0951' CB7E BIT 7,(HL) ; Test Public Bit directory
2096 0953' 2B DEC HL ; Restore pointer
2097 0954' 2B DEC HL
2098 0955' 28 14' JR Z,SEARC3 ; No public file then jump
2099 0957' 1A LD A,(DE) ; Get first byte FCB
2100 0958' FE E5 CP 0E5H ; Test if searching empty directory
2101 095A' 28 0F' JR Z,SEARC3 ; Yes then jump
2103 ; The following 3 lines of code represent a deviation from the description of
2104 ; PUBLIC Files as given in DDJ Article by Bridger Mitchell and Derek McKay of
2105 ; Plu*Perfect Systems. The PUBLIC Specification states that Public Files will
2106 ; NOT be found by any wildcard reference except when a "?" is in the FCB+0
2107 ; byte. The code here relaxes that requirement as follows: If we are in the
2108 ; same user area as the public file, then don't report the file as PUBLIC, but
2109 ; find it. This has a nasty side effect - it allows erasing of PUBLIC files
2110 ; if we are in the same area. However, these files also show up on the direc-
2111 ; tory (they wouldn't otherwise), so at least we should know we're blasting
2112 ; them.
2114 095C' AE XOR (HL) ; Test FCB = Directory Entry
2115 095D' E6 7F AND 7FH ; Mask it (setting Zero Flag)
2116 095F' 28 19' JR Z,SEARC5 ; Jump if user is same
2117 0961' 3E FF LD A,0FFH
2118 0963' 32 0051' LD (SEARPU),A ; Set Public file found
2119 IF UPATH
2120 0966' CD 0AAF' CALL SETPSF ; Set Public/System file flag
ZMAC Relocating Macro Assembler v 1.7, page 45
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2123 ENDIF
2124 0969' 18 0F' JR SEARC5 ; Jump found
2126 096B' 79 SEARC3: LD A,C ; Get FCB counter
2127 096C' FE 0D CP 13 ; Is it User Code?
2128 096E' 28 0A' JR Z,SEARC5 ; ..jump if so..don't test
2129 0970' FE 0C CP 12 ; Is it an Extent Number?
2130 0972' 1A LD A,(DE) ; ..Get byte from FCB
2131 0973' 28 11' JR Z,SEARC7 ; ..Jump if Extent Number
2132 0975' AE XOR (HL) ; Is FCB byte = Directory Entry byte?
2133 0976' E6 7F AND 07FH ; ..Mask it
2134 0978' 20 90' SEARC4: JR NZ,SEARCN ; ..jump if not same and get next entry
2135 097A' 13 SEARC5: INC DE ; Increment FCB pointer
2136 097B' 23 INC HL ; Increment Directory Entry pointer
2137 097C' 0C INC C ; Increment counter
2138 097D' 05 DEC B ; Decrement counter
2139 097E' 18 BA' JR SEARC2 ; Test next byte
2141 0980' 3D SEARC6: DEC A ; Set question mark found flag
2142 0981' 32 0050' LD (SEARQU),A
2143 0984' 18 F4' JR SEARC5 ; Jump found
2145 0986' SEARC7:
2146 0986' AE XOR (HL) ; Test extent
2147 0987' CD 098C' CALL SEARC7A ; Mask Extent
2148 098A' 18 EC' JR SEARC4 ; ..and test Result
2151 098C' C5 SEARC7A: PUSH BC
2152 098D' 47 LD B,A ; Save Extent
2153 098E' 3A 0040' LD A,(NEXTND) ; Get extent mask
2154 0991' 2F CPL ; Complement it
2155 0992' E6 1F AND MAXEXT ; Mask it
2156 0994' A0 AND B ; Mask extent
2157 0995' C1 POP BC ; Restore counters
2158 0996' C9 RET
2160 0997' CD 06FC' SEARC8: CALL SETFCT ; Error set file counter
2161 099A' C3 0B7A' JP RETCFF ; Set return code to FF and exit
2163 099D' 2A 0050' SEARC9: LD HL,(SEARQU) ; Get question mark and public found flags
2164 09A0' 7C LD A,H
2165 09A1' A5 AND L
2166 09A2' 20 D4' JR NZ,SEARC4 ; Yes then search for next entry
2167 09A4' CD 0723' CALL TSTLF ; Test for last file
2168 09A7' D4 0714' CALL NC,SETLF0 ; And update if so
2169 09AA' 2A 0052' LD HL,(RECDIR) ; Set DE return to directory record
2170 09AD' 22 005F' LD (DEVAL),HL ; .. for DateStamper simulation
2171 09B0' 3A 0054' LD A,(FILCNT) ; Get file counter
2172 09B3' E6 03 AND 3 ; Mask it
2173 09B5' 32 004C' LD (PEXIT),A ; And set exit code
2174 09B8' AF XOR A ; Clear exit code search
2175 09B9' 32 005A' LD (SEAREX),A
2176 09BC' C9 RET ; And return to caller
2178 ; The following code is common to DELETE, RENAME, and CSTAT.
ZMAC Relocating Macro Assembler v 1.7, page 46
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2179 ; It is coded in a manner that is compatable with the Z280
2180 ; in protected Mode.
2182 09BD' CD 08D8' COMCOD: CALL CHKRO ; Check disk W/P
2183 09C0' CD 08EE' CALL SEAR12 ; Search file
2184 09C3' CD 071C' COMCO1: CALL TSTFCT ; Test if file found
2185 09C6' E1 POP HL ; Routine addr to HL (in case not found)
2186 09C7' C8 RET Z ; Not then exit
2187 09C8' E5 PUSH HL ; ..found, so routine back to stack
2188 09C9' E5 PUSH HL ; Twice, as RET pops first push
2189 09CA' 21 09CF' LD HL,COMCO2
2190 09CD' E3 EX (SP),HL ; COMCO2 to stack, routine addr to HL
2191 09CE' E9 JP (HL) ; ..branch to routine
2193 09CF' CD 0817' COMCO2: CALL WRFCB ; Write directory buffer on disk
2194 09D2' CD 090A' CALL SEARCN ; Search next entry
2195 09D5' 18 EC' JR COMCO1 ; And test it
2198 ; Rename File - Note Wildcard Support
2200 09D7' CD 09BD' RENAM: CALL COMCOD ; Go to common code w/VRENAM on stack
2202 09DA' CD 08AC' VRENAM: CALL CHKFRO ; Check file W/P
2203 09DD' 2A 005D' LD HL,(ARWORD)
2204 09E0' 11 0010 LD DE,16 ; Offset to new name
2205 09E3' 19 ADD HL,DE ; Add offset
2206 09E4' EB EX DE,HL ; Copy HL=>DE
2207 09E5' CD 06F1' CALL CALDIR ; Get directory entry
2208 09E8' 23 INC HL
2209 09E9' 23 INC HL
2210 09EA' CBBE RES 7,(HL) ; Make any renamed file private
2211 09EC' 2B DEC HL
2212 09ED' 2B DEC HL
2213 09EE' 06 0B LD B,11 ; Set up loop counter
2214 09F0' 23 RENAM1: INC HL ; Increment directory pointer
2215 09F1' 13 INC DE ; Increment FCB pointer
2216 09F2' 1A LD A,(DE) ; Get character from FCB
2217 09F3' E6 7F AND 7FH ; Mask it
2218 09F5' FE 3F CP '?' ; Test if question mark
2219 09F7' 20 01' JR NZ,RENAM2 ; no, then change character on disk
2220 09F9' 7E LD A,(HL) ; Else get what's there as there is no change
2221 09FA' 17 RENAM2: RLA ; Clear MSB
2222 09FB' CB16 RL (HL) ; Get MSB from directory
2223 09FD' 1F RRA ; And move to FCB
2224 09FE' 77 LD (HL),A ; Save in directory
2225 09FF' 10 EF' DJNZ RENAM1 ; Loop until done
2226 0A01' C9 RET
2228 ; Change Status Bits for File
2230 0A02' CD 09BD' CSTAT: CALL COMCOD ; Go to common code w/VCSTAT on stack
2232 0A05' DDE5 VCSTAT: PUSH IX
2233 0A07' D1 POP DE ; FCB pointer in DE
2234 0A08' CD 06F1' CALL CALDIR ; Get directory entry
ZMAC Relocating Macro Assembler v 1.7, page 47
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2235 0A0B' 06 0B LD B,11 ; Set up loop counter
2236 0A0D' 23 CSTAT1: INC HL ; Increment directory pointer
2237 0A0E' 13 INC DE ; Increment FCB pointer
2238 0A0F' 3E 04 LD A,4 ; Are we pointing to Wheel Attribute?
2239 0A11' B8 CP B
2240 0A12' 20 0E' JR NZ,CSTAT2 ; ..jump if not
2241 0A14' E5 PUSH HL
2242 0A15' 2A 0013' LD HL,(WHEEL) ; Else do we have Wheel privileges?
2243 0A18' 7E LD A,(HL)
2244 0A19' E1 POP HL
2245 0A1A' A7 AND A ; ..set flags to show
2246 0A1B' 20 05' JR NZ,CSTAT2 ; Jump if we have Wheel
2247 0A1D' CB7E BIT 7,(HL) ; Is file Wheel protected?
2248 0A1F' C2 08CF' JP NZ,CHKFR2 ; ..jump if so
2249 0A22' 1A CSTAT2: LD A,(DE) ; Get status bit from FCB
2250 0A23' CB16 RL (HL) ; Remove MSB of directory
2251 0A25' 17 RLA ; Get msb from FCB
2252 0A26' CB1E RR (HL) ; And move into directory char
2253 0A28' 10 E3' DJNZ CSTAT1 ; Loop until done
2254 0A2A' C9 RET
2256 ; Compute File Size
2258 0A2B' 01 0000 FILSZ: LD BC,0 ; Reset file size length
2259 0A2E' 51 LD D,C
2260 0A2F' CD 0515' CALL LDRRC ; Save it in FCB+33,34,35
2261 0A32' CD 08EE' CALL SEAR12 ; Search file (hfb)
2262 0A35' CD 071C' FILSZ0: CALL TSTFCT ; Test if file found
2263 0A38' C8 RET Z ; Not then exit
2264 0A39' CD 06F1' CALL CALDIR ; Get directory entry
2265 0A3C' EB EX DE,HL ; Copy to DE
2266 0A3D' 21 000F LD HL,15 ; Offset to next record
2267 0A40' CD 0D7F' CALL CALRRC ; Calculate random record count
2268 0A43' 7A LD A,D ; Test LSB < (ix+33)
2269 0A44' DD96 21 SUB (IX+33)
2270 0A47' 79 LD A,C ; Test ISB < (ix+34)
2271 0A48' DD9E 22 SBC A,(IX+34)
2272 0A4B' 78 LD A,B ; Test MSB < (ix+35)
2273 0A4C' DD9E 23 SBC A,(IX+35)
2274 0A4F' D4 0515' CALL NC,LDRRC ; Write new maximum
2275 0A52' CD 090A' CALL SEARCN ; Search next file
2276 0A55' 18 DE' JR FILSZ0 ; And test it
2278 ; Find File
2279 IF UPATH
2280 0A57' CD 0719' FINDF: CALL SRCT15 ; Search file
2281 0A5A' C0 RET NZ ; Yes then exit
2282 0A5B' 3A 0015' LD A,(FLAGS)
2283 0A5E' CB6F BIT 5,A ; Test if Path enabled
2284 0A60' C8 RET Z ; Exit if not
2285 0A61' 2A 0011' LD HL,(PATH) ; Get Path address
2286 0A64' 7C LD A,H ; Test if zero (no path)
2287 0A65' B5 OR L
2288 0A66' C8 RET Z ; Yes then exit
2289 0A67' 7E FINDF0: LD A,(HL) ; Get first entry path name
2290 0A68' 23 INC HL ; Increment pointer
ZMAC Relocating Macro Assembler v 1.7, page 48
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2291 0A69' B7 OR A ; Test if last entry
2292 0A6A' CA 0997' JP Z,SEARC8 ; Yes then error exit
2293 0A6D' E6 7F AND 7FH ; Mask drive number
2294 0A6F' FE 24 CP '$' ; Test if current drive
2295 0A71' 20 04' JR NZ,FINDF1 ; No then jump
2296 0A73' 3A 002C' LD A,(DRIVE) ; Get current drive
2297 0A76' 3C INC A ; Increment drive number
2298 0A77' 3D FINDF1: DEC A ; Decrement drive number
2299 0A78' E5 PUSH HL ; Save path pointer
2300 0A79' CD 0581' CALL SELDK ; Select drive
2301 0A7C' E1 POP HL ; Restore path pointer
2302 0A7D' 7E LD A,(HL) ; Get user number
2303 0A7E' 23 INC HL ; Advance pointer
2304 0A7F' E6 7F AND 7FH ; Mask user number
2305 0A81' FE 24 CP '$' ; Test if current user
2306 0A83' 20 03' JR NZ,FINDF2 ; No then jump
2307 0A85' 3A 002A' LD A,(USER) ; Get current user
2308 0A88' E6 1F FINDF2: AND 1FH ; Mask user number
2309 0A8A' E5 PUSH HL ; Save path pointer
2310 0A8B' CD 055E' CALL RESUSR ; Add new user number in FCB+0 and FCB+13
2311 0A8E' CD 0719' CALL SRCT15 ; Search file and test if present
2312 0A91' E1 POP HL ; Restore path pointer
2313 0A92' 28 D3' JR Z,FINDF0 ; No then test next path entry
2314 0A94' E5 PUSH HL ; Save path pointer
2315 0A95' CD 06F1' CALL CALDIR ; Get directory entry
2316 0A98' 11 000A LD DE,10 ; Add offset system bit
2317 0A9B' 19 ADD HL,DE
2318 0A9C' CB7E BIT 7,(HL) ; Test system file
2319 0A9E' 3A 0015' LD A,(FLAGS) ; Test for relaxed path definition
2320 0AA1' 17 RLA ; ..by rotating bit..
2321 0AA2' 17 RLA ; ..into carry flag
2322 0AA3' E1 POP HL ; Restore path pointer
2323 0AA4' 38 02' JR C,FINDF3 ; If carry, system attrib not required
2324 0AA6' 28 BF' JR Z,FINDF0 ; No system file then test next path entry
2325 0AA8' 3A 002B' FINDF3: LD A,(DEFDRV) ; Get current drive
2326 0AAB' 3C INC A ; Increment drive number
2327 0AAC' 32 002D' LD (FCB0),A ; Save it in exit FCB0
2328 0AAF' DDCB 07FE SETPSF: SET 7,(IX+PSFATT) ; set Public/System file flag
2329 0AB3' C9 RET ; And return to caller
2330 ENDIF ;Upath
2332 ; Open File Command
2334 0AB4' CD 051F' CMND15: CALL SELDRV ; Select drive from FCB
2335 0AB7' DD36 000E LD (IX+FCBMOD),0 ; Clear data module number
2337 ; Open File
2338 IF UPATH
2339 0ABB' CD 0A57' CALL FINDF ; Find file (use path name)
2340 0ABE' CD 071C' CALL TSTFCT ; Test file found
2343 ENDIF ;Upath
2344 0AC1' C8 RET Z ; No then exit
2345 0AC2' DD7E 07 OPENF0: LD A,(IX+PSFATT) ; Get Public/System file bit
2346 0AC5' F5 PUSH AF ; Save it
2347 0AC6' DD7E 0C LD A,(IX+FCBEXT) ; Get extent number from FCB
2348 0AC9' F5 PUSH AF ; Save it
ZMAC Relocating Macro Assembler v 1.7, page 49
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2349 0ACA' CD 06F1' CALL CALDIR ; Get directory entry
2350 0ACD' 7E LD A,(HL) ; Find real user number file is in
2351 0ACE' F6 80 OR 80H ; Set user valid flag
2352 0AD0' DDE5 PUSH IX ; Save FCB entry
2353 0AD2' D1 POP DE ; Get in in DE
2354 0AD3' 01 0020 LD BC,32 ; Number of bytes to move
2355 0AD6' EDB0 LDIR ; Move directory to FCB
2356 0AD8' DD77 0D LD (IX+FCBUSR),A ; And put user byte back
2357 0ADB' CD 0D7A' CALL SETB14 ; Set FCB/File Not Modified
2358 0ADE' DD46 0C LD B,(IX+FCBEXT) ; Get extent number
2359 0AE1' DD4E 0F LD C,(IX+FCBREC) ; Get next record number
2360 0AE4' F1 POP AF ; Get old extent number
2361 0AE5' DD77 0C LD (IX+FCBEXT),A ; Save it
2362 0AE8' B8 CP B ; Compare old and new extent number
2363 0AE9' 28 04' JR Z,OPENF1 ; Same then jump
2364 0AEB' 0E 00 LD C,0 ; Set next record count to 0
2365 0AED' CB19 RR C ; Record count to Max (80H) if need new extent
2366 0AEF' DD71 0F OPENF1: LD (IX+FCBREC),C ; Save next record count
2367 0AF2' F1 POP AF ; Get Public/System file bit
2368 0AF3' DDCB 0716 RL (IX+PSFATT) ; Remove MSB from IX+8
2369 0AF7' 17 RLA ; Set new MSB in carry
2370 0AF8' DDCB 071E RR (IX+PSFATT) ; Save Carry in IX+8
2371 IF ZS
2372 0AFC' 2A 0018' LD HL,(STLAV) ; Get address of last accessed routine
2373 0AFF' C3 0DB9' JP STAMPT
2378 ENDIF ;Zs
2380 ; Make File Command
2382 0B02' CD 051F' CMND22: CALL SELDRV ; Select drive from FCB
2383 0B05' DD36 000E LD (IX+FCBMOD),0 ; Clear data module number
2385 ; Make File
2387 0B09' CD 08D8' MAKES: CALL CHKRO ; Check drive W/P
2388 0B0C' 2A 005D' LD HL,(ARWORD)
2389 0B0F' 7E LD A,(HL) ; Get first byte FCB
2390 0B10' F5 PUSH AF ; Save it
2391 0B11' 36 E5 LD (HL),0E5H ; Set first byte to empty file
2392 0B13' 3E 01 LD A,1 ; Search for 1 byte
2393 0B15' CD 08F3' CALL SEARCH ; Search empty file
2394 0B18' F1 POP AF ; Get first byte FCB
2395 0B19' DD77 00 LD (IX+0),A ; Restore it
2396 0B1C' CD 071C' CALL TSTFCT ; Test empty file found
2397 0B1F' C8 RET Z ; No then return error
2398 0B20' 2A 005D' LD HL,(ARWORD) ; Get FCB pointer
2399 0B23' CD 0452' CALL CKSUB ; Check if this is a submit file
2400 0B26' 11 000F LD DE,15 ; Prepare offset
2401 0B29' 19 ADD HL,DE ; Add it
2402 0B2A' 06 11 LD B,17 ; Set loop counter
2403 0B2C' AF XOR A
2404 0B2D' 77 MAKE0: LD (HL),A ; Clear FCB+15 up to FCB+31
2405 0B2E' 23 INC HL ; Increment pointer
2406 0B2F' 10 FC' DJNZ MAKE0 ; And clear all bytes
2407 0B31' DDCB 07BE RES 7,(IX+PSFATT) ; Reset Public/System file bit
2408 0B35' DDCB 0BBE RES 7,(IX+ARCATT) ; Reset archive bit if present
ZMAC Relocating Macro Assembler v 1.7, page 50
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2409 0B39' CD 06F1' CALL CALDIR ; Get directory entry
2410 0B3C' DDE5 PUSH IX ; Save FCB entry
2411 0B3E' D1 POP DE ; Get it in DE
2412 0B3F' EB EX DE,HL ; Exchange FCB and directory entry
2413 0B40' 01 0020 LD BC,32 ; Number of bytes to move
2414 0B43' EDB0 LDIR ; Move bytes
2415 0B45' CD 0817' CALL WRFCB ; Write FCB on disk
2416 0B48' CD 0D7A' CALL SETB14 ; Set file not modified
2417 IF ZS
2418 0B4B' 2A 001A' LD HL,(STCRV) ; Get address of Stamp Create routine
2419 0B4E' C3 0DB9' JP STAMPT ; ..and stamp it
2423 ENDIF ;Zs
2425 ; Open Next Extent
2427 0B51' DDCB 0E7E OPENEX: BIT 7,(IX+FCBMOD) ; Test if FCB/File Modified (write)
2428 0B55' 20 08' JR NZ,OPENX2 ; Not then jump
2429 0B57' CD 07AB' CALL CLOSE ; Close current FCB
2430 0B5A' 3A 004C' LD A,(PEXIT) ; Get exit code
2431 0B5D' 3C INC A ; Test if error
2432 0B5E' C8 RET Z ; Yes then exit
2433 0B5F' CD 0B85' OPENX2: CALL CALNEX ; Calculate next extent (LABEL MOVED)
2434 0B62' 38 13' JR C,OPENX3 ; Error then jump
2436 0B64' CD 0719' OPENX0: CALL SRCT15 ; Search for 15-char match & test presence
2437 0B67' 20 16' JR NZ,OPENX5 ; Yes then jump
2438 0B69' 3A 004F' LD A,(RDWR) ; Test Read/Write flag
2439 0B6C' B7 OR A ; Test if read
2440 0B6D' 28 08' JR Z,OPENX3 ; Yes then error
2441 0B6F' CD 0B09' CALL MAKES ; Make new extent if write
2442 0B72' CD 071C' CALL TSTFCT ; Test if succesfull
2443 0B75' 20 0B' JR NZ,OPENX6 ; Yes then exit
2444 0B77' CD 0D7A' OPENX3: CALL SETB14 ; Set FCB/File Not Modified
2445 0B7A' 3E FF RETCFF: LD A,0FFH ; (hfb/cwc) set exit code
2446 0B7C' C3 04BB' OPENX4: JP SAVEA ; And return to caller
2448 0B7F' CD 0AC2' OPENX5: CALL OPENF0 ; Open file
2449 0B82' AF OPENX6: XOR A ; And clear exit code
2450 0B83' 18 F7' JR OPENX4 ; Use same routine
2452 ;==OPENX2: CALL CALNEX ; Calculate next extent
2453 ;== JR C,OPENX3 ; Error then jump
2454 ;== JR OPENX0 ; Open next extent, FCB contains DU:
2456 ; Calculate Next Extent
2457 ; Exit: Carry=1 => Overflow Detected
2459 0B85' CD 0BA6' CALNEX: CALL GETDME ; Get extent number, data module number
2460 0B88' CB70 BIT 6,B ; Test error bit random record
2461 0B8A' 37 SCF ; Set error flag
2462 0B8B' C0 RET NZ ; ..Error exit if Non-zero
2463 0B8C' 0C INC C ; Increment extent number
2464 0B8D' 79 LD A,C ; Get extent number
2465 0B8E' E6 1F AND MAXEXT ; Mask it for max extent
2466 0B90' 4F LD C,A ; Save it in C
2467 ;== JR NZ,SETDME ; If new data module not required
ZMAC Relocating Macro Assembler v 1.7, page 51
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2468 0B91' 20 07' JR NZ,CALNE1 ;== IF NEW DATA MODULE NOT REQUIRED
2469 0B93' 04 INC B ; Set next data module
2470 0B94' 78 LD A,B ; Get it in A
2471 0B95' E6 3F AND MAXMOD ; Mask it for max module
2472 0B97' 47 LD B,A ; Save it in B
2473 0B98' 37 SCF ; Set error flag
2474 0B99' C8 RET Z ; And return if file overflow
2475 0B9A' DD36 0020 CALNE1: LD (IX+NXTREC),0 ;== ZERO NEXT RECORD COUNT
2476 0B9E' DD71 0C SETDME: LD (IX+FCBEXT),C ; Save Extent number
2477 0BA1' DD70 0E LD (IX+FCBMOD),B ; Save Data Module number
2478 IF ZS
2479 0BA4' A7 AND A ; Clear flag here if ZS
2480 0BA5' C9 RET
2481 ENDIF ; ..else fall thru on ZD to do same thing
2483 0BA6' DD4E 0C GETDME: LD C,(IX+FCBEXT) ; Get Extent number
2484 0BA9' DD46 0E LD B,(IX+FCBMOD) ; Get Data Module number
2485 0BAC' 79 LD A,C
2486 0BAD' CD 098C' CALL SEARC7A ; Mask Extent
2487 0BB0' CBB8 RES 7,B ; Clear Unmodified Flag
2488 0BB2' B0 OR B ; Test for Module and Extent = 0
2489 0BB3' C9 RET ; ..and return to caller
2491 ; Read Random Record Command
2493 0BB4' CD 052D' CMND33: CALL SELDR1 ; Select drive from FCB
2495 ; Read Random Sector
2497 0BB7' AF XOR A ; Set read/write flag
2498 0BB8' CD 0CF6' CALL LDFCB ; Load random record in FCB
2499 0BBB' 28 04' JR Z,READS ; No error then read sector
2500 0BBD' C9 RET ; Return error
2502 ; Read Sequential
2504 0BBE' CD 052D' CMND20: CALL SELDR1 ; Select drive from FCB
2506 ; Read Sector
2508 0BC1' AF READS: XOR A ; Set Read/Write flag
2509 0BC2' 32 004F' LD (RDWR),A ; Save it
2510 0BC5' DD7E 20 LD A,(IX+NXTREC) ; Get record counter
2511 0BC8' FE 80 CP 80H ; Test if last record this extent
2512 ;= JR NC,READS1 ; Yes then open next extent
2513 0BCA' 28 09' JR Z,READS1 ;= Yes then open next extent
2514 0BCC' DDBE 0F CP (IX+FCBREC) ; Test if greater then current record
2515 0BCF' 38 07' JR C,READS2 ; No then get record
2516 0BD1' 3E 01 READS0: LD A,1 ; Set end of file flag
2517 0BD3' 18 A7' JR OPENX4 ; And exit
2519 0BD5' CD 0BE9' READS1: CALL OPNXCK ; Open next extent
2520 0BD8' CD 06AA' READS2: CALL GETDM ; Get block number from DM in FCB
2521 0BDB' 28 F4' JR Z,READS0 ; Jump if block number=0 to end file
2522 0BDD' CD 06D7' CALL CALSEC ; Calculate Sector Number (128 bytes)
2523 0BE0' CD 067A' CALL CALST ; Calculate Sector/Track number
ZMAC Relocating Macro Assembler v 1.7, page 52
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2524 0BE3' CD 0795' CALL READR ; Read data
2525 0BE6' C3 0CE4' JP WRITS7 ; Increment elsewhere if necessary
2527 ; Consolidated Routine to Open Extent and check status
2529 0BE9' CD 0B51' OPNXCK: CALL OPENEX ; Open next extent
2530 0BEC' 3A 004C' LD A,(PEXIT) ; Get exit code
2531 0BEF' B7 OR A
2532 0BF0' C8 RET Z ;== IF OPEN OK
2533 0BF1' E1 POP HL ;== ELSE POP RETURN ADDRESS TO ABORT R/W
2534 0BF2' 18 DD' JR READS0 ;== AND SET ERROR CODE TO EOF
2535 ;== JR NZ,READS0 ; Yes then end of file
2536 ;== LD (IX+NXTREC),A ; Clear record counter (jww)
2537 ;== RET
2539 ; Write Random Record Command (with and without Zero Fill)
2541 0BF4' CMND40: ; (hfb/cwc)
2542 0BF4' CD 052D' CMND34: CALL SELDR1 ; Select drive from FCB
2544 ; Write Random Sector and Write Random with Zero Fill
2546 0BF7' 3E FF LD A,0FFH ; Set Read/Write flag
2547 0BF9' CD 0CF6' CALL LDFCB ; Load FCB from random record
2548 0BFC' 28 04' JR Z,WRITES ; No error then write record
2549 0BFE' C9 RET ; Return error
2551 ; Write Sequential
2553 0BFF' CD 052D' CMND21: CALL SELDR1 ; Select drive from FCB
2555 ; Write Sector. Permitted to PUBlic files and those found along Path
2557 0C02' 3E FF WRITES: LD A,0FFH ; Set read/write flag
2558 0C04' 32 004F' LD (RDWR),A ; And save it
2560 = 0C08' BGPTCH1 EQU $+1 ;<-- Patched location for BGii
2562 0C07' CD 08D8' CALL CHKRO ; Check disk W/P
2563 0C0A' DDCB 097E BIT 7,(IX+ROATT) ; Test if file W/P
2564 0C0E' 20 0E' JR NZ,WRITSA ; Yes then file W/P message
2565 0C10' CD 08C4' CALL CHKFR3 ; Test W/P if path or Public used
2566 0C13' 2A 0013' LD HL,(WHEEL) ; Get address of Wheel byte
2567 0C16' 7E LD A,(HL) ; Do we have it?
2568 0C17' A7 AND A
2569 0C18' 20 07' JR NZ,WRITSB ; Yes - allow write
2570 0C1A' DDCB 087E BIT 7,(IX+WHLATT) ; Else test if Wheel Prot file
2571 0C1E' C2 08CF' WRITSA: JP NZ,CHKFR2 ; Yes then file W/P message
2572 0C21' DDCB 207E WRITSB: BIT 7,(IX+NXTREC) ; End of this extent?
2573 0C25' C4 0BE9' CALL NZ,OPNXCK ; Open next extent and check status (hfb)
2574 0C28' CD 06AA' CALL GETDM ; Get block number from FCB
2575 0C2B' C2 0CC3' JP NZ,WRITS5 ; Jump to write sector if Block Number <> 0
2576 0C2E' E5 PUSH HL ; Save pointer to Block Number
2577 0C2F' 79 LD A,C ; Test first Block Number in extent
2578 0C30' B7 OR A
2579 0C31' 28 04' JR Z,WRITS1 ; Yes then jump
ZMAC Relocating Macro Assembler v 1.7, page 53
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2580 0C33' 3D DEC A ; Decrement pointer to Block Number
2581 0C34' CD 06C0' CALL GETDM4 ; Get previous Block Number
2583 ; Get Free Block from ALV Buffer
2584 ; Entry DE=Old Block Number
2585 ; Exit DE=New Block Number (0 if No Free Block)
2586 ; HL counts Up,DE counts Down
2587 ; GETFRE routine relocated here inline
2588 0C37' 62 WRITS1: LD H,D ; Copy old block to HL
2589 0C38' 6B LD L,E
2590 0C39' 7A GETFR0: LD A,D ; Test down counter is zero
2591 0C3A' B3 OR E
2592 0C3B' 28 0B' JR Z,GETFR1 ; Yes then jump
2593 0C3D' 1B DEC DE ; Decrememt down counter
2594 0C3E' E5 PUSH HL ; Save up/down counter
2595 0C3F' D5 PUSH DE
2596 0C40' CD 0844' CALL GETBIT ; Get bit from ALV buffer
2597 0C43' 1F RRA ; Test if zero
2598 0C44' 30 20' JR NC,GETFR3 ; Yes then found empty block
2599 0C46' D1 POP DE ; Get up/down counter
2600 0C47' E1 POP HL
2601 0C48' ED4B 0041' GETFR1: LD BC,(MAXLEN) ; Get maximum ALV length-1 in BC
2602 0C4C' 7D LD A,L ; Is HL >= length ALV-1?
2603 0C4D' 91 SUB C ; ..do while preserving HL
2604 0C4E' 7C LD A,H
2605 0C4F' 98 SBC A,B
2606 0C50' 30 0E' JR NC,GETFR2 ; End buffer then jump
2607 0C52' 23 INC HL ; Increment up counter
2608 0C53' D5 PUSH DE ; Save down/up counter
2609 0C54' E5 PUSH HL
2610 0C55' EB EX DE,HL ; Save up counter in DE
2611 0C56' CD 0844' CALL GETBIT ; Get bit from ALV buffer
2612 0C59' 1F RRA ; Test if zero
2613 0C5A' 30 0A' JR NC,GETFR3 ; Yes then found empty block
2614 0C5C' E1 POP HL ; Get down/up counter
2615 0C5D' D1 POP DE
2616 0C5E' 18 D9' JR GETFR0 ; And test next block
2618 0C60' 7A GETFR2: LD A,D ; Test if last block tested
2619 0C61' B3 OR E
2620 0C62' 20 D5' JR NZ,GETFR0 ; No then test next block
2621 0C64' 18 07' JR WRITSG ; Continue with DE=0
2623 0C66' 37 GETFR3: SCF ; Set block number used
2624 0C67' 17 RLA ; Save bit
2625 0C68' CD 0868' CALL SETBT0 ; Put bit in ALV buffer
2626 0C6B' D1 POP DE ; Get correct counter
2627 0C6C' E1 POP HL ; Restore stack pointer
2628 ; ..continue with (DE=block number)
2630 0C6D' E1 WRITSG: POP HL ; Get pointer to Block Number
2631 0C6E' 7A LD A,D ; Test if blocknumber = 0
2632 0C6F' B3 OR E
2633 0C70' 28 7F' JR Z,WRITS8 ; Yes then disk full error
2634 0C72' DDCB 0EBE RES 7,(IX+FCBMOD) ; Reset FCB/File Modified
2635 0C76' 73 LD (HL),E ; Save blocknumber
ZMAC Relocating Macro Assembler v 1.7, page 54
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2636 0C77' 3A 0042' LD A,(MAXLEN+1) ; Get number of blocks
2637 0C7A' B7 OR A ; Is it < 256?
2638 0C7B' 28 02' JR Z,WRITS2 ; ..Jump if so
2639 0C7D' 23 INC HL ; Increment to MSB Block Number
2640 0C7E' 72 LD (HL),D ; ..and save MSB block number
2641 0C7F' 0E 02 WRITS2: LD C,2 ; Set write new block flag
2642 0C81' 3A 003F' LD A,(NMASK) ; Get sector mask
2643 0C84' DDA6 20 AND (IX+NXTREC) ; Mask with record counter
2644 0C87' 28 02' JR Z,WRITSX ; Zero then Ok (at start new record)
2645 0C89' 0E 00 LD C,0 ; Else clear new block flag
2646 0C8B' 3A 004B' WRITSX: LD A,(FUNCT) ; Get function number
2647 0C8E' D6 28 SUB 40 ; Test if Write RR with zero fill
2648 0C90' 20 33' JR NZ,WRITS6 ; No then jump
2649 0C92' D5 PUSH DE ; Save blocknumber
2650 0C93' 2A 0034' LD HL,(DIRBUF) ; Use directory buffer for zero fill
2651 0C96' 06 80 LD B,128 ; 128 bytes to clear
2652 0C98' 77 WRITS3: LD (HL),A ; Clear directory buffer
2653 0C99' 23 INC HL ; Increment pointer
2654 0C9A' 10 FC' DJNZ WRITS3 ; Clear all bytes
2655 0C9C' CD 06D7' CALL CALSEC ; Calculate sector number (128 bytes)
2656 0C9F' 3A 003F' LD A,(NMASK) ; Get sector mask
2657 0CA2' 47 LD B,A ; Copy it
2658 0CA3' 04 INC B ; Increment it to get number of writes
2659 0CA4' 2F CPL ; Complement sector mask
2660 0CA5' A3 AND E ; Mask sector number
2661 0CA6' 5F LD E,A ; And save it
2662 0CA7' 0E 02 LD C,2 ; Set write new block flag
2663 0CA9' E5 WRITS4: PUSH HL ; Save registers
2664 0CAA' D5 PUSH DE
2665 0CAB' C5 PUSH BC
2666 0CAC' CD 067A' CALL CALST ; Calculate sector/track
2667 0CAF' CD 083D' CALL DMADIR ; Set DMA directory buffer
2668 0CB2' C1 POP BC ; Get write new block flag
2669 0CB3' C5 PUSH BC ; Save it again
2670 0CB4' CD 079A' CALL WRITER ; Write record on disk
2671 0CB7' C1 POP BC ; Restore registers
2672 0CB8' D1 POP DE
2673 0CB9' E1 POP HL
2674 0CBA' 0E 00 LD C,0 ; Clear write new block flag
2675 0CBC' 1C INC E ; Increment sector number
2676 0CBD' 10 EA' DJNZ WRITS4 ; Write all blocks
2677 0CBF' CD 0837' CALL STDMA ; Set user DMA address
2678 0CC2' D1 POP DE ; Get Block Number
2679 0CC3' 0E 00 WRITS5: LD C,0 ; Clear write new block flag
2680 0CC5' DDCB 0EBE WRITS6: RES 7,(IX+FCBMOD) ; Reset FCB/File Modified flag
2681 0CC9' C5 PUSH BC ; Save it
2682 0CCA' CD 06D7' CALL CALSEC ; Calculate sector number (128 bytes)
2683 0CCD' CD 067A' CALL CALST ; Calculate Sector/Track
2684 0CD0' C1 POP BC ; Get write new block flag
2685 0CD1' CD 079A' CALL WRITER ; Write record on disk
2686 0CD4' DD7E 20 LD A,(IX+NXTREC) ; Get record counter
2687 0CD7' DDBE 0F CP (IX+FCBREC) ; Compare with next record
2688 0CDA' 38 08' JR C,WRITS7 ; If less then jump
2689 0CDC' 3C INC A ; Increment record count
2690 0CDD' DD77 0F LD (IX+FCBREC),A ; Save it on next record position
2691 0CE0' DDCB 0EBE RES 7,(IX+FCBMOD) ; Reset FCB/File Modified flag
ZMAC Relocating Macro Assembler v 1.7, page 55
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2692 0CE4' 3A 004B' WRITS7: LD A,(FUNCT) ; Get function number
2693 0CE7' FE 14 CP 20 ; (hfb)
2694 0CE9' D8 RET C ; Return if < 20 (hfb)
2695 0CEA' FE 16 CP 21+1 ; (hfb)
2696 0CEC' D0 RET NC ; Return if > 21 (hfb)
2697 0CED' DD34 20 INC (IX+NXTREC) ; Increment record count
2698 0CF0' C9 RET ; And return to caller
2700 0CF1' 3E 02 WRITS8: LD A,2 ; Set disk full error
2701 0CF3' C3 04BB' JP SAVEA ; And return to caller
2704 ; Load FCB for Random Read/Write
2705 ; Exit : Zero Flag = 1 No Error
2706 ; 0 Error Occured
2708 0CF6' 32 004F' LDFCB: LD (RDWR),A ; Save Read/Write flag
2709 0CF9' DD7E 21 LD A,(IX+33) ; Get first byte random record
2710 0CFC' 57 LD D,A ; Save it in D
2711 0CFD' CBBA RES 7,D ; Reset MSB to get next record
2712 0CFF' 17 RLA ; Shift MSB in carry
2713 0D00' DD7E 22 LD A,(IX+34) ; Load next byte random record
2714 0D03' 17 RLA ; Shift Carry
2715 0D04' F5 PUSH AF ; Save it
2716 0D05' E6 1F AND MAXEXT ; Mask next extent
2717 0D07' 4F LD C,A ; Save it in C
2718 0D08' F1 POP AF ; Get byte
2719 0D09' 17 RLA ; Shift 4 times
2720 0D0A' 17 RLA
2721 0D0B' 17 RLA
2722 0D0C' 17 RLA
2723 0D0D' E6 0F AND 0FH ; Mask it
2724 0D0F' 47 LD B,A ; Save data module number
2725 0D10' DD7E 23 LD A,(IX+35) ; Get next byte random record
2726 0D13' 1E 06 LD E,6 ; Set random record to large flag
2727 0D15' FE 04 CP 4 ; Test random record to large
2728 0D17' 30 5C' JR NC,LDFCB8 ; Yes then error
2729 0D19' 07 RLCA ; Shift 4 times
2730 0D1A' 07 RLCA
2731 0D1B' 07 RLCA
2732 0D1C' 07 RLCA
2733 0D1D' 80 ADD A,B ; Add byte
2734 0D1E' 47 LD B,A ; Save data module number in B
2735 0D1F' DD72 20 LD (IX+NXTREC),D ; Set next record count
2736 0D22' DD56 0E LD D,(IX+FCBMOD) ; Get data module number
2737 0D25' CB72 BIT 6,D ; Test error random record
2738 0D27' 20 0E' JR NZ,LDFCB0 ; Yes then jump
2739 0D29' 79 LD A,C ; Get new extent number
2740 0D2A' DDBE 0C CP (IX+FCBEXT) ; Compare with FCB
2741 0D2D' 20 08' JR NZ,LDFCB0 ; Not equal then open next extent
2742 0D2F' 78 LD A,B ; Get new data module number
2743 0D30' DDAE 0E XOR (IX+FCBMOD) ; Compare with data module number
2744 0D33' E6 3F AND MAXMOD ; Mask it
2745 0D35' 28 37' JR Z,LDFCB6 ; Equal then return
2746 0D37' CB7A LDFCB0: BIT 7,D ; Test FCB modified (write)
2747 0D39' 20 0F' JR NZ,LDFCB1 ; No then jump
ZMAC Relocating Macro Assembler v 1.7, page 56
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2748 0D3B' D5 PUSH DE ; Save registers
2749 0D3C' C5 PUSH BC
2750 0D3D' CD 07AB' CALL CLOSE ; Close extent
2751 0D40' C1 POP BC ; Restore registers
2752 0D41' D1 POP DE
2753 0D42' 1E 03 LD E,3 ; Set close error
2754 0D44' 3A 004C' LD A,(PEXIT) ; Get exit code
2755 0D47' 3C INC A
2756 0D48' 28 27' JR Z,LDFCB7 ; Error then exit
2757 0D4A' CD 0B9E' LDFCB1: CALL SETDME ; Save Data Module and Extent
2758 0D4D' CD 08F1' CALL SEAR15 ; Search next FCB
2759 0D50' 3A 004C' LD A,(PEXIT) ; Get error code
2760 0D53' 3C INC A
2761 0D54' 20 15' JR NZ,LDFCB5 ; No error then exit
2762 0D56' 3A 004F' LD A,(RDWR) ; Get read/write flag
2763 0D59' 1E 04 LD E,4 ; Set read empty record
2764 0D5B' 3C INC A
2765 0D5C' 20 13' JR NZ,LDFCB7 ; Read then error
2766 0D5E' CD 0B09' CALL MAKES ; Make new FCB
2767 0D61' 1E 05 LD E,5 ; Set make error
2768 0D63' 3A 004C' LD A,(PEXIT) ; Get error code
2769 0D66' 3C INC A
2770 0D67' 28 08' JR Z,LDFCB7 ; Error then exit
2771 0D69' 18 03' JR LDFCB6 ; No error exit (zero set)
2773 0D6B' CD 0AC2' LDFCB5: CALL OPENF0 ; Open file
2774 0D6E' C3 0B82' LDFCB6: JP OPENX6 ; Set zero flag and clear error code
2776 0D71' DD36 C00E LDFCB7: LD (IX+FCBMOD),0C0H ; Set random record error
2777 0D75' 7B LDFCB8: LD A,E ; Get error code
2778 0D76' 32 004C' LD (PEXIT),A ; And save it
2779 0D79' B7 OR A ; Clear zero flag
2780 0D7A' DDCB 0EFE SETB14: SET 7,(IX+FCBMOD) ; (hfb) get FCB/File Not Modified
2781 0D7E' C9 RET ; And return to caller
2783 ; Calculate Random Record
2784 ; Entry HL=Offset in FCB
2785 ; DE=FCB Pointer
2786 ; Exit D=LSB Random Record
2787 ; C=ISB Random Record
2788 ; B=MSB Random Record
2790 0D7F' 19 CALRRC: ADD HL,DE ; Pointer to FCB+15 or FCB+32
2791 0D80' 7E LD A,(HL) ; Get record number
2792 0D81' 21 000C LD HL,12 ; Offset to extent number
2793 0D84' 19 ADD HL,DE ; Get pointer to extent byte
2794 0D85' 57 LD D,A ; Save record number
2795 0D86' 7E LD A,(HL) ; Get extent byte
2796 0D87' E6 1F AND MAXEXT ; Mask it 000eeeee
2797 0D89' CB12 RL D ; Shift MSB in Carry Cy=R, d=rrrrrrr0
2798 0D8B' CE 00 ADC A,0 ; Add Carry 00xeeeex
2799 0D8D' 1F RRA ; Shift 1 time (16 bits) 000xeeee
2800 0D8E' CB1A RR D ; D=xrrrrrrr
2801 0D90' 4F LD C,A ; Save ISB
2802 0D91' 23 INC HL ; Increment to data module number
2803 0D92' 23 INC HL
ZMAC Relocating Macro Assembler v 1.7, page 57
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2804 0D93' 7E LD A,(HL) ; Get data module number 00mmmmmm
2805 0D94' 0F RRCA ; Divide module by 16
2806 0D95' 0F RRCA
2807 0D96' 0F RRCA
2808 0D97' 0F RRCA
2809 0D98' F5 PUSH AF ; Save it mmmm00mm
2810 0D99' E6 03 AND 03H ; Mask for maximum module
2811 0D9B' 47 LD B,A ; Save it 000000mm
2812 0D9C' F1 POP AF ; Get LSB
2813 0D9D' E6 F0 AND 0F0H ; Mask it mmmm0000
2814 0D9F' 81 ADD A,C ; Add with ISB mmmxeeee
2815 0DA0' 4F LD C,A ; Save ISB
2816 0DA1' D0 RET NC ; No carry then return
2817 0DA2' 04 INC B ; Increment MSB 000000mm
2818 0DA3' C9 RET ; And return to caller
2819 ; 000000mm mmmxeeee xrrrrrrr
ZMAC Relocating Macro Assembler v 1.7, page 58
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2821 IF ZS
2822 ;************************************************************************
2823 ;* U n i v e r s a l T i m e / D a t e S u p p o r t *
2824 ;************************************************************************
2826 ; In order to provide time/date support for as many systems as possible,
2827 ; a set of universal routines are used. These routines do not do the
2828 ; actual stamping, but provide all the data required to method specific
2829 ; programs to perform the needed services. To use the DOS services, the
2830 ; external handler needs to tie itself into the Time/Date vector table
2831 ; in the ZSDOS configuration area. The Get Stamp, Put Stamp, Stamp Last
2832 ; Access, Stamp Create, and Stamp Modify routines receive the following
2833 ; parameters in the Z80 registers:
2834 ; A = Offset to DIR entry [0,20H,40H,60H]
2835 ; BC = Address of ZSDOS WRFCB routine
2836 ; DE = Pointer to Directory Buffer
2837 ; HL = DMA address
2838 ; IX = Pointer to FCB passed to DOS
2839 ; The directory buffer contains the dir entry for the FCB passed to DOS,
2840 ; A contains the offset. The disk has been tested for R/O on all calls
2841 ; except get stamp and is R/W. If a CP/M+ style stamping is used, a simple
2842 ; call to the address passed in BC is used to update the disk after adding
2843 ; the time as required. This call is ALWAYS required. The routines may
2844 ; use AF,BC,DE, and HL without restoring them. Four levels of stack are
2845 ; available on the DOS stack for use by the functions. All routines must
2846 ; exit with a RET instruction, and A=1 if successful, A=0FFH if error.
2848 ; Get/put Timestamps
2850 0DA4' CMD102:
2851 0DA4' CD 051F' CMD103: CALL SELDRV ; Select DU: from FCB
2852 0DA7' CD 0719' CALL SRCT15 ; Find the FCB
2853 0DAA' 28 31' JR Z,DOTDER ; If not found
2854 0DAC' 2A 001E' LD HL,(GETSTV) ; Get time stamp function address
2855 0DAF' 3A 004B' LD A,(FUNCT)
2856 0DB2' FE 66 CP 102 ; Get stamp?
2857 0DB4' 28 0A' JR Z,DOTDR3 ; Yes
2858 0DB6' 2A 0020' LD HL,(PUTSTV) ; Get address of set stamp routine
2859 ; ..fall thru to common code..
2860 ; Enter here for Stamp Last Access, Stamp Create, Stamp Modify
2862 0DB9' E5 STAMPT: PUSH HL
2863 0DBA' CD 08E5' CALL CHKRO1 ; Test for disk W/P but avoid error trap
2864 0DBD' E1 POP HL
2865 0DBE' 28 1D' JR Z,DOTDER ; No stamp if disk is W/P
2867 0DC0' CD 0BA6' DOTDR3: CALL GETDME ; Get Data Module and Extent Number
2868 0DC3' 20 18' JR NZ,DOTDER ; ..Quit if Not Extent 0 of Module 0
2869 0DC5' 3A 0056' LD A,(SECPNT) ; Offset to FCB in dirbuf
2870 0DC8' ED5B 0034' LD DE,(DIRBUF) ; Dir buffer pointer
2871 0DCC' 01 0817' LD BC,WRFCB ; Address of WRFCB routine
2872 0DCF' E5 PUSH HL ; Save function vector
2873 0DD0' 2A 002E' LD HL,(DMA) ; Put DMA in HL
2874 0DD3' C9 RET ; Then vector to routine
2876 ; Time and Date Routines. Like the date stamping routines, the user must
ZMAC Relocating Macro Assembler v 1.7, page 59
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2877 ; supply the actual driver routines for time and date. These routines are
2878 ; attached to ZSDOS via the vector table in the configuration area. The
2879 ; routines are passed the address to Get/Put the Time and Date in the DE
2880 ; and IX registers. The routines may use AF,BC, and D without restor-
2881 ; ing them. Four levels of stack are available on the DOS stack for use
2882 ; by the the functions. All routines must exit with a RET instruction,
2883 ; and A=1 if successful, A=0FFH if error.
2884 ; In order to better provide for internal DateStamper, the clock routines
2885 ; must save the value at DE+5 when called, and return this value to the
2886 ; DOS in the E register. In addition, the HL register must be returned
2887 ; as the called DE value +5.
2888 ; The Time/Date string consists of 6 packed BCD digits arrayed as:
2889 ; Byte 00 01 02 03 04 05
2890 ; YY MM DD HH MM SS
2892 ; Set Time/Date from user-supplied buffer string
2894 0DD4' 0E 01 CMD99: LD C,1 ; Set parameter to set time/date
2895 0DD6' 21 DEFB 21H ; ..and fall thru to GSTD
2897 ; Get Time/Date to string whose address is supplied by the user
2899 0DD7' 0E 00 CMD98: LD C,0 ; Set parameter to get time/date
2900 0DD9' 2A 0016' GSTD: LD HL,(GSTIME) ; Get time/date get/set routine address
2901 0DDC' E5 PUSH HL ; ..to stack for pseudo "Jump"
2902 0DDD' F6 FF DOTDER: OR 0FFH ; Save 1 T state while setting flags
2903 0DDF' C9 RET ; Vector to service routine
2904 ENDIF ;Zs
ZMAC Relocating Macro Assembler v 1.7, page 60
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
2906 IF NOT ZS
3105 ENDIF
3107 ; Calculate checksum of 127 bytes addressed by HL. Return with HL
3108 ; pointing to the 128th byte.
3110 0DE0' 06 7F CKS127: LD B,127 ; Test 1st 127 bytes
3111 0DE2' 86 CKSLP: ADD A,(HL) ; Sum all bytes to A
3112 0DE3' 23 INC HL
3113 0DE4' 10 FC' DJNZ CKSLP
3114 0DE6' C9 RET
ZMAC Relocating Macro Assembler v 1.7, page 61
ZSDOS 1.1 - Enhanced CP/M BDOS Replacement ZSDOS .Z80
33/20/A6 41:00
3117 ;**************************************************************
3118 ;* Z S D O S H i g h R A M D a t a *
3119 ;**************************************************************
3121 ; High RAM area. These locations are not stored by an IOP or
3122 ; BackGrounder.
3124 0DE7' CODEND:
3125 IF ROM
3126 IF $-ZSDOS GT 0E00H
3130 ELSE
3131 IF ZS
3132 IF $-ZSDOS GT 0DF1H
3134 ENDIF ;$-zsdos
3135 ORG ZSDOS+0DF1H ; Set here for Internal Path
3137 IF $-ZSDOS GT 0DF9H
3141 ENDIF ;Zs
3142 ENDIF ;Rom
3143 0DF1' HIRAM:
3144 IF ZS
3145 0DF1' 01 00 IPATH: DEFB 1,0 ; Internal Path = Drive A, User 0
3146 0DF3' 0000 0000 DEFW 00,00 ; ..two more blank entries
3147 0DF7' 00 DEFB 0 ; ...and ending Null
3148 0DF8' 0000 TDFVCT: DEFW 00 ; Time and date file vector
3151 ENDIF ;Zs
3152 0DFA' 0000 LOGIN: DEFW 00 ; Login vector
3153 0DFC' 0000 DSKWP: DEFW 00 ; Disk write protect vector
3154 0DFE' 0000 HDLOG: DEFW 00 ; Fixed disk login vector
3156 IF ROM
3158 ELSE
3159 = 000A FREEMEM EQU HIRAM-CODEND
3160 ENDIF ;Rom
3162 ; Variables for use with BGii
3164 = 0008 BGLOWL EQU BGHIRAM-BGLORAM ; Size of Low RAM save
3165 = 006D BGHIL EQU BGRAMTOP-BGHIRAM ; Size of Hi RAM save
3167 END ; End program