LS-DOS 6.3.1 - SYS0/SYS Assembly Listing (HTML format version)
[Copyright 1999,2002 Frank Durda IV, All Rights Reserved.
Mirroring of any material on this page in any form is expressly prohibited.
The official web site for this material is: http://nemesis.lonestar.org
Contact this address for use clearances: clearance at nemesis.lonestar.org
Comments and queries to this address: web_software at nemesis.lonestar.org]
MISOSYS EDAS-4.3 04/11/99 20:43:48 SYSRES - LS-DOS 6.2 Page 00001
00001 ;SYSRES/ASM - LS-DOS 6.2
000A 00003 LF EQU 10
000D 00004 CR EQU 13
00005 ;
00006 ;*LIST OFF ;Xref of Lowcore
0000 00007 *GET LDOS60/EQU:2
08F0 00008 @$SYS EQU 08F0H
0000 00009 @@1 DEFL 0000H
0000 00010 @@2 DEFL 0000H
0000 00011 @@3 DEFL 0000H
0000 00012 @@4 DEFL 0000H
0877 00013 @BANK EQU 0877H
FFFF 00014 @BLD631 EQU 0FFFFH
FFFF 00015 @BLD631C EQU 0FFFFH
FFFF 00016 @BLD631D EQU 0FFFFH
FFFF 00017 @BLD631E EQU 0FFFFH
FFFF 00018 @BLD631F EQU 0FFFFH
FFFF 00019 @BLD631G EQU 0FFFFH
FFFF 00020 @BLD631H EQU 0FFFFH
1300 00021 @BYTEIO EQU 1300H
0689 00022 @CHNIO EQU 0689H
0553 00023 @CKBRKC EQU 0553H
0545 00024 @CLS EQU 0545H
0623 00025 @CTL EQU 0623H
06E3 00026 @DIV16 EQU 06E3H
0642 00027 @DSP EQU 0642H
052D 00028 @DSPLY EQU 052DH
0000 00029 @FRENCH EQU 0000H
0000 00030 @GERMAN EQU 0000H
0638 00031 @GET EQU 0638H
07BD 00032 @HEX16 EQU 07BDH
07C2 00033 @HEX8 EQU 07C2H
06F8 00034 @HEXD EQU 06F8H
06F6 00035 @HEXDEC EQU 06F6H
0000 00036 @HZ50 EQU 0000H
0000 00037 @INTL EQU 0000H
0630 00038 @JCL EQU 0630H
0635 00039 @KBD EQU 0635H
0628 00040 @KEY EQU 0628H
0585 00041 @KEYIN EQU 0585H
0089 00042 @KITSK EQU 0089H
0503 00043 @LOGER EQU 0503H
0500 00044 @LOGOT EQU 0500H
0000 00045 @MOD2 EQU 0000H
FFFF 00046 @MOD4 EQU 0FFFFH
0530 00047 @MSG EQU 0530H
06C9 00048 @MUL16 EQU 06C9H
0084 00049 @OPREG EQU 0084H
0528 00050 @PRINT EQU 0528H
063D 00051 @PRT EQU 063DH
0E29 00052 @PRTIMO EQU 0E29H
0645 00053 @PUT EQU 0645H
0FE9 00054 @RSTNMI EQU 0FE9H
0680 00055 @RSTREG EQU 0680H
078D 00056 @TIME EQU 078DH
FFFF 00057 @USA EQU 0FFFFH
0B99 00058 @VDCTL EQU 0B99H
0D38 00059 @VDCTL3 EQU 0D38H
0935 00060 @VDPRT EQU 0935H
0D42 00061 @_VDCTL EQU 0D42H
0DF1 00062 ADDR_2_ROWCOL EQU 0DF1H
0201 00063 BAR$ EQU 0201H
439D 00064 BOOTST$ EQU 439DH
0200 00065 BUR$ EQU 0200H
0A7B 00066 CASHK$ EQU 0A7BH
006C 00067 CFLAG$ EQU 006CH
0300 00068 CORE$ DEFL 0300H
F800 00069 CRTBGN$ EQU 0F800H
0033 00070 DATE$ EQU 0033H
07A8 00071 DATELO$ EQU 07A8H
04C7 00072 DAYTBL$ EQU 04C7H
0031 00073 DCBKL$ EQU 0031H
0470 00074 DCT$ EQU 0470H
006D 00075 DFLAG$ EQU 006DH
0846 00076 DIS_DO_RAM EQU 0846H
0B94 00077 DODATA$ EQU 0B94H
0210 00078 DODCB$ EQU 0210H
0C44 00079 DO_CONTROL EQU 0C44H
0CB8 00080 DO_DSPCHAR EQU 0CB8H
0C8C 00081 DO_INVERT_DIS EQU 0C8CH
0C89 00082 DO_INVERT_ENA EQU 0C89H
0C9B 00083 DO_INVERT_OFF EQU 0C9BH
0000 00084 DO_MASK EQU 0000H
0BCB 00085 DO_RET EQU 0BCBH
0BCC 00086 DO_RET1 EQU 0BCCH
0CCE 00087 DO_SCROLL EQU 0CCEH
0BEA 00088 DO_TABS EQU 0BEAH
04C0 00089 DSKTYP$ EQU 04C0H
04C2 00090 DTPMT$ EQU 04C2H
0FF4 00091 DVREND$ EQU 0FF4H
0206 00092 DVRHI$ EQU 0206H
0817 00093 ENADIS_DO_RAM EQU 0817H
000E 00094 FDDINT$ EQU 000EH
006A 00095 FLGTAB$ EQU 006AH
0DAE 00096 GET_@_ROWCOL EQU 0DAEH
0750 00097 HERTZ$ EQU 0750H
040E 00098 HIGH$ EQU 040EH
0072 00099 IFLAG$ EQU 0072H
0420 00100 INBUF$ EQU 0420H
003E 00101 INTVC$ EQU 003EH
0203 00102 JCLCB$ EQU 0203H
0230 00103 JLDCB$ EQU 0230H
07D6 00104 KCK@ EQU 07D6H
0074 00105 KFLAG$ EQU 0074H
08FC 00106 KIDATA$ EQU 08FCH
0208 00107 KIDCB$ EQU 0208H
0202 00108 LBANK$ EQU 0202H
0401 00109 MAXDAY$ EQU 0401H
0076 00110 MODOUT$ EQU 0076H
04DC 00111 MONTBL$ EQU 04DCH
0077 00112 NFLAG$ EQU 0077H
0078 00113 OPREG$ EQU 0078H
086E 00114 OPREG_SV_AREA EQU 086EH
0835 00115 OPREG_SV_PTR EQU 0835H
0410 00116 PAKNAM$ EQU 0410H
0382 00117 PAUSE@ EQU 0382H
07AF 00118 PCSAVE$ EQU 07AFH
001B 00119 PDRV$ EQU 001BH
0218 00120 PRDCB$ EQU 0218H
0DCD 00121 PUTA@DE EQU 0DCDH
0DCA 00122 PUT_@ EQU 0DCAH
0DC6 00123 PUT_@_ROWCOL EQU 0DC6H
007B 00124 RFLAG$ EQU 007BH
0DD0 00125 ROWCOL_2_ADDR EQU 0DD0H
04C4 00126 RSTOR$ EQU 04C4H
0238 00127 S1DCB$ EQU 0238H
0CF3 00128 SET_SCROLL EQU 0CF3H
007C 00129 SFLAG$ EQU 007CH
0220 00130 SIDCB$ EQU 0220H
0228 00131 SODCB$ EQU 0228H
0380 00132 STACK$ EQU 0380H
0000 00133 START$ EQU 0000H
002D 00134 TIME$ EQU 002DH
002C 00135 TIMER$ EQU 002CH
002B 00136 TIMSL$ EQU 002BH
0713 00137 TIMTSK$ EQU 0713H
04C3 00138 TMPMT$ EQU 04C3H
07B1 00139 TRACE_INT EQU 07B1H
0A8F 00140 TYPHK$ EQU 0A8FH
0B26 00141 TYPTSK$ EQU 0B26H
007F 00142 VFLAG$ EQU 007FH
0401 00143 ZERO$ EQU 0401H
00144 ;*LIST ON
0000 00145 *GET COPYCOM:3 ;Embed copyright notice
00146 ; COPYCOM - File for Copyright COMment block
00147 ;
0000 00148 *GET BUILDVER/ASM:3
00149 ;
00150 ; Buildver/asm is a bit of a kludge since not all utilities can load
00151 ; equates from LDOS60 and still compile. LOWCORE and everybody else
00152 ; relies on this setting, and it eventually ends up in LDOS60/EQU
00153 ; for programs that can use that.
00154 ;
FFFF 00155 @BLD631 EQU -1 ;<631>Build 631 distribution (LEVEL 1B)
00156 ; These switches activate patches made since the 1B release.
00157 ; It is important that all earlier patches be enabled when a higher
00158 ; patch is enabled.
00159 ; Patches C thru F were published in TMQ IV.iv, page 32 (NOTE: the
00160 ; patch addresses listed for SPOOL in SPOOL1/FIX are 19H high.)
FFFF 00161 @BLD631C EQU -1 ;<631>Apply 1C patches (SETKI)
FFFF 00162 @BLD631D EQU -1 ;<631>Apply 1D patches (DIR)
FFFF 00163 @BLD631E EQU -1 ;<631>Apply 1E patches (DIR & MEMDISK/DCT)
FFFF 00164 @BLD631F EQU -1 ;<631>Apply 1F patches (SPOOL)
00165 ; Patches G and H were published in TMQ V.i, pages 10 and 18/19.
FFFF 00166 @BLD631G EQU -1 ;<631>Apply 1G patches (//KEYIN,DIR,DO *)
FFFF 00167 @BLD631H EQU -1 ;<631>Apply 1H patches (MEMORY)
00168 ;
00169 ;End of BUILDVER/ASM
00170 IF @BLD631
00172 ELSE
00173 COM '<*(C) 1982,3,4,6 by LSI*>'
00174 ENDIF
00175 ;
00177 ;
00178 ; LDOS 6.2 Low Core RAM storage assignments
00179 ; Copyright (C) 1982 by Logical Systems, Inc.
00180 ;
0000 00181 START$ EQU 0
0000 00182 ORG 0+START$
00183 ;
00184 ; Page 0 - RST's, data, and buffers
00185 ;
0000 F3 00186 @RST00 DI ;IPL Entry for R/S 4-P
0001 3E01 00187 LD A,00000001B ;Set image in A
0003 D39C 00188 OUT (9CH),A ;toggle in BOOT/ROM
0005 00 00189 DB 0,0,0 ;CP/M emulator SVC
00 00
0008 C9 00190 @RST08 RET
0009 0000 00191 DW 0
000B 0000 00192 SVCRET$ DW 0 ;Return address from SVC
000D 00 00193 LSVC$ DB 0 ;Last SVC executed
000E F3 00194 FDDINT$ DI ;NOP or DI (F3H) for
000F C9 00195 RET ; System (Smooth)
0010 C9 00196 @RST10 RET
0011 0000 00197 DW 0
0013 00198 USTOR$ DS 5 ;User storage area
0018 C9 00199 @RST18 RET
0019 0000 00200 DW 0
001B 01 00201 PDRV$ DB 1 ;Current drive, physical
001C 0000 00202 PHIGH$ DW 0 ;Physical HIGH$
001E 0030 00203 LOW$ DW 3000H ;Lowest usable memory
0020 C9 00204 @RST20 RET
0021 0000 00205 DW 0
0023 00 00206 LDRV$ DB 0 ;Current drive, logical
0024 0000 00207 JDCB$ DW 0 ;Saved FCB pointer
0026 0000 00208 JRET$ DW 0 ;Saved I/O return address
0028 C35B1A 00209 @RST28 JP RST28 ;System SVC processor
002B 55 00210 TIMSL$ DB 55H ;Fast=55, slow=FF
002C 00 00211 TIMER$ DB 0 ;RTC counter
002D 00 00212 TIME$ DC 3,0 ;SS:MM:HH storage area
00 00
0030 C3A019 00213 @RST30 JP @DEBUG ;DEBUG call address
0033 00214 DATE$ DS 5 ;YY/DD/MM/packed
0038 C3FF1B 00215 @RST38 JP RST38@ ;Interrupt RST
00216 IF @BLD631
003B 01 00217 OSRLS$ DB 01H ;<631>OS Release #
00218 ELSE
00219 OSRLS$ DB 00H ;OS Release #
00220 ENDIF
00221 ;
00222 ; INTIM$ stores the image read from RDINTSTATUS*
00223 ;
003C 00 00224 INTIM$ DB 0 ;Interrupt latch image
00225 ;
00226 ; INTMSK$ masks the image read from RDINTSTATUS*
00227 ; LDOS 6.x permits only RS-232 RCV INT, IOBUS INT,
00228 ; and RTC INT to be used by the TASKER off of RST38
00229 ;
003D 2C 00230 INTMSK$ DB 2CH ;Mask for INTIM$
00231 ;
00232 ; INTVC$ stores the eight vectors associated
00233 ; with the INTIM$ bit assignments
00234 ;
003E 481C 00235 INTVC$ DW RETINST ;Primary interrupts
0040 481C 00236 DW RETINST,RTCPROC,RETINST
941C 481C
0046 481C 00237 DW RETINST,RETINST,RETINST,RETINST
481C 481C 481C
00238 ;
00239 ; TCB$ stores the TCB vectors for task slots 0-11
00240 ;
004E 00241 TCB$ DS 24 ;Interrupt task vectors
00242 ;
00243 ; NMI vector used in disk I/O
00244 ;
0066 00245 @NMI DS 3 ;Don't overlay this
00246 ;
00247 ; OVRLY$ stores the system's overlay request #
00248 ;
0069 00 00249 OVRLY$ DB 0 ;Current overlay resident
00250 ;
00251 ; FLGTAB$ stores 26 flags and images. A pointer
00252 ; to this table is obtained from SVC-@FLAGS
00253 ;
006A 00254 FLGTAB$ EQU $
00255 ;
00256 ;
00257 ; AFLAG$ - Start CYL for Allocation search
00258 ;
006A 01 00259 AFLAG$ DB 01 ;AFLAG
006B 00 00260 DB 0 ;BFLAG
00261 ;
00262 ; CFLAG$ assignments:
00263 ; 0 - Cannot change HIGH$ via SVC-100
00264 ; 1 - @CMNDR in execution
00265 ; 2 - @KEYIN request from SYS1
00266 ; 3 - System request for drivers, filters, DCTs
00267 ; 4 - @CMNDR to only execute LIB commands
00268 ; 5 - Sysgen inhibit bit
00269 ; 6 - @ERROR inhibit display
00270 ; 7 - @ERROR to use user (DE) buffer
00271 ;
006C 00 00272 CFLAG$ DB 0 ;Condition flag
00273 ;
00274 ; DFLAG$ assignments:
00275 ; 0 - SPOOL is active
00276 ; 1 - TYPE ahead is active
00277 ; 2 - VERIFY is on
00278 ; 3 - SMOOTH active
00279 ; 4 - MemDISK active
00280 ; 5 - FORMS active
00281 ; 6 - KSM active
00282 ; 7 - accept GRAPHICS in screen print
00283 ;
006D 0A 00284 DFLAG$ DB 00001010B ;DEV Flag (SMOOTH,TYPE)
00285 ;
00286 ; EFLAG$ - Assignments: (sys13 usage)
00287 ; use only bits 4, 5 and 6 to indicate user
00288 ; entry code to be passed to SYS13. SYS13
00289 ; will be executed from SYS1 if this byte
00290 ; is NON/0, bit 4, 5 and 6 will be merged into
00291 ; the SYS13 (1000,1111b) overlay request
00292 ;
006E 00 00293 EFLAG$ DB 0 ;Flag E
006F 00 00294 FEMSK$ DB 0 ;Port FE mask
0070 00 00295 DC 2,0 ;Flags G-H
00
00296 ;
00297 ; IFLAG$ - Assignments: (INTERNATIONAL)
00298 ; 0 - FRENCH
00299 ; 1 - GERMAN
00300 ; 2 - SWISS
00301 ; 3 -
00302 ; 4 -
00303 ; 5 -
00304 ; 6 - Special DMP mode ON/OFF
00305 ; 7 - '7' bit mode ON/OFF
00306 ;
0072 00307 IFLAG$ EQU $
00308 IF @FRENCH
00309 DB 01000001B
00310 ENDIF
00311 IF @GERMAN
00312 DB 01000010B
00313 ENDIF
00314 IF @USA
0072 00 00315 DB 0
00316 ENDIF
0073 00 00317 DB 0 ;Flag J
00318 ;
00319 ; KFLAG$ assignments:
00320 ; 0 - BREAK latch
00321 ; 1 - PAUSE latch
00322 ; 2 - ENTER latch
00323 ; 3 - reserved
00324 ; 4 - reserved
00325 ; 5 - CAPs lock
00326 ; 6 - reserved
00327 ; 7 - character in TYPE ahead
00328 ;
0074 00 00329 KFLAG$ DB 0 ;Keyboard flag
00330 ;
00331 ; LFLAG$ assignments:
00332 ; 0 - inhibit step rate question in FORMAT
00333 ; 4 - inhibit 8" query in FLOPPY/DCT
00334 ; 5 - inhibit # sides question in FORMAT
00335 ; 6,7 - Reserved for IM 2 hardware
00336 ;
0075 11 00337 LFLAG$ DB 00010001B ;LDOS feature inhibit
00338 ;
00339 ; MODOUT$ mask assignments:
00340 ; 0 -
00341 ; 1 - cassette motor on/off
00342 ; 2 - mode select (0 = 80/64, 1 = 40/32)
00343 ; 3 - enable alternate character set
00344 ; 4 - enable external I/O
00345 ; 5 - video wait states (0 = disable, 1 = enable)
00346 ; 6 - clock speed ( 1 = 4 Mhz, 0 = 2 MHz)
00347 ; 7 -
00348 ;
00349 IF @INTL
00350 MODOUT$ DB 70H ;MODOUT international
00351 ELSE
0076 78 00352 MODOUT$ DB 78H ;MODOUT port image (FAST)
00353 ENDIF
00354 ;
00355 ;
00356 ; NFLAG$ - Network flag$
00357 ; 0 - Allow setting of file open bit in DIR
00358 ; 1 / 5 - Reserved
00359 ; 6 - Set if in Task Processor
00360 ; 7 - Reserved
00361 ;
0077 00 00362 DB 0 ;Inhibit open bit in DIR
00363 ;
00364 ; OPREG$ memory management image port
00365 ; 0 - SEL0 - Select map overlay bit 0
00366 ; 1 - SEL1 - Select map overlay bit 1
00367 ; 2 - 80/64 - 1 = 80 x 24
00368 ; 3 - Inverse video
00369 ; 4 - MBIT0 - memory map bit 0
00370 ; 5 - MBIT1 - memory map bit 1
00371 ; 6 - FXUPMEM - fix upper memory
00372 ; 7 - PAGE - page 1K video RAM (set for 80x24)
00373 ;
0078 87 00374 OPREG$ DB 87H ;Memory management image
00375 ;
00376 ; PFLAG$ - Printer flag
00377 ; 7 = Printer spooler is paused
00378 ; 0 - 6 = Reserved
00379 ;
0079 00 00380 DB 0
007A 00 00381 DB 0 ;QFLAG$
00382 ;
00383 ; RFLAG$ - Retry init for FDC driver
00384 ;
007B 08 00385 RFLAG$ DB 08 ;FDC retry count >=2
00386 ;
00387 ; SFLAG$ assignments:
00388 ; 0 - inhibit file open bit
00389 ; 1 - set to 1 if bit-2 set & EXEC file opened
00390 ; 2 - set by @RUN to permit load of EXEC file
00391 ; 3 - SYSTEM (FAST)
00392 ; 4 - BREAK key disabled
00393 ; 5 - JCL active
00394 ; 6 - force extended error messages
00395 ; 7 - DEBUG to be turned on after load
00396 ;
007C 08 00397 SFLAG$ DB 8 ;System flag (FAST)
00398 ;
00399 ;
00400 ; Machine TYPE assignment:
00401 ; All values are in decimal
00402 ;
00403 ; 2 = TRS-80 Model 2
00404 ; 4 = TRS-80 Model 4
00405 ; 5 = TRS-80 MODEL 4P
00406 ; 12 = TRS-80 Model 12
00407 ; 16 = TRS-80 Model 16
00408 ;
00409 IF @MOD4
007D 04 00410 TFLAG$ DB 04 ;Model 4 assignment
00411 ELSE
00412 ERR 'Undefined machine TYPE for TFLAG'
00413 ENDIF
007E 00 00414 DB 0 ;Flag U
00415 ;
00416 ; Video FLAG$ assignments:
00417 ; 0-3 - Set blink rate (1=fastest,7=slowest)
00418 ; 4 - display CLOCK
00419 ; 5 - cursor blink toggle bit
00420 ; 6 - Inhibit blinking cursor (user)
00421 ; 7 - Inhibit blinking cursor (system)
00422 ;
007F 00 00423 VFLAG$ DB 0 ;Blink,Slow,No clock
00424 ;
00425 ; WRINT$ - interrupt mask register
00426 ; 0 - enable 1500 baud rising edge
00427 ; 1 - enable 1500 baud falling edge
00428 ; 2 - enable real time clock
00429 ; 3 - enable I/O bus interrupts
00430 ; 4 - enable RS-232 transmit interrupts
00431 ; 5 - enable RS-232 receive data interrupts
00432 ; 6 - enable RS-232 error interrupt
00433 ;
0080 04 00434 WRINT$ DB 4 ;WRINTMASK port image
0081 00 00435 DB 0 ;Flag x
00436 ;
00437 ; Bits 0-7 indicate new style dating on drives 0-7
00438 ;
0082 FF 00439 YFLAG$ DB 0FFH
0083 00 00440 DB 0 ;Z flag
00441 ;
00442 ; Contents are high-order byte of SVC table
00443 ;
0084 01 00444 DB SVCTAB$<-8 ;MSB of SVC table
00445 ;
00446 ; OSVER$ stores the operating system version
00447 ;
0085 63 00448 OSVER$ DB 63H ;OS version #
00449 ;
00450 ; Vector for config initialization
00451 ;
0086 C9 00452 @ICNFG RET ;Initialization config
0087 0000 00453 DW 0
00454 ;
00455 ; Chain vector for KI task processor
00456 ;
0089 C9 00457 @KITSK RET ;Keyboard task routine
008A 0000 00458 DW 0
00459 ;
00460 ; System File Control Block for overlays
00461 ;
008C 80 00462 SFCB$ DB 80H,0,0 ;System /SYS FCB
00 00
008F 001D 00463 DW SBUFF$
0091 00 00464 DB 0
0092 0000 00465 DW 0,0,0,-1,0,-1,-1
0000 0000 FFFF 0000 FFFF FFFF
00466 ;
00467 ; 32-byte DEBUG save area
00468 ;
00A0 00469 DBGSV$ DS 32
00470 ;
00471 ; Job Control Language File Control Block
00472 ;
00C0 00 00473 JFCB$ DC 3,0
00 00
00C3 001D 00474 DW SBUFF$
00C5 00475 DS 27
00476 ;
00477 ; System Command Line file control block
00478 ;
00E0 00479 CFCB$ EQU $ ;Command Interpreter FCB
00E0 43 00480 CFGFCB$ DB 'CONFIG/SYS.CCC:0',3
4F 4E 46 49 47 2F 53 59
53 2E 43 43 43 3A 30 03
00F1 00481 DS 15
00482 ;
00483 ; Page 1 - System Supervisor Call Table
00484 ;
0100 00485 SVCTAB$ EQU $
00486 IFNE $,100H
00487 ERR 'SVCTBL location violation'
00488 ENDIF
00489 ;
00490 ; Initial version
00491 ;
2400 00492 MAXCOR$ EQU 2400H+START$
3000 00493 MINCOR$ EQU 3000H+START$
1300 00494 ORG @BYTEIO
00495 ;
00496 ; file positioning routines - MUST BE FIRST
00497 ;
1300 00500 *GET FILPOSN:3
00501 ;FILPOSN/ASM - LS-DOS 6.3
00502 ;
00503 ; Entry for byte I/O from @GET & @PUT
00504 ;
1300 DDE5 00505 BYTEIO PUSH IX
1302 D1 00506 POP DE ;Transfer DCB to DE
1303 CD6815 00507 CALL CKOPEN@ ;Ck file open, save regs
1306 DDCB01FE 00508 SET 7,(IX+1) ;Denote byte or LRec
130A 78 00509 LD A,B ;Get type code & test
130B FE02 00510 CP 2 ;For get/put
130D 79 00511 LD A,C
130E 281F 00512 JR Z,WRCHAR ;Go on PUT
1310 3058 00513 JR NC,IORETZ ;Ignore if CTL
00514 ;
00515 ; Get a byte from a file
00516 ;
1312 CD9215 00517 RDCHAR CALL CKEOF1 ;Ck for end of file
1315 C0 00518 RET NZ ;Return if at end
1316 DDCB016E 00519 BIT 5,(IX+1) ;If buffer not current,
131A C47913 00520 CALL NZ,NSEC1 ; read next sector
131D C0 00521 RET NZ
131E CD1214 00522 CALL BFRPOS ;Pt to byte posn in bfr
1321 1A 00523 LD A,(DE) ;P/u the byte
1322 DD3405 00524 INC (IX+5) ;Inc NEXT ptr
1325 CC2A13 00525 CALL Z,SET5 ;Set bit 5 if zero
1328 BF 00526 CP A ;Set Z flag--no error
1329 C9 00527 RET
00528 ;
132A DDCB01EE 00529 SET5 SET 5,(IX+1)
132E C9 00530 RET
00531 ;
00532 ; Write a byte to a file
00533 ;
132F DDCB0076 00534 WRCHAR BIT 6,(IX+0) ;Prot level give write acc?
1333 CAC613 00535 JP Z,RWRIT3 ; go if not
1336 F5 00536 PUSH AF ;Save byte
1337 DDCB016E 00537 BIT 5,(IX+1) ;Get next sector if
133B C46C13 00538 CALL NZ,WRCH2 ; buffer is not current
133E 2803 00539 JR Z,WRCH1 ;Skip if read was ok
1340 E3 00540 EX (SP),HL ;Pop stack but keep
1341 E1 00541 POP HL ; error # in AF
1342 C9 00542 RET
00543 ;
1343 CD1214 00544 WRCH1 CALL BFRPOS ;Next bfr byte posn
1346 F1 00545 POP AF
1347 12 00546 LD (DE),A ;Stuff the byte
1348 DDCB01E6 00547 SET 4,(IX+1) ;Buffer contains updated data
134C DD3405 00548 INC (IX+5) ;Inc NEXT byte
134F F5 00549 PUSH AF ;Save Z or NZ flag
1350 CC2A13 00550 CALL Z,SET5 ;Set bit 5 if offset 0
1353 CD9215 00551 CALL CKEOF1 ;Check for EOF
1356 2006 00552 JR NZ,ATEOFW ;Go if there
1358 DDCB0176 00553 BIT 6,(IX+1) ;Jump if EOF set to next
135C 2009 00554 JR NZ,DNTSET ; only if at EOF
135E DD7108 00555 ATEOFW LD (IX+8),C ;Set EOF
1361 DD750C 00556 LD (IX+12),L
1364 DD740D 00557 LD (IX+13),H
1367 F1 00558 DNTSET POP AF ;Restore offset flag
1368 2846 00559 JR Z,RWRIT1 ;Go to write sector if 00
136A AF 00560 IORETZ XOR A ;Set Z flag--no error
136B C9 00561 RET
00562 ;
00563 ; WRCHR needs the next sector - if UPDATE, ck EOF
00564 ;
136C DD7E01 00565 WRCH2 LD A,(IX+1) ;Ck if UPD bit set
136F E607 00566 AND 7 ;Mask for prot level
1371 FE04 00567 CP 4 ;Check for UPD
1373 2004 00568 JR NZ,NSEC1 ;Bypass EOF ck on > UPD
1375 CD9215 00569 NXTSECT CALL CKEOF1 ;Ck for end of file
1378 C0 00570 RET NZ ;Can't extend in update mode
1379 DD7E01 00571 NSEC1 LD A,(IX+1) ;Read access?
137C E607 00572 AND 7
137E FE06 00573 CP 6
1380 3044 00574 JR NC,RWRIT3 ;"Illegal access..." if not
1382 CDCB15 00575 NSEC2 CALL IOREC ;Calc cylinder/sector
1385 C0 00576 RET NZ
1386 DDCB01AE 00577 RES 5,(IX+1) ;Show buffer current
138A DD6E03 00578 LD L,(IX+3) ;P/u buffer address
138D DD6604 00579 LD H,(IX+4)
1390 CDF419 00580 CALL @RDSEC ;Read the sector
1393 2803 00581 JR Z,BUMPNRN ;Go if no error
1395 FE06 00582 CP 6 ;Test for prot sector
1397 C0 00583 RET NZ ;Quit if error not 6
1398 DD340A 00584 BUMPNRN INC (IX+10) ;Inc the NRN ptr LSB
139B 2003 00585 JR NZ,ZEROA@
139D DD340B 00586 INC (IX+11) ; and MSB if necessary
00587 IF @BLD631
00588 @SEEKSC: ;<631>
00589 ENDIF
13A0 AF 00590 ZEROA@ XOR A
13A1 C9 00591 RET
00592 ;
00593 ; Repositioning needs to write out the buffer
00594 ;
13A2 DD7E01 00595 RWRIT@ LD A,(IX+1)
13A5 E690 00596 AND 90H ;Test for non-sector i/o and
13A7 FE90 00597 CP 90H ; buffer contents changed
13A9 2805 00598 JR Z,RWRIT1 ;Go if conditions true
13AB 18F3 00599 JR ZEROA@ ; else no need to write
13AD CD6815 00600 @RWRIT CALL CKOPEN@ ;Ck file open, save regs
13B0 CD0B14 00601 RWRIT1 CALL GETNRN ;P/u NRN
13B3 7C 00602 LD A,H ;Ignore if rewound
13B4 B5 00603 OR L
13B5 C8 00604 RET Z
13B6 2B 00605 DEC HL ;Dec & reset NRN
13B7 DD750A 00606 LD (IX+10),L
13BA DD740B 00607 LD (IX+11),H
00608 ;
00609 ; Check access protection level
00610 ;
13BD DD7E01 00611 RWRIT2 LD A,(IX+1) ;Get prot
13C0 E607 00612 AND 7
13C2 FE05 00613 CP 5 ;Update access or better?
13C4 3804 00614 JR C,RWRIT4
13C6 3E25 00615 RWRIT3 LD A,25H ;Illegal access error code
13C8 B7 00616 OR A ;Return NZ
13C9 C9 00617 RET
00618 ;
13CA E604 00619 RWRIT4 AND 4 ;If UPDATE access, then
13CC 2805 00620 JR Z,RWRIT5 ; can't extend if at EOF
13CE CD9215 00621 CALL CKEOF1
13D1 20F3 00622 JR NZ,RWRIT3 ; so show "Illegal access...
13D3 CDCB15 00623 RWRIT5 CALL IOREC ;Calculate cylinder & sector
13D6 C0 00624 RET NZ
13D7 DD6E03 00625 LD L,(IX+3) ;P/u buffer addr
13DA DD6604 00626 LD H,(IX+4)
13DD DDCB01A6 00627 RES 4,(IX+1) ;Altered buffer flag off
13E1 DDCB00D6 00628 SET 2,(IX+0) ;Show modification done
13E5 CDE819 00629 CALL @WRSEC ; for directory mod flag
13E8 C0 00630 RET NZ
13E9 3E00 00631 VEROP LD A,0 ;Verify operation if set
13EB B7 00632 OR A
13EC C4DC19 00633 CALL NZ,@VRSEC ;Verify if no write error
13EF C0 00634 RET NZ ;Return if wrt/ver error
13F0 CD9813 00635 CALL BUMPNRN ;Increment NRN
00636 ;
00637 ; Check if ERN to be set to NRN
00638 ; Should be done for byte i/o, but not random i/o
00639 ;
13F3 CD9215 00640 CALL CKEOF1 ;Returns 0 if not at EOF
13F6 3D 00641 DEC A ;Set bit 6 if retcod=0
13F7 DDA601 00642 AND (IX+1) ;If IX+1, bit 6 set, then
13FA E640 00643 AND 40H ; don't update EOF unless at
13FC 20A2 00644 JR NZ,ZEROA@ ; or past the old EOF
13FE DD750C 00645 YESEOF LD (IX+12),L ;Update ERN
1401 DD740D 00646 LD (IX+13),H
1404 DDCB015E 00647 BIT 3,(IX+1) ;Test if ending '!'
00648 IF @BLD631
1408 202C 00649 JR NZ,WEOF1 ;<631>Upd dir if so
00650 ELSE
00651 JP NZ,WEOF1 ;Upd dir if so
00652 ENDIF
140A C9 00653 RET
00654 ;
140B DD6E0A 00655 GETNRN LD L,(IX+10) ;Xfer NRN to HL
140E DD660B 00656 LD H,(IX+11)
1411 C9 00657 RET
00658 ;
1412 DD7E05 00659 BFRPOS LD A,(IX+5) ;P/u byte offset in buffer
1415 DD8603 00660 ADD A,(IX+3) ;Add to buffer lsb
1418 5F 00661 LD E,A
1419 DD7E04 00662 LD A,(IX+4) ; and adjust buffer MSB
141C CE00 00663 ADC A,0 ; if needed
141E 57 00664 LD D,A ;Return DE = posn
141F C9 00665 RET
00666 IF @BLD631
00667 ;<631>
00668 ;<631> Return formatted date, HL => user buffer
00669 ;<631>
1420 CDA807 00670 @DATE CALL DATELO$ ;<631>Call existing date code in LOWCORE
1423 E5 00671 PUSH HL ;<631>
1424 2B 00672 DEC HL ;<631>
1425 2B 00673 DEC HL ;<631>
1426 7E 00674 LD A,(HL) ;<631>
1427 FE3A 00675 CP ':' ;<631>Test for decade overflow
1429 3803 00676 JR C,DATE1 ;<631>
142B D60A 00677 SUB 0AH ;<631>
142D 77 00678 LD (HL),A ;<631>
142E E1 00679 DATE1 POP HL ;<631>
142F C9 00680 RET ;<631>
00681 ELSE
00682 ;
00683 ; Entry to seek next record of a file
00684 ;
00685 @SEEKSC CALL CKOPEN@ ;Link to FCB & ck if open
00686 CALL CKEOF1 ;Ensure not > EOF
00687 CALL Z,IOREC ;Get track/sector data
00688 RET NZ ;Back on I/O error
00689 CALL @SEEK ;Issue seek to drive
00690 XOR A ;Ignore seek errors here
00691 RET
00692 ENDIF
00693 IF @BLD631
00694 ;
00695 ; Entry to Write an end-of-file mark
00696 ;<631> This routine relocated here to allow more relative branch references.
00697 ;
1430 CD6815 00698 @WEOF CALL CKOPEN@
1433 CDA213 00699 CALL RWRIT@ ;Write buffer if needed
1436 DD4607 00700 WEOF1 LD B,(IX+7) ;P/u DEC of FPDE
1439 DD4E06 00701 LD C,(IX+6) ;P/u drive #
143C CDBB18 00702 CALL @DIRRD ;Read file's dir record
143F C0 00703 RET NZ ;Back if read error
1440 2C 00704 INC L ;Pt to ERN offset
1441 2C 00705 INC L
1442 2C 00706 INC L
1443 DD7E08 00707 LD A,(IX+8) ;P/u EOF offset
1446 77 00708 LD (HL),A ;Put in direc
1447 111100 00709 LD DE,17 ;Pt to EOF in dir
144A 19 00710 ADD HL,DE
144B DD7E0C 00711 LD A,(IX+12) ;P/u lo EOF
144E 77 00712 LD (HL),A ;Put EOF in direc
144F 23 00713 INC HL
1450 DD7E0D 00714 LD A,(IX+13) ;P/u hi EOF
1453 77 00715 LD (HL),A
1454 C30318 00716 JP @DIRWR ;Write direc and return
00717 ENDIF
00718 ;
00719 ; Entry to Skip record routine
00720 ;
1457 CDDA14 00721 @SKIP CALL @LOC ;Locate next record
145A 03 00722 INC BC ;Step past it
00723 ;
00724 ; Entry to Position to record routine
00725 ;
145B CD6815 00726 @POSN CALL CKOPEN@
145E DDCB01F6 00727 SET 6,(IX+1) ;Upd eof only if NRN>EOF
1462 DDCB017E 00728 BIT 7,(IX+1) ;Jump if sector i/o only
1466 281D 00729 JR Z,POSN1
1468 60 00730 LD H,B ;Record ptr to HL
1469 69 00731 LD L,C
146A DDB609 00732 OR (IX+9) ;P/u LRL
146D 2816 00733 JR Z,POSN1 ;Skip nxt if LRL=256
146F CDC906 00734 CALL @MUL16 ;Calc sector & offset
1472 44 00735 LD B,H ;Physical sector =>BC
1473 4D 00736 LD C,L
1474 DD7705 00737 LD (IX+5),A ;Set byte ptr
1477 DDCB016E 00738 BIT 5,(IX+1) ;Jump if buffer does not
147B 200B 00739 JR NZ,POSN2 ; contain current sector
147D CD0B14 00740 CALL GETNRN ;P/u the NRN
1480 37 00741 SCF
1481 ED42 00742 SBC HL,BC
1483 2812 00743 JR Z,$CKEOF ;Pass on to CKEOF
1485 DD7705 00744 POSN1 LD (IX+5),A ;Offset in buffer
1488 C5 00745 POSN2 PUSH BC
1489 CDA213 00746 POSN2A CALL RWRIT@ ;Write current if needed
148C C1 00747 POP BC ; before moving
148D C0 00748 RET NZ ;Back on write error
148E DD710A 00749 LD (IX+10),C ;NRN
1491 DD700B 00750 LD (IX+11),B
1494 CD2A13 00751 CALL SET5 ;Show bfr does not
1497 C39215 00752 $CKEOF JP CKEOF1 ; contain current sector
00753 ;
00754 ; Entry to force a physical read
00755 ;
149A CD6815 00756 @RREAD CALL CKOPEN@
149D 0E01 00757 LD C,1 ;Cause ADJUST to bump
00758 ; ; NRN when called
149F CD0B14 00759 BKSP1 CALL GETNRN ;Get current record #
14A2 7C 00760 LD A,H ;If file is rewound,
14A3 B5 00761 OR L ; then ignore the req
14A4 2815 00762 JR Z,BKSP0 ; & force OFFSET = 0
14A6 2B 00763 DEC HL ;Back up by 1
14A7 CDBA15 00764 CALL ADJ2 ;RET if sector I/O only,
00765 ; else bump fwd if RREAD
00766 ; then back up if bit 5=0
14AA E5 00767 PUSH HL ;Will be popped into BC
14AB 18DC 00768 JR POSN2A ;Finish the job
00769 ;
00770 ; Entry to backspace one logical record
00771 ;
14AD CD6815 00772 @BKSP CALL CKOPEN@
14B0 4F 00773 LD C,A ;Keep ADJUST from bumping
14B1 DD4609 00774 LD B,(IX+9) ;P/u LRL
14B4 B0 00775 OR B ;Is it a 0
14B5 28E8 00776 JR Z,BKSP1 ;Go if so
14B7 DD7E05 00777 LD A,(IX+5) ;P/u next byte pointer
14BA 90 00778 SUB B ;Sub one record length
14BB DD7705 00779 BKSP0 LD (IX+5),A
14BE 38DF 00780 JR C,BKSP1 ;Go if crossed sec bdry
14C0 AF 00781 XOR A ; else all done
14C1 C9 00782 RET
00783 ;
00784 ; Entry to Rewind to beginning
00785 ;
14C2 CD6815 00786 @REW CALL CKOPEN@
14C5 47 00787 LD B,A ;Zero NRN
14C6 4F 00788 LD C,A
14C7 18BC 00789 JR POSN1 ;Will also zero offset
00790 ;
00791 ; Entry to Position to end-of-file
00792 ;
14C9 CD6815 00793 @PEOF CALL CKOPEN@
14CC DD4E0C 00794 LD C,(IX+12) ;ERN to BC
14CF DD460D 00795 LD B,(IX+13)
14D2 DDB608 00796 OR (IX+8) ;P/u EOF byte
14D5 28AE 00797 JR Z,POSN1 ;Go if full sector
14D7 0B 00798 DEC BC ;Point to last rec
14D8 18AB 00799 JR POSN1 ;Use POSN to get end
00800 ;
00801 ; Entry to Locate current record number
00802 ;
14DA CD6815 00803 @LOC CALL CKOPEN@
14DD CD0B14 00804 CALL GETNRN ;P/u NRN
14E0 CDB715 00805 CALL ADJUST ;Get offset and adj NRN
14E3 DD5E09 00806 LOC1 LD E,(IX+9) ;P/u LRL
14E6 7B 00807 LD A,E ;Test LRL for zero
14E7 B7 00808 OR A ;If zero, then give NRN
14E8 2816 00809 JR Z,LOC3 ;LRL=0, NRN is correct
14EA 0C 00810 INC C ;If offset is zero,
14EB 0D 00811 DEC C ; then it's at 256,
14EC 2801 00812 JR Z,LOC2 ; and we don't dec NRN
14EE 2B 00813 DEC HL
00814 ;
00815 ; Divide the three byte pointer (HLC) by the LRL
00816 ;
14EF CDE306 00817 LOC2 CALL @DIV16 ;Divide (NRN-1)/LRL
14F2 45 00818 LD B,L ;Save high order result
14F3 54 00819 LD D,H ;Save possible overflow
14F4 67 00820 LD H,A ;Prepare 2nd dividend
14F5 69 00821 LD L,C ;P/u low order dividend
14F6 7B 00822 LD A,E ;P/u LRL divisor again
14F7 CDE306 00823 CALL @DIV16
14FA 60 00824 LD H,B ;Xfer high order result
14FB B7 00825 OR A ;If remainder, we have a
14FC 2801 00826 JR Z,$+3 ; partial record to round
14FE 23 00827 INC HL ; up to next record #
14FF 7A 00828 LD A,D ;Xfer possible overflow
1500 C1 00829 LOC3 POP BC ;Pop RESTREG return adr
1501 E3 00830 EX (SP),HL ;Exchange value with BC
1502 C5 00831 PUSH BC ;Restore RESTREG
00832 ;
00833 IF @MOD4
1503 00834 ORARET@ EQU $
00835 ENDIF
1503 B7 00836 OR A
1504 C9 00837 RET
00838 ;
00839 ; Entry to Locate the end-of-file record
00840 ;
1505 CD6815 00841 @LOF CALL CKOPEN@
1508 DD6E0C 00842 LD L,(IX+12) ;P/u ERN
150B DD660D 00843 LD H,(IX+13)
150E DD4E08 00844 LD C,(IX+8) ;EOF byte
1511 18D0 00845 JR LOC1 ;Handle all LRLs
00846 IF @BLD631
00847 ;<631> @WEOF has been relocated above @SKIP in 6.3.1
00848 ELSE
00849 ;
00850 ; Entry to Write an end-of-file mark
00851 ;
00852 @WEOF CALL CKOPEN@
00853 CALL RWRIT@ ;Write buffer if needed
00854 WEOF1 LD B,(IX+7) ;P/u DEC of FPDE
00855 LD C,(IX+6) ;P/u drive #
00856 CALL @DIRRD ;Read file's dir record
00857 RET NZ ;Back if read error
00858 INC L ;Pt to ERN offset
00859 INC L
00860 INC L
00861 LD A,(IX+8) ;P/u EOF offset
00862 LD (HL),A ;Put in direc
00863 LD DE,17 ;Pt to EOF in dir
00864 ADD HL,DE
00865 LD A,(IX+12) ;P/u lo EOF
00866 LD (HL),A ;Put EOF in direc
00867 INC HL
00868 LD A,(IX+13) ;P/u hi EOF
00869 LD (HL),A
00870 JP @DIRWR ;Write direc and return
00871 ENDIF
00872 ;
00873 ; Entry to Read a record
00874 ;
1513 CD6815 00875 @READ CALL CKOPEN@
1516 E5 00876 PUSH HL
1517 CDA213 00877 CALL RWRIT@ ;Write buffer if needed
151A E1 00878 POP HL
151B C0 00879 RET NZ ;Back on write error
151C DD4609 00880 LD B,(IX+9) ;P/u LRL
151F 78 00881 LD A,B ;If LRL=256, just
1520 B7 00882 OR A
1521 CA7513 00883 JP Z,NXTSECT ; get the next sector
1524 E5 00884 RDREC PUSH HL ;Save buffer posn
1525 C5 00885 PUSH BC ;Save LRL
1526 CD1213 00886 CALL RDCHAR ;Read next byte
1529 C1 00887 POP BC
152A E1 00888 POP HL
152B C0 00889 RET NZ ;Back on read error
152C 77 00890 LD (HL),A ;Put char into buffer
152D 23 00891 INC HL ;Bump buffer ptr
152E 10F4 00892 DJNZ RDREC ;Loop for entire record
1530 C9 00893 RET
00894 ;
00895 ; Entry to Write a record
00896 ;
1531 CD6815 00897 @WRITE CALL CKOPEN@
1534 32EA13 00898 WRIT1 LD (VEROP+1),A ;Turn on/off verify
1537 DD4609 00899 LD B,(IX+9) ;P/u LRL
153A 78 00900 LD A,B ;Bypass if LRL=256
153B B7 00901 OR A
153C CABD13 00902 JP Z,RWRIT2
153F E5 00903 PUSH HL ;Save some FCB values
1540 DD6605 00904 LD H,(IX+5) ;P/u buffer offset loc
1543 DD6E08 00905 LD L,(IX+8) ;P/U EOF offset byte
1546 E3 00906 EX (SP),HL ;Put values on stack
00907 ; and recover HL
1547 7E 00908 WRREC LD A,(HL) ;Pass the logical record
1548 23 00909 INC HL ; to the writing routine
1549 E5 00910 PUSH HL ; byte by byte
154A C5 00911 PUSH BC
154B CD2F13 00912 CALL WRCHAR
154E C1 00913 POP BC
154F E1 00914 POP HL
1550 2005 00915 JR NZ,WRERROR ;Exit and fix FCB
1552 10F3 00916 DJNZ WRREC ;Loop for entire record
1554 E3 00917 EX (SP),HL ;Remove stored FCB info
1555 E1 00918 POP HL ;Recover HL
1556 C9 00919 RET
1557 E3 00920 WRERROR EX (SP),HL ;Get FCB Values
1558 DD7405 00921 LD (IX+5),H ; and put them back
155B DD7508 00922 LD (IX+8),L
155E E1 00923 POP HL ;Restore HL
155F C9 00924 RET ;Go back with error
00925 ;
00926 ; Entry to Verify after write of a record
00927 ;
1560 CD6815 00928 @VER CALL CKOPEN@
1563 3C 00929 INC A ;Set verify byte
1564 18CE 00930 JR WRIT1
1566 37 00931 LNKFCB@ SCF ;Init to force file open
1567 D2 00932 DB 0D2H ; test by JP NC,aaaa
1568 1A 00933 CKOPEN@ LD A,(DE) ;Ignore if from LNKFCB
1569 07 00934 RLCA ;Test hi bit of FCB
156A E3 00935 EX (SP),HL
156B 222600 00936 LD (JRET$),HL ;Save ret
156E ED532400 00937 LD (JDCB$),DE ;Save DCB
1572 E3 00938 EX (SP),HL
1573 300F 00939 JR NC,NOTOPEN ;Go if not an open FCB
1575 F1 00940 POP AF ;Get return
1576 D5 00941 PUSH DE ;Dcb addr to IX
1577 DDE3 00942 EX (SP),IX
1579 E5 00943 PUSH HL ;Save regs
157A D5 00944 PUSH DE
157B C5 00945 PUSH BC
157C E5 00946 PUSH HL ;Estab ret
157D 218915 00947 LD HL,RESTREG ; to restore registers
1580 E3 00948 EX (SP),HL
1581 F5 00949 PUSH AF ;Put back ret
1582 AF 00950 XOR A
1583 C9 00951 RET ;Go back
00952 ;
1584 F1 00953 NOTOPEN POP AF
1585 3E26 00954 LD A,26H ;File not open
1587 B7 00955 OR A
1588 C9 00956 RET
00957 ;
1589 C1 00958 RESTREG POP BC ;Pop back registers save
158A D1 00959 POP DE ; in CKOPEN@
158B E1 00960 POP HL
158C DDE1 00961 POP IX
158E C9 00962 RET
00963 ;
00964 ; Entry to Check if at end-of-file
00965 ;
158F CD6815 00966 @CKEOF CALL CKOPEN@
1592 CD0B14 00967 CKEOF1 CALL GETNRN ;P/U NRN into HL
1595 E5 00968 PUSH HL ;Save un-adjusted NRN
1596 CDB715 00969 CALL ADJUST ;Adjust for special cases
1599 7C 00970 LD A,H ;Compare hi byte
159A DDBE0D 00971 CP (IX+13)
159D 200E 00972 JR NZ,CKEOF2 ;Go if not equal
159F 7D 00973 LD A,L ;Compare lo byte
15A0 DDBE0C 00974 CP (IX+12)
15A3 2008 00975 JR NZ,CKEOF2 ;Go if not equal
15A5 0D 00976 DEC C ;Adjust for 00=256
15A6 DD7E08 00977 LD A,(IX+8) ;Compare offset byte
15A9 3D 00978 DEC A
15AA 91 00979 SUB C
15AB 3F 00980 CCF
15AC 03 00981 INC BC ;Restore old C value
15AD E1 00982 CKEOF2 POP HL ;Restore unadjusted NRN
15AE 3E1D 00983 LD A,1DH ;Rec # out of range code
15B0 2002 00984 JR NZ,CKEOF3 ;Go if not at EOF
15B2 3D 00985 DEC A ;X'1C'=EOF encountered
15B3 C9 00986 RET ;Return with NZ flag
15B4 D0 00987 CKEOF3 RET NC ;Return with error
15B5 AF 00988 XOR A ;No error
15B6 C9 00989 RET
00990 ;
00991 ; File positioning adjustment routines
00992 ;
15B7 00993 ADJUST EQU $ ;Entry from @CKEOF & @LOC
15B7 DD4E05 00994 LD C,(IX+5) ;Pick up offset
15BA 00995 ADJ2 EQU $ ;Entry from @BKSP/@RREAD
15BA DDCB017E 00996 BIT 7,(IX+1) ;Sector I/O only?
15BE C8 00997 RET Z ;No adjustment if so
15BF 79 00998 LD A,C ;Offset =0? (or "RREAD?")
15C0 B7 00999 OR A
15C1 2801 01000 JR Z,$+3 ;Go if zero
15C3 23 01001 INC HL ;Adjust
15C4 DDCB016E 01002 BIT 5,(IX+1) ;Check magic bit
15C8 C0 01003 RET NZ ;Go if set
15C9 2B 01004 DEC HL ;Adjust
15CA C9 01005 RET
01006 ;
01007 ; Calculate the cylinder/sector of needed record
01008 ;
15CB CD0B14 01009 IOREC CALL GETNRN ;P/u record number
15CE CD261A 01010 CALL @DCTBYT-5 ;Get # of sectors/gran
15D1 E61F 01011 AND 1FH
15D3 3C 01012 INC A
15D4 CDE306 01013 CALL @DIV16 ;By # of sectors/gran
15D7 326016 01014 LD (CALS5+1),A ;Sv rmndr (sector offset)
15DA DDE5 01015 PUSH IX ;Xfer fcb to HL
15DC E3 01016 EX (SP),HL
15DD 010E00 01017 LD BC,14 ;Pt to 1st extent info
15E0 09 01018 ADD HL,BC
15E1 C1 01019 POP BC ;Pop gran ptr HL into BC
15E2 3E05 01020 LD A,5 ;Init to ck 4 extents
15E4 110000 01021 LD DE,0 ; & extended FXDE ptr
15E7 F5 01022 GREC1 PUSH AF
15E8 7E 01023 LD A,(HL) ;P/u starting cyl byte
15E9 23 01024 INC HL ; & bypass if FF
15EA 3C 01025 INC A
15EB 280B 01026 JR Z,GREC2
15ED E5 01027 PUSH HL ;Xfer the # of grans up
15EE 62 01028 LD H,D ; to but not including
15EF 6B 01029 LD L,E ; this extent into HL
15F0 AF 01030 XOR A ;Sub gran pointer from
15F1 ED42 01031 SBC HL,BC ; cumulative figure & go
15F3 380E 01032 JR C,GREC3 ; if not in previous ext
15F5 E1 01033 POP HL
15F6 2829 01034 JR Z,CALCSEC
15F8 23 01035 GREC2 INC HL
15F9 F1 01036 POP AF
15FA 3D 01037 DEC A
15FB 2819 01038 JR Z,GREC4 ;Jump when all quads c'kd
15FD 5E 01039 LD E,(HL) ;P/u cumulative # grans
15FE 23 01040 INC HL ; up to but not
15FF 56 01041 LD D,(HL) ; including this extent
1600 23 01042 INC HL
1601 18E4 01043 JR GREC1
1603 24 01044 GREC3 INC H ;Within 256 grans?
1604 7D 01045 LD A,L ;Xfer lo-order difference
1605 E1 01046 POP HL ;Rcvr # of contig grans
01047 ; ; in this extent
1606 20F0 01048 JR NZ,GREC2 ;Go if not within 256
1608 D5 01049 PUSH DE ;Save cumulative count
1609 5F 01050 LD E,A ;Xfer gran dif (neg)
160A 7E 01051 LD A,(HL) ;P/u # of grans
160B E61F 01052 AND 1FH ; in this extent
160D 83 01053 ADD A,E ;Add to negative diff
160E 7B 01054 LD A,E ;Put neg diff into A
160F D1 01055 POP DE
1610 30E6 01056 JR NC,GREC2 ;Go if not in this extent
1612 ED44 01057 NEG ;Is in this extent, make
1614 180B 01058 JR CALCSEC ; diff positive & use it
01059 ;
01060 ; All current quads checked - Need directory info
01061 ;
01062 GREC4
1616 CD6416 01063 CALL ALLOC ;Get # of grans
1619 C0 01064 RET NZ ; into the extent
161A 325016 01065 LD (CALS4+1),A ; or error RET
161D 302A 01066 JR NC,CALS3 ;Jp if record in 1st ext
161F 181F 01067 JR CALS1 ; else jp if in another
01068 ;
01069 ; Calc sector in gran
01070 ;
1621 325016 01071 CALCSEC LD (CALS4+1),A ;Stuff # grans into
1624 46 01072 LD B,(HL) ; this extent
1625 2B 01073 DEC HL ;P/u # contig grans &
1626 4E 01074 LD C,(HL) ; rel start & start cyl
1627 23 01075 INC HL
1628 F1 01076 POP AF ;Rcvr # of quad
1629 2F 01077 CPL
162A C604 01078 ADD A,4
162C 3019 01079 JR NC,CALS2 ;Jump if 1st ext or quad
162E 3C 01080 INC A ;If not 1st, set up to move
162F 07 01081 RLCA ; matching quad to the
1630 07 01082 RLCA ; first position by
1631 C5 01083 PUSH BC ; shuffling the others up
1632 D5 01084 PUSH DE
1633 4F 01085 LD C,A ;Get bytes to move
1634 0600 01086 LD B,0
1636 EB 01087 EX DE,HL ;DE = top of last quad
1637 21FCFF 01088 LD HL,-4
163A 19 01089 ADD HL,DE ;HL = top of next lower
163B EDB8 01090 LDDR ;Do the shuffle
163D EB 01091 EX DE,HL
163E D1 01092 POP DE
163F C1 01093 POP BC
1640 70 01094 CALS1 LD (HL),B ;Move info on matching quad
1641 2B 01095 DEC HL ; into position
1642 71 01096 LD (HL),C
1643 2B 01097 DEC HL
1644 72 01098 LD (HL),D
1645 2B 01099 DEC HL
1646 73 01100 LD (HL),E
1647 60 01101 CALS2 LD H,B ;Xfer start & contig gran
1648 69 01102 LD L,C ;Xfer start cylinder
1649 7C 01103 CALS3 LD A,H
164A 07 01104 RLCA ;P/u start gran on track
164B 07 01105 RLCA
164C 07 01106 RLCA
164D E607 01107 AND 7
164F C600 01108 CALS4 ADD A,0 ;P/u # grans into extent
1651 CD1919 01109 CALL RELCYL ;Calc 1st relative cyl
1654 85 01110 ADD A,L ;Add starting cylinder
1655 57 01111 LD D,A
1656 78 01112 LD A,B ;Rcvr # sectors/gran
1657 E61F 01113 AND 1FH
1659 3C 01114 INC A
165A D5 01115 PUSH DE ;Calculate sector offset
165B CD0A19 01116 CALL @MUL8 ; into desired cylinder
165E D1 01117 POP DE ; for desired granule
165F C600 01118 CALS5 ADD A,0 ;P/u # of excess sectors
1661 5F 01119 LD E,A ; over even gran & add
1662 AF 01120 XOR A ; to granule sector
1663 C9 01121 RET
01122 ;
01123 ; On entry, gran needed is in BC
01124 ;
1664 CDAE16 01125 ALLOC CALL CYL_GRN ;Find ext cntng gran
1667 C0 01126 RET NZ ;Ret on error
1668 E5 01127 PUSH HL ;Save starting cyl & gran
1669 60 01128 LD H,B ;Xfer granule needed to
166A 69 01129 LD L,C ; HL then calculate how
166B AF 01130 XOR A ; many grans into this
166C ED52 01131 SBC HL,DE ; extent is the desired
166E 7D 01132 LD A,L ; granule
166F 32A716 01133 LD (ALL6+1),A ;Stuff rel gran from
1672 E1 01134 POP HL ; start of extent
1673 D5 01135 PUSH DE ;Save granule count
1674 DDE5 01136 PUSH IX ; to extent
1676 E3 01137 EX (SP),HL ;FCB pointer to HL
1677 110E00 01138 LD DE,14 ;Pt to 1st alloc in FCB
167A 19 01139 ADD HL,DE
167B D1 01140 POP DE ;Pop starting cylinder
167C 0605 01141 LD B,5 ; to this extent
167E 7E 01142 ALL1 LD A,(HL) ;P/u a cyl
167F 23 01143 INC HL ;Does starting cyl of
1680 BB 01144 CP E ; needed gran alloc
1681 2006 01145 JR NZ,ALL2 ; appear in this extent?
1683 7E 01146 LD A,(HL) ;Now see if needed gran is
1684 AA 01147 XOR D ; in this extent field
1685 E6E0 01148 AND 0E0H ; by checking its starting gran
1687 2819 01149 JR Z,ALL4
1689 05 01150 ALL2 DEC B ;Dec the count down loop
168A 2805 01151 JR Z,ALL3 ;Done if no match
168C 23 01152 INC HL ;Go to next extent
168D 23 01153 INC HL ; info in FCB
168E 23 01154 INC HL
168F 18ED 01155 JR ALL1
1691 D5 01156 ALL3 PUSH DE ;Save needed extent info
1692 EB 01157 EX DE,HL ;Set up to shuffle extent
1693 21FCFF 01158 LD HL,-4 ; info
1696 19 01159 ADD HL,DE
1697 010C00 01160 LD BC,12
169A EDB8 01161 LDDR
169C EB 01162 EX DE,HL
169D C1 01163 POP BC
169E AF 01164 XOR A ;Set Z, no error
169F 37 01165 SCF ;Set CF, extent not found
16A0 1803 01166 JR ALL5
16A2 72 01167 ALL4 LD (HL),D
16A3 EB 01168 EX DE,HL
16A4 AF 01169 XOR A ;Set Z no error
16A5 D1 01170 ALL5 POP DE
16A6 3E00 01171 ALL6 LD A,0 ;# of grans into this ext
16A8 C9 01172 RET ;Where desired gran is
01173 ;
01174 ; Extent is unused - need to allocate more space
01175 ;
16A9 CDF216 01176 CG06 CALL CG07 ;Try to allocate more
16AC C1 01177 POP BC ;Get back desired gran
16AD C0 01178 RET NZ ;Return on error
01179 ;Look for gran again
01180 ;
01181 ; Find extent containing desired granule
01182 ;
16AE C5 01183 CYL_GRN PUSH BC ;Save desired gran #
16AF 110000 01184 LD DE,0 ;Init gran counter
16B2 DD4607 01185 LD B,(IX+7) ;P/u DEC of file
16B5 78 01186 CG01 LD A,B
16B6 32AC17 01187 LD (STUFDEC+1),A ;Stuff
16B9 DD4E06 01188 LD C,(IX+6) ;P/u drive for file
16BC CDBB18 01189 CALL @DIRRD ;Read its directory
16BF 011600 01190 LD BC,22 ;Point to 1st extent
16C2 09 01191 ADD HL,BC ; of its directory
16C3 EB 01192 EX DE,HL ;Gran count to HL
16C4 C1 01193 POP BC ;Restore desired gran
16C5 C0 01194 RET NZ ;Return on read error
16C6 1A 01195 CG02 LD A,(DE) ;Is this extent
16C7 FEFE 01196 CP 0FEH ; allocated?
16C9 301F 01197 JR NC,CG05 ;Jump if it is not
16CB 13 01198 INC DE ;Point to allocation
16CC 1A 01199 LD A,(DE) ;P/u relative gran & #
16CD E5 01200 PUSH HL ; of contiguous grans
16CE E61F 01201 AND 1FH ;Keep contiguous grans
16D0 3C 01202 INC A ; & bump for 0 offset
16D1 85 01203 ADD A,L ;Add to count in HL
16D2 6F 01204 LD L,A
16D3 3001 01205 JR NC,CG03
16D5 24 01206 INC H ;Bump hi order
16D6 E5 01207 CG03 PUSH HL ;Save gran count to
16D7 2B 01208 DEC HL ; end of extent
16D8 AF 01209 XOR A ;Test if EOF is in this
16D9 ED42 01210 SBC HL,BC ; allocation
16DB E1 01211 POP HL
16DC 3004 01212 JR NC,CG04 ;EOF not > this alloc
16DE 13 01213 INC DE ;Get rid of old
16DF F1 01214 POP AF ; current quantity
16E0 18E4 01215 JR CG02 ;Check next extent
01216 ;
01217 ; The EOF is within this allocation. Recover
01218 ; the allocation data and exit
01219 ;
16E2 E1 01220 CG04 POP HL ;P/u gran count to extent
16E3 EB 01221 EX DE,HL ;Gran count to DE
16E4 7E 01222 LD A,(HL) ;P/u granule data
16E5 2B 01223 DEC HL
16E6 6E 01224 LD L,(HL) ;P/u starting cylinder
16E7 67 01225 LD H,A
16E8 AF 01226 XOR A
16E9 C9 01227 RET
01228 ;
01229 ; This extent is 1) unused, or 2) FXDE pointer
01230 ; and the needed gran has not been found yet
01231 ;
16EA C5 01232 CG05 PUSH BC ;Gran count to DE &
16EB EB 01233 EX DE,HL ;DIR ptr to HL
16EC 20BB 01234 JR NZ,CG06 ;Jump if unused
16EE 23 01235 INC HL ;Point to DEC of FXDE
16EF 46 01236 LD B,(HL) ;P/u the DEC
16F0 18C3 01237 JR CG01 ; & loop
01238 ;
01239 ; See if the drive has enough free space left
01240 ;
16F2 C5 01241 CG07 PUSH BC ;Save needed gran
16F3 DD4E06 01242 LD C,(IX+6) ;P/u file's drive
16F6 CD7418 01243 CALL @GATRD ;Get GAT
16F9 C1 01244 POP BC ;Rcvr needed gran
16FA C0 01245 RET NZ ;Return if GAT error
16FB E5 01246 PUSH HL
16FC 60 01247 LD H,B ;Xfer the requested
16FD 69 01248 LD L,C ; gran to HL &
16FE AF 01249 XOR A ; subtract current gran
16FF ED52 01250 SBC HL,DE ;Count to calculate how
1701 44 01251 LD B,H ; many excess grans
1702 4D 01252 LD C,L ; are needed
1703 03 01253 INC BC
1704 D1 01254 POP DE ;Rcvr dir byte ptr
1705 13 01255 INC DE ;Pt to next DIR byte
1706 2623 01256 LD H,DIRBUF$<-8 ;Start looking at TRK #1
1708 3A6A00 01257 LD A,(AFLAG$) ;P/u Search start CYL
170B 6F 01258 LD L,A ; and put it in L
170C C5 01259 PUSH BC ;Save excess grans needed
170D 7B 01260 LD A,E ;Is this extent the 1st?
170E E61E 01261 AND 1EH ;Jump if so, else we can
1710 FE16 01262 CP 16H ; use it for allocation
1712 2842 01263 JR Z,CG14
1714 1D 01264 DEC E ;Backup to previous
1715 1D 01265 DEC E ; extent
1716 1A 01266 CG12 LD A,(DE) ;P/u # of contig grans to
1717 E61F 01267 AND 1FH ; see if the last gran
1719 3C 01268 INC A ; used can be extended
171A 4F 01269 LD C,A ;Is current # the max
171B FE20 01270 CP 20H ; an extent can hold?
171D 2820 01271 JR Z,CG13 ;Jump if a full extent
171F 1A 01272 LD A,(DE) ; (32 grans max) - else
1720 E6E0 01273 AND 0E0H ; p/u the relative
1722 07 01274 RLCA ; granule offset
1723 07 01275 RLCA
1724 07 01276 RLCA
1725 81 01277 ADD A,C ;Add the # of contiguous
1726 D5 01278 PUSH DE ; granules
1727 CD1919 01279 CALL RELCYL ;Calc relative cyl needed
172A 47 01280 LD B,A ;Save offset
172B 4B 01281 LD C,E
172C D1 01282 POP DE
172D 1B 01283 DEC DE ;Backup to starting cyl
172E 1A 01284 LD A,(DE)
172F 13 01285 INC DE ; & repoint to alloc byte
1730 80 01286 ADD A,B ;Add cyls used to
1731 6F 01287 LD L,A ; starting cyl
1732 2623 01288 LD H,DIRBUF$<-8 ;Is it less than max?
1734 FECB 01289 CP 0CBH
1736 3007 01290 JR NC,CG13 ;Jump if too big
1738 79 01291 LD A,C
1739 46 01292 LD B,(HL) ;P/u the cyl's GAT
173A CD5B18 01293 CALL TSTBIT ;Test if gran is free
173D 284B 01294 JR Z,CG21 ;Bypass if free gran
01295 ;
01296 ; The next gran cannot be used - get another extent
01297 ;
173F 1C 01298 CG13 INC E ;Else point to next
1740 1C 01299 INC E ; extent field
1741 7B 01300 LD A,E
1742 E61E 01301 AND 1EH ;Jump if not on the FXDE
1744 FE1E 01302 CP 1EH ; field, else we have to
1746 200E 01303 JR NZ,CG14 ; obtain an FXDE record
01304 ;
01305 ; Last extent used up, get new dir rec for FXDE
01306 ;
1748 CDA417 01307 CALL CG23 ;Write curent GAT & HIT
174B C1 01308 POP BC
174C C0 01309 RET NZ ;Ret if GAT/HIT error
174D C5 01310 PUSH BC
174E CDAF17 01311 CALL NEWHIT ;Get new HIT for FXDE
1751 C1 01312 POP BC
1752 C0 01313 RET NZ ;Loop to process
1753 C3AE16 01314 JP CYL_GRN ; new extent
01315 ;
01316 ; Extent is vacant - use it & get new allocation
01317 ;
1756 CDFE18 01318 CG14 CALL MAXCYL ;Get highest # cyl
1759 326017 01319 LD (CG17+1),A ;Stuff highest cyl
175C 0602 01320 LD B,2
175E 7D 01321 CG16 LD A,L ;Test last cyl used
175F FE00 01322 CG17 CP 0 ;P/u max cyl
1761 3007 01323 JR NC,CG18
1763 7E 01324 LD A,(HL) ;P/u a GAT byte
1764 3C 01325 INC A
1765 2010 01326 JR NZ,CG19 ;Go if space in this cyl
1767 2C 01327 INC L ; else bump to next one
1768 18F4 01328 JR CG16 ; & loop
176A 2E00 01329 CG18 LD L,0 ;Now start from begin
176C 10F0 01330 DJNZ CG16 ; of disk & recheck
176E C1 01331 POP BC
176F CDA417 01332 CALL CG23 ;Write out GAT & HIT
1772 C0 01333 RET NZ
1773 3E1B 01334 LD A,1BH ;"disk space full"
1775 B7 01335 OR A
1776 C9 01336 RET
01337 ;
01338 ; Found available space in cylinder
01339 ;
1777 3EFF 01340 CG19 LD A,0FFH ;Set DIR extent to FF
1779 12 01341 LD (DE),A
177A 0E00 01342 LD C,0
177C 46 01343 LD B,(HL) ;P/u current GAT alloc
177D 79 01344 CG20 LD A,C
177E CD5B18 01345 CALL TSTBIT ;Find a free gran
1781 2807 01346 JR Z,CG21 ; & jump when found
1783 1A 01347 LD A,(DE) ; else advance starting
1784 C620 01348 ADD A,20H ; rel gran value
1786 12 01349 LD (DE),A
1787 0C 01350 INC C ;Bump pointer to test
1788 18F3 01351 JR CG20 ; next gran
01352 ;
01353 ; Next gran in line is free - allocate it
01354 ;
178A 79 01355 CG21 LD A,C
178B CD6818 01356 CALL SETBIT ;Show it allocated
178E B6 01357 OR (HL)
178F 77 01358 LD (HL),A
1790 1D 01359 DEC E ;Backup to starting cyl
1791 1A 01360 LD A,(DE) ;Bump by one to see if
1792 3C 01361 INC A ; this alloc is the 1st
1793 2002 01362 JR NZ,CG22 ; one for the extent &
1795 7D 01363 LD A,L ; we have to set the
01364 ; starting cylinder
1796 12 01365 LD (DE),A ;Stuff starting cyl
1797 1C 01366 CG22 INC E
1798 1A 01367 LD A,(DE) ;Add 1 to # of contiguous
1799 3C 01368 INC A ; granules
179A 12 01369 LD (DE),A
179B C1 01370 POP BC ;Decrement needed gran
179C 0B 01371 DEC BC ; count since we just
179D C5 01372 PUSH BC ; allocated one
179E 78 01373 LD A,B ;Loop if we need more
179F B1 01374 OR C ; space allocated
17A0 C21617 01375 JP NZ,CG12
17A3 C1 01376 POP BC
17A4 DD4E06 01377 CG23 LD C,(IX+6) ;Else p/u the drive #
17A7 CD7518 01378 CALL @GATWR ; & write out the GAT
17AA C0 01379 RET NZ
17AB 0600 01380 STUFDEC LD B,0 ;P/u DEC of FPDE
17AD 1854 01381 JR @DIRWR
01382 ;
01383 ; Get new HIT for FXDE
01384 ;
17AF DD4E06 01385 NEWHIT LD C,(IX+6) ;P/u drive #
17B2 CD9718 01386 CALL @HITRD ;Read the HIT
17B5 C0 01387 RET NZ
17B6 DD7E07 01388 LD A,(IX+7) ;P/u FPDE DEC so 1st ck
17B9 E61F 01389 AND 1FH ; will be for next
17BB CD1F18 01390 CALL @SCNHIT ; in line
17BE 3E1E 01391 LD A,1EH ;Init "full directory...
17C0 C0 01392 RET NZ ;Ret if no space
17C1 45 01393 LD B,L ;Set DEC for
17C2 7D 01394 LD A,L ; directory read
17C3 320218 01395 LD (NHIT3+1),A ;Stuff new DEC from HIT
17C6 54 01396 LD D,H
17C7 DD5E07 01397 LD E,(IX+7) ;P/u current DEC
17CA 1A 01398 LD A,(DE) ;Copy filespec hash code
17CB 77 01399 LD (HL),A ; to new DEC
17CC CD9818 01400 CALL @HITWR
17CF CCBB18 01401 CALL Z,@DIRRD
17D2 C0 01402 RET NZ
17D3 3690 01403 LD (HL),90H ;Show dir rec in use as
17D5 2C 01404 INC L ; FXDE record
17D6 C5 01405 PUSH BC ;P/u DEC of FPDE &
17D7 3AAC17 01406 LD A,(STUFDEC+1) ; stuff it into FXDE's
17DA 77 01407 LD (HL),A ; DIR+1 to link back
17DB 2C 01408 INC L
17DC 0614 01409 LD B,20 ;Zero out 20 bytes
17DE 3600 01410 NHIT1 LD (HL),0 ; in the FXDE
17E0 2C 01411 INC L
17E1 10FB 01412 DJNZ NHIT1
17E3 E5 01413 PUSH HL ;Save ptr to 1st extent
17E4 060A 01414 LD B,10 ;Init to X'FF' 10 bytes
17E6 36FF 01415 NHIT2 LD (HL),0FFH ; or 5 extents
17E8 2C 01416 INC L
17E9 10FB 01417 DJNZ NHIT2
17EB D1 01418 POP DE ;Rcvr ptr to 1st extent
17EC 13 01419 INC DE ;Pt to allocation byte
17ED C1 01420 POP BC
17EE CD0318 01421 CALL @DIRWR ;Write FXDE back to disk
17F1 C0 01422 RET NZ ;Return if error
17F2 3AAC17 01423 LD A,(STUFDEC+1) ; else p/u DEC of FPDE
17F5 47 01424 LD B,A
17F6 CDBB18 01425 CALL @DIRRD ;Read its directory
17F9 C0 01426 RET NZ ; & return if error
17FA 7D 01427 LD A,L
17FB C61E 01428 ADD A,1EH ;Point to FXDE posn
17FD 6F 01429 LD L,A ; in FPDE
17FE 36FE 01430 LD (HL),0FEH ;Show link to FXDE
1800 2C 01431 INC L
1801 3600 01432 NHIT3 LD (HL),0 ;Show what's the FXDE DEC
01433 ; & write the DIR back
01434 ;
01435 ; Routine to write a directory sector
01436 ; B => DEC of FPDE, C => logical drive number
01437 ; HL <= points to directory record in SBUFF$
01438 ;
1803 CD0718 01439 @DIRWR CALL DIRWR ;Permit two attempts
1806 C8 01440 RET Z
1807 D5 01441 DIRWR PUSH DE ;Save the reg
1808 CDCA18 01442 CALL CALCDIR ;Calc dir cyl
180B 2E00 01443 LD L,0 ;Set buffer to start
180D CDEC19 01444 CALL @WRSSC ;Write the sector
1810 CCDC19 01445 CALL Z,@VRSEC ;Verify on no error
1813 D606 01446 SUB 6
1815 D1 01447 POP DE
1816 C8 01448 RET Z ;Back on system sector
1817 FE09 01449 CP 0FH-6 ;WP error?
1819 3E12 01450 LD A,18 ;Set dir write error
181B C0 01451 RET NZ ; if not WP
181C D603 01452 SUB 3
181E C9 01453 RET
01454 ;
01455 ; Find a spare HIT entry
01456 ;
181F F5 01457 @SCNHIT PUSH AF
1820 3E07 01458 LD A,7 ;Get highest # sector
1822 CD2B1A 01459 CALL @DCTBYT ; on a cylinder
1825 D5 01460 PUSH DE ; into register E
1826 57 01461 LD D,A
1827 E61F 01462 AND 1FH
1829 5F 01463 LD E,A
182A 1C 01464 INC E ;& get number of heads
182B AA 01465 XOR D ; into register A
182C 07 01466 RLCA
182D 07 01467 RLCA
182E 07 01468 RLCA
182F 3C 01469 INC A
1830 CD0A19 01470 CALL @MUL8 ;To calc sectors/cylinder
1833 CD3B19 01471 CALL CKDBLBIT ;Double if necessary
1836 D1 01472 POP DE ;Total sectors per cyl
1837 D602 01473 SUB 2 ;Reduce for GAT & HIT
1839 324D18 01474 LD (NHIT7+1),A ;# of directory sectors
183C F1 01475 POP AF ;Get DEC init entry
183D 6F 01476 LD L,A
183E CD4918 01477 CALL NHIT6 ;Ck if HIT slot is spare
1841 C8 01478 RET Z ;Return if it is spare
1842 2E01 01479 LD L,1 ;Start at beginning
1844 2C 01480 NHIT5 INC L
1845 2002 01481 JR NZ,NHIT6
1847 B4 01482 OR H
1848 C9 01483 RET
1849 7D 01484 NHIT6 LD A,L
184A E61F 01485 AND 1FH
184C FE00 01486 NHIT7 CP 0
184E 7D 01487 LD A,L
184F 3805 01488 JR C,NHIT8
1851 F61F 01489 OR 1FH
1853 6F 01490 LD L,A
1854 18EE 01491 JR NHIT5
1856 7E 01492 NHIT8 LD A,(HL)
1857 B7 01493 OR A
1858 C8 01494 RET Z
1859 18E9 01495 JR NHIT5
01496 ;
01497 ; Test if gran is free in GAT
01498 ;
185B E607 01499 TSTBIT AND 7 ;Get 0 to 7
185D 07 01500 RLCA ;Shift to match BIT n,
185E 07 01501 RLCA ; opcode
185F 07 01502 RLCA
1860 F640 01503 OR 40H
1862 326618 01504 LD (TBIT1+1),A ;Modify BIT instruction
1865 CB40 01505 TBIT1 BIT 0,B
1867 C9 01506 RET
01507 ;
01508 ; Set gran to allocated in GAT
01509 ;
1868 07 01510 SETBIT RLCA ;Shift to create opcode
1869 07 01511 RLCA ; to match current bit
186A 07 01512 RLCA
186B F6C7 01513 OR 0C7H
186D 327218 01514 LD (SBIT1+1),A ;Create SET n, opcode
1870 AF 01515 XOR A
1871 CBC7 01516 SBIT1 SET 0,A
1873 C9 01517 RET
01518 ;
01519 ; Routine reads/writes the Granule Allocation Table
01520 ;
1874 F6 01521 @GATRD DB 0F6H ;Set NZ for test
1875 AF 01522 @GATWR XOR A ;Set Z for test
1876 D5 01523 PUSH DE
1877 E5 01524 PUSH HL
1878 F5 01525 PUSH AF ;Save flag for test
1879 CDF718 01526 CALL @DIRCYL
187C 210023 01527 LD HL,DIRBUF$
187F 5D 01528 LD E,L ;Set E to 0
1880 F1 01529 POP AF ;Rcvr flag for R/W
1881 2807 01530 JR Z,GATRW1 ;Go if @GATWR
1883 CDD818 01531 CALL @RDSSC
1886 3E14 01532 LD A,14H ;Init "GAT read error"
1888 180A 01533 JR GATRW2
188A CDEC19 01534 GATRW1 CALL @WRSSC ;Protected sector write
188D CCDC19 01535 CALL Z,@VRSEC ;Verify if OK
1890 FE06 01536 CP 6 ;Protected sector?
1892 3E15 01537 LD A,15H ;Init "GAT write error"
1894 E1 01538 GATRW2 POP HL
1895 D1 01539 POP DE
1896 C9 01540 RET
01541 ;
01542 ; Read or write the hash index table
01543 ;
1897 F6 01544 @HITRD DB 0F6H ;Set NZ for test
1898 AF 01545 @HITWR XOR A ;Set Z for test
1899 C5 01546 PUSH BC
189A D5 01547 PUSH DE
189B F5 01548 PUSH AF ;Save flag for test
189C CDF718 01549 CALL @DIRCYL ;D => directory cylinder
189F 1E01 01550 LD E,1 ;E => HIT sector
18A1 21001D 01551 LD HL,SBUFF$ ;HL => HIT buffer area
18A4 F1 01552 POP AF ;Rcvr flag for RD/WR
18A5 2807 01553 JR Z,HITRW1 ;Go if @HITWR
18A7 CDD818 01554 CALL @RDSSC ;Read cyl D, sector E
18AA 3E16 01555 LD A,22 ;Init "HIT read error"
18AC 180A 01556 JR HITRW2
18AE CDEC19 01557 HITRW1 CALL @WRSSC ;Protected sector write
18B1 CCDC19 01558 CALL Z,@VRSEC ;Verify the write
18B4 FE06 01559 CP 6 ;Protected sector?
18B6 3E17 01560 LD A,23 ;"HIT write error"
18B8 D1 01561 HITRW2 POP DE ;Message for other than
18B9 C1 01562 POP BC ; attempt protected sector
18BA C9 01563 RET
01564 ;
01565 ; Routine to read a directory sector
01566 ; B => DEC of FPDE, C => logical drive number
01567 ; HL <= points to directory record in SBUFF$
01568 ;
18BB D5 01569 @DIRRD PUSH DE
18BC CDCA18 01570 CALL CALCDIR ;Set HL to SBUFF$
18BF E5 01571 PUSH HL
18C0 2E00 01572 LD L,0 ;Start of bfr
18C2 CDD818 01573 CALL @RDSSC ;Read it
18C5 E1 01574 POP HL
18C6 3E11 01575 LD A,17 ;Init to dir read err
18C8 D1 01576 POP DE
18C9 C9 01577 RET
01578 ;
01579 ; Routine to get directory access data
01580 ; B => DEC
01581 ; DE <= cylinder and sector needed
01582 ; HL <= pointer to directory record in SBUFF$
01583 ;
18CA CDF718 01584 CALCDIR CALL @DIRCYL ;Get directory cyl in D
18CD 78 01585 LD A,B ;Calculate record start
18CE E6E0 01586 AND 0E0H ; from the DEC
18D0 6F 01587 LD L,A
18D1 261D 01588 LD H,SBUFF$<-8 ;Point to buffer start
18D3 A8 01589 XOR B ;Calculate directory
18D4 C602 01590 ADD A,2 ; sector needed
18D6 5F 01591 LD E,A
18D7 C9 01592 RET
01593 ;
01594 ; Read system sector, D=Track, E=Sector, HL=Buffer
01595 ;
18D8 CDF118 01596 @RDSSC CALL READIR
18DB C8 01597 RET Z
18DC D5 01598 PUSH DE
18DD 110100 01599 LD DE,1 ;Pt to tk 0, sec 1
18E0 CDF419 01600 CALL @RDSEC ;Read to find dir cyl
18E3 D1 01601 POP DE
18E4 C0 01602 RET NZ
18E5 E5 01603 PUSH HL
18E6 23 01604 INC HL ;Pt to dir tk #
18E7 23 01605 INC HL
18E8 56 01606 LD D,(HL) ;P/u dir tk fm boot
18E9 2609 01607 LD H,9 ;Update memory table
18EB CD341A 01608 CALL DCTFLD@
18EE 6F 01609 LD L,A
18EF 72 01610 LD (HL),D
18F0 E1 01611 POP HL
18F1 CDF419 01612 READIR CALL @RDSEC ;Retry dir read
18F4 D606 01613 SUB 6 ;Test protected
18F6 C9 01614 RET
01615 ;
18F7 3E09 01616 @DIRCYL LD A,9
18F9 CD2B1A 01617 CALL @DCTBYT ;Get the dir cylinder
18FC 57 01618 LD D,A
18FD C9 01619 RET
01620 ;
18FE 3E06 01621 MAXCYL LD A,6
1900 C5 01622 PUSH BC
1901 DD4E06 01623 LD C,(IX+6)
1904 CD2B1A 01624 CALL @DCTBYT ;Get highest # cyl
1907 3C 01625 INC A ;Adjust for zero offset
1908 C1 01626 POP BC
1909 C9 01627 RET
01628 ;
01629 ; Multiply register E by register A
01630 ;
190A C5 01631 @MUL8 PUSH BC ;Mult A x E
190B 57 01632 LD D,A
190C AF 01633 XOR A
190D 0608 01634 LD B,8
190F 87 01635 MEA1 ADD A,A
1910 CB23 01636 SLA E
1912 3001 01637 JR NC,MEA2
1914 82 01638 ADD A,D
1915 10F8 01639 MEA2 DJNZ MEA1
1917 C1 01640 POP BC
1918 C9 01641 RET
01642 ;
01643 ; Calculate relative cylinder for granule needed
01644 ;
1919 5F 01645 RELCYL LD E,A
191A CD261A 01646 CALL @DCTBYT-5 ;Get # of grans/track
191D 47 01647 LD B,A ;Hang on to this
191E 07 01648 RLCA
191F 07 01649 RLCA
1920 07 01650 RLCA
1921 E607 01651 AND 7
1923 3C 01652 INC A ;Adj for 0 offset
1924 CD3B19 01653 CALL CKDBLBIT
01654 ;
01655 ; Divide register E by register A
01656 ;
1927 C5 01657 @DIV8 PUSH BC
1928 4F 01658 LD C,A
1929 0608 01659 LD B,8
192B AF 01660 XOR A
192C CB23 01661 DEA1 SLA E
192E 17 01662 RLA
192F B9 01663 CP C
1930 3802 01664 JR C,DEA2
1932 91 01665 SUB C
1933 1C 01666 INC E
1934 10F6 01667 DEA2 DJNZ DEA1
1936 4F 01668 LD C,A
1937 7B 01669 LD A,E
1938 59 01670 LD E,C
1939 C1 01671 POP BC
193A C9 01672 RET
01673 ;
01674 ; Routine to double the A register if DBL bit is set
01675 ;
01676 CKDBLBIT
193B 57 01677 LD D,A ;Adjust for 2-sided &
193C 3E04 01678 LD A,4 ; calculate # of cyls
193E CD2B1A 01679 CALL @DCTBYT
1941 CB6F 01680 BIT 5,A ;Test if 2-sided
1943 7A 01681 LD A,D
1944 2801 01682 JR Z,$+3 ;Double the grans if 2
1946 87 01683 ADD A,A ; & fall thru to DIV8
1947 C9 01684 RET
1948 01686 CORE$ DEFL $
F80D 01687 ORG CRTBGN$+13
01688 IF @BLD631
F80D 4C 01689 DB 'LS-DOS 06.03.01' ;<631>
53 2D 44 4F 53 20 30 36
2E 30 33 2E 30 31
01690 ELSE
01691 DB 'LS-DOS 06.03.00'
01692 ENDIF
01693 IF @USA
F81C 20 01694 DB ' '
01695 ENDIF
01696 IF @GERMAN
01697 DB 'D'
01698 ENDIF
01699 IF @FRENCH
01700 DB 'F'
01701 ENDIF
01702 IF @BLD631
F81D 2D 01703 DB '- Copyright 1986/90 ' ;<631>
20 43 6F 70 79 72 69 67
68 74 20 31 39 38 36 2F
39 30 20
F831 4D 01704 DB 'MISOSYS, Inc. ' ;<631>
49 53 4F 53 59 53 2C 20
49 6E 63 2E 20 20 20 20
01705 ELSE
01706 DB '- Copyright 1986 '
01707 DB 'Logical Systems Inc.'
01708 ENDIF
F85E 01709 ORG CRTBGN$+80+14
F85E 20 01710 DB ' All Rights Reserved. '
20 20 20 20 20 20 20 20
20 20 20 20 20 20 41 6C
6C 20 52 69 67 68 74 73
20 52 65 73 65 72 76 65
64 2E 20
F882 20 01711 DB ' '
20 20 20 20 20 20 20 20
20 20 20 20 20 20
01712 ; DB 'Licensed to Tandy Corporation.'
1948 01713 ORG CORE$
01714 ;
01715 ; get the system loader
01716 ;
1948 01719 *GET LOADER:3
01720 ;LOADER/ASM - LS-DOS 6.2
1948 01721 CORE$ DEFL $
0100 01722 ORG SVCTAB$
01723 ;
01724 ; Supervisor Call table - Page 5
01725 ;
0100 F21B 01726 DW @IPL,@KEY,@DSP,@GET ;0-3
2806 4206 3806
0108 4506 01727 DW @PUT,@CTL,@PRT,@WHERE ;4-7
2306 3D06 7919
0110 3506 01728 DW @KBD,@KEYIN,@DSPLY,@LOGER ;8-11
8505 2D05 0305
0118 0005 01729 DW @LOGOT,@MSG,@PRINT,@VDCTL ;12-15
3005 2805 990B
0120 8203 01730 DW @PAUSE,@PARAM,@DATE,@TIME ;16-19
8719 2014 8D07
0128 8906 01731 DW @CHNIO,@ABORT,@EXIT,SVCERR ;20-23
081B 0B1B F41A
0130 7E19 01732 DW @CMNDI,@CMNDR,@ERROR,@DEBUG ;24-27
7B19 0F1B A019
0138 F51C 01733 DW @CKTSK,@ADTSK,@RMTSK,@RPTSK ;28-31
DA1C D71C EB1C
0140 D01C 01734 DW @KLTSK,@CKDRV,@DODIR,@RAMDIR ;32-35
9319 AF19 AC19
0148 F41A 01735 DW SVCERR,SVCERR,SVCERR,SVCERR ;36-39
F41A F41A F41A
0150 B519 01736 DW @DCSTAT,@SLCT,@DCINIT,@DCRES ;40-43
BC19 C019 C419
0158 C819 01737 DW @RSTOR,@STEPI,@SEEK,@RSLCT ;44-47
CC19 D019 D419
0160 D819 01738 DW @RDHDR,@RDSEC,@VRSEC,@RDTRK ;48-51
F419 DC19 E019
0168 E419 01739 DW @HDFMT,@WRSEC,@WRSSC,@WRTRK ;52-55
E819 EC19 F019
0170 9619 01740 DW @RENAME,@REMOVE,@INIT,@OPEN ;56-59
A619 8D19 8A19
0178 9919 01741 DW @CLOSE,@BKSP,@CKEOF,@LOC ;60-63
AD14 8F15 DA14
0180 0515 01742 DW @LOF,@PEOF,@POSN,@READ ;64-67
C914 5B14 1315
0188 C214 01743 DW @REW,@RREAD,@RWRIT,@SEEKSC ;68-71
9A14 AD13 A013
0190 5714 01744 DW @SKIP,@VER,@WEOF,@WRITE ;72-75
6015 3014 3115
0198 381B 01745 DW @LOAD,@RUN,@FSPEC,@FEXT ;76-79
1D1B 8119 8419
01A0 9C19 01746 DW @FNAME,@GTDCT,@GTDCB,@GTMOD ;80-83
1E1A 9019 B219
01A8 F41A 01747 DW SVCERR,@RDSSC,@GATRD,@DIRRD ;84-87
D818 7418 BB18
01B0 0318 01748 DW @DIRWR,@GATWR,@MUL8,@MUL16 ;88-91
7518 0A19 C906
01B8 F41A 01749 DW SVCERR,@DIV8,@DIV16,@HEXD ;92-95
2719 E306 F806
01C0 E103 01750 DW @DECHEX,@HEXDEC,@HEX8,@HEX16 ;96-99
F606 C207 BD07
01C8 4819 01751 DW @HIGH$,@FLAGS,@BANK,@BREAK ;100-103
6A19 7708 6F19
01D0 9203 01752 DW @SOUND,@CLS,@CKBRKC,@VDPRT ;104-107
4505 5305 3509
01D8 F41A 01753 DW SVCERR,SVCERR,SVCERR,SVCERR ;108-111
F41A F41A F41A
01E0 F41A 01754 DW SVCERR,SVCERR,SVCERR,SVCERR ;112-115
F41A F41A F41A
01E8 F41A 01755 DW SVCERR,SVCERR,SVCERR,SVCERR ;116-119
F41A F41A F41A
01F0 F41A 01756 DW SVCERR,SVCERR,SVCERR,SVCERR ;120-123
F41A F41A F41A
01F8 F41A 01757 DW SVCERR,SVCERR,SVCERR,SVCERR ;124-127
F41A F41A F41A
1948 01758 ORG CORE$
01759 ;
01760 ; Routine to set or retrieve HIGH$/LOW$
01761 ;
1948 7C 01762 @HIGH$ LD A,H ;Test if put or get
1949 B5 01763 OR L
194A 2812 01764 JR Z,GETHILO ;Go if get
194C 3A6C00 01765 LD A,(CFLAG$) ;Is HIGH$ changeable?
194F 0F 01766 RRCA
1950 3E2B 01767 LD A,43 ;Init SVC parm error
1952 D8 01768 RET C ;Back with NZ
1953 04 01769 INC B ;Test for HIGH$/LOW$
1954 05 01770 DEC B
1955 200E 01771 JR NZ,PUTLO ;Go if LOW$
1957 220E04 01772 LD (HIGH$),HL ;Set new HIGH$
195A 2A0E04 01773 GETHI LD HL,(HIGH$) ;P/u the value &
195D C9 01774 RET ; ret with Z-flag
195E 04 01775 GETHILO INC B ;Test for HIGH$/LOW$
195F 05 01776 DEC B
1960 28F8 01777 JR Z,GETHI
1962 2A1E00 01778 LD HL,(LOW$) ;P/u LOW$
1965 221E00 01779 PUTLO LD (LOW$),HL ;Get LOW$
1968 AF 01780 XOR A ;Set Z-flag
1969 C9 01781 RET
01782 ;
196A FD216A00 01783 @FLAGS LD IY,FLGTAB$
196E C9 01784 RET
01785 ;
196F E5 01786 @BREAK PUSH HL ;Save user vector
1970 2A881C 01787 LD HL,(BRKVEC$) ;P/u current vector
1973 E3 01788 EX (SP),HL ;Save current & get user
1974 22881C 01789 LD (BRKVEC$),HL ;Stuff new vector
1977 E1 01790 POP HL ;Recover old vector
1978 C9 01791 RET
01792 ;
1979 E1 01793 @WHERE POP HL
197A E9 01794 JP (HL)
01795 ;
01796 ; Code for these SVCs is in system overlays
01797 ;
197B 3EA3 01798 @CMNDR LD A,0A3H ;Interpret command & RET
197D EF 01799 RST 40
197E 3EB3 01800 @CMNDI LD A,0B3H ;Interpret a command
1980 EF 01801 RST 40
1981 3EC3 01802 @FSPEC LD A,0C3H ;Parse a filespec
1983 EF 01803 RST 40
1984 3ED3 01804 @FEXT LD A,0D3H ;Optional default EXT
1986 EF 01805 RST 40
1987 3EE3 01806 @PARAM LD A,0E3H ;Parameter scanner
1989 EF 01807 RST 40
198A 3E94 01808 @OPEN LD A,94H ;Open a file
198C EF 01809 RST 40
198D 3EA4 01810 @INIT LD A,0A4H ;Initialize a file
198F EF 01811 RST 40
1990 3EB4 01812 @GTDCB LD A,0B4H ;Get a DCB vector
1992 EF 01813 RST 40
1993 3EC4 01814 @CKDRV LD A,0C4H ;Drive available?
1995 EF 01815 RST 40
1996 3EF4 01816 @RENAME LD A,0F4H ;Rename a file
1998 EF 01817 RST 40
1999 3E95 01818 @CLOSE LD A,95H ;Close a file
199B EF 01819 RST 40
199C 3EA5 01820 @FNAME LD A,0A5H ;Recover filespec
199E EF 01821 RST 40
199F C9 01822 @DBGHK RET ;Init DEBUG off (NOP=on)
19A0 F5 01823 @DEBUG PUSH AF
19A1 3E97 01824 LD A,97H ;Enter system Debugger
19A3 EF 01825 RST 40
19A4 0315 01826 EXTDBG$ DW ORARET@ ;Hook for extended DEBUG
19A6 3E9C 01827 @REMOVE LD A,9CH ;Remove a file/device
19A8 EF 01828 RST 40
19A9 3ECD 01829 @DOKEY LD A,0CDH ;DO execution
19AB EF 01830 RST 40
19AC 3E9E 01831 @RAMDIR LD A,09EH ;Directory data
19AE EF 01832 RST 40
19AF 3EAE 01833 @DODIR LD A,0AEH ;Directory data
19B1 EF 01834 RST 40
19B2 3EBE 01835 @GTMOD LD A,0BEH ;Get module address
19B4 EF 01836 RST 40
01837 ;
01838 ; These SVCs handle the disk primitive requests
01839 ;
19B5 AF 01840 @DCSTAT XOR A ;FDC status
19B6 183E 01841 JR IOFUNC
19B8 3A2300 01842 TAPDRV LD A,(LDRV$) ;P/u drive #
19BB 4F 01843 LD C,A
19BC 3E01 01844 @SLCT LD A,1 ;Select drive
19BE 1836 01845 JR IOFUNC
19C0 3E02 01846 @DCINIT LD A,2 ;FDC init
19C2 1832 01847 JR IOFUNC
19C4 3E03 01848 @DCRES LD A,3 ;FDC reset
19C6 182E 01849 JR IOFUNC
19C8 3E04 01850 @RSTOR LD A,4 ;Restore to cyl 0
19CA 182A 01851 JR IOFUNC
19CC 3E05 01852 @STEPI LD A,5 ;Step in 1 cyl
19CE 1826 01853 JR IOFUNC
19D0 3E06 01854 @SEEK LD A,6 ;Seek a track/sector
19D2 1822 01855 JR IOFUNC
19D4 3E07 01856 @RSLCT LD A,7 ;Re-select drive
19D6 181E 01857 JR IOFUNC
19D8 3E08 01858 @RDHDR LD A,8
19DA 181A 01859 JR IOFUNC
19DC 3E0A 01860 @VRSEC LD A,10 ;Verify a sector
19DE 1816 01861 JR IOFUNC
19E0 3E0B 01862 @RDTRK LD A,11
19E2 1812 01863 JR IOFUNC
19E4 3E0C 01864 @HDFMT LD A,12
19E6 180E 01865 JR IOFUNC
19E8 3E0D 01866 @WRSEC LD A,13 ;Write standard sector
19EA 180A 01867 JR IOFUNC
19EC 3E0E 01868 @WRSSC LD A,14 ;Write a system sector
19EE 1806 01869 JR IOFUNC
19F0 3E0F 01870 @WRTRK LD A,15 ;Write a track
19F2 1802 01871 JR IOFUNC
19F4 3E09 01872 @RDSEC LD A,9 ;Read a sector
01873 ;
19F6 C5 01874 IOFUNC PUSH BC ;Save reg pair
19F7 47 01875 LD B,A ;Xfer the function code
01876 ;
01877 ; Bring up bank 0
01878 ;
19F8 C5 01879 PUSH BC
19F9 AF 01880 XOR A
19FA 47 01881 LD B,A ;Set bank function 0,
19FB 4F 01882 LD C,A ; bank number 0
19FC CD7708 01883 CALL @BANK ;Bring up bank
19FF F1 01884 POP AF ;Perform EX (SP),BC
1A00 C5 01885 PUSH BC
1A01 F5 01886 PUSH AF
1A02 C1 01887 POP BC
01888 ;
01889 ; Continue disk I/O setup
01890 ;
1A03 79 01891 LD A,C ;Xfer the drive code
1A04 322300 01892 LD (LDRV$),A
1A07 FDE5 01893 PUSH IY
1A09 CD1E1A 01894 CALL @GTDCT ;Get DCT address in IY
1A0C 3E20 01895 LD A,20H ;Set illegal drive #
1A0E B7 01896 OR A ; if drive disabled
1A0F CD1C1A 01897 CALL GODOIO
1A12 FDE1 01898 POP IY
01899 ;
01900 ; Bring back the old bank
01901 ;
1A14 C1 01902 POP BC
1A15 F5 01903 PUSH AF ;Save disk I/O retcod
1A16 3E66 01904 LD A,102 ;Set for @BANK
1A18 EF 01905 RST 40 ;No need to ck for error
01906 ; from @BANK
1A19 F1 01907 POP AF
1A1A C1 01908 POP BC
1A1B C9 01909 RET
01910 ;
1A1C FDE9 01911 GODOIO JP (IY)
01912 ;
1A1E E5 01913 @GTDCT PUSH HL ;Get i/o routine addr
1A1F CD341A 01914 CALL DCTFLD@ ; into IY
1A22 E3 01915 EX (SP),HL
1A23 FDE1 01916 POP IY
1A25 C9 01917 RET
01918 ;
01919 ; Entry to get DCT+8 of FCB (IX) drive spec
01920 ;
1A26 DD4E06 01921 D@FBYT8 LD C,(IX+6) ;P/u drive
01922 ;
01923 ; Entry to get DCT+8 of Reg C drive spec
01924 ;
01925 DCTBYT8@
1A29 3E08 01926 LD A,8
01927 ;
01928 ; Entry to get byte (Reg A) from DCT of Reg C drive
01929 ; C => logical drive specification
01930 ; A => relative byte requested from DCT
01931 ; A <= data at position requested
01932 ;
1A2B E5 01933 @DCTBYT PUSH HL ;Save the register pair
1A2C 67 01934 LD H,A ;Xfer relative position
1A2D CD341A 01935 CALL DCTFLD@ ;Get HL pointing to
1A30 6F 01936 LD L,A ; DCT position
1A31 7E 01937 LD A,(HL) ;Get the byte
1A32 E1 01938 POP HL
1A33 C9 01939 RET
01940 ;
01941 ; Entry to get HL pointing to DCT byte Reg C, Reg A
01942 ; C => logical drive number
01943 ; A => relative byte in DCT requested
01944 ; HL <= start of requested DCT for the drive
01945 ; A <= low order pointer to relative byte request
01946 ;
1A34 79 01947 DCTFLD@ LD A,C ;Get drive spec &
1A35 E607 01948 AND 7 ; strip excess data
1A37 87 01949 ADD A,A ;Times 2
1A38 6F 01950 LD L,A ; & saved
1A39 87 01951 ADD A,A ;Times 4
1A3A 87 01952 ADD A,A ;Times 8
1A3B 85 01953 ADD A,L ;Times 10
1A3C C670 01954 ADD A,70H ;Add DCT offset from 0
1A3E 6F 01955 LD L,A ;Point L to DCT low order
1A3F 84 01956 ADD A,H ;Add in rel pos desired
1A40 2604 01957 LD H,DCT$<-8 ;Point H to DCT hi-order
1A42 C9 01958 RET
01959 ;
01960 ; Process supervisory calls <0-127>
01961 ;
1A43 FE1A 01962 SVCUSER CP 26 ;Check for @ERROR
1A45 2808 01963 JR Z,ERRSVC ;Skip next if so
1A47 320D00 01964 LD (LSVC$),A ;Store SVC request
1A4A E3 01965 EX (SP),HL ;P/u RET address
1A4B 220B00 01966 LD (SVCRET$),HL ; and save it
1A4E E3 01967 EX (SP),HL ;Restore RET address
1A4F E5 01968 ERRSVC PUSH HL ;Save HL
1A50 07 01969 RLCA ;Multiply by two
1A51 2601 01970 LD H,SVCTAB$<-8 ;Base of table
1A53 6F 01971 LD L,A ;Set up the low order
1A54 7E 01972 LD A,(HL) ;P/u table entry
1A55 2C 01973 INC L
1A56 66 01974 LD H,(HL)
1A57 6F 01975 LD L,A
1A58 E3 01976 EX (SP),HL ;P/u HL & stuff vector
1A59 79 01977 LD A,C ;Xfer for PUT type ops
1A5A C9 01978 RET
01979 ;
01980 ; RST 28 vector - System & user SVCs
01981 ;
1A5B B7 01982 RST28 OR A ;Test if bit 7 set
1A5C F2431A 01983 JP P,SVCUSER ;Jump on user SVC attempt
1A5F E3 01984 EX (SP),HL ;Discard return addr &
1A60 F5 01985 PUSH AF ; save HL, AF
1A61 219F19 01986 LD HL,@DBGHK ;Set up DEBUG linkage
1A64 7E 01987 LD A,(HL)
1A65 32791A 01988 LD (SET@EXEC),A
1A68 36C9 01989 LD (HL),0C9H
1A6A F1 01990 POP AF ;Restore AF, HL
1A6B E1 01991 POP HL
1A6C CD7F1A 01992 HKRES$ CALL CKMOD@ ;Get overlay if needed
1A6F 3E00 01993 LD A,0 ;P/u new overlay #
1A70 01994 OVRLYOLD EQU $-1
1A71 326900 01995 LD (OVRLY$),A ; & update current
1A74 CD0000 01996 TRANSFR CALL 0 ;Traadr of SYSx
1A77 F5 01997 PUSH AF
1A78 3E00 01998 LD A,0 ;Set to C9 if EXEC only
1A79 01999 SET@EXEC EQU $-1
1A7A 329F19 02000 LD (@DBGHK),A
1A7D F1 02001 POP AF
1A7E C9 02002 RET
02003 ;
02004 ; DOS command overlay request
02005 ;
1A7F E5 02006 CKMOD@ PUSH HL
1A80 67 02007 LD H,A ;Save command value
1A81 78 02008 LD A,B
1A82 32D21A 02009 LD (EXOVR2+1),A ;Set overlay #
1A85 7C 02010 LD A,H
1A86 F601 02011 OR 1 ;Set for SYS6 & SYS7
1A88 FE89 02012 CP 89H ;Is it either?
1A8A 7C 02013 LD A,H ;Get back the correct #
1A8B 2813 02014 JR Z,EXOVR ;Sys6/7 req? Use ISAM!
1A8D FE8A 02015 CP 8AH ;Sys8 also ISAM
1A8F 280F 02016 JR Z,EXOVR
1A91 3A6900 02017 LD A,(OVRLY$) ;P/u current overlay
1A94 AC 02018 XOR H ;Ck if it's the one
1A95 E60F 02019 AND 0FH ; we need to execute
1A97 7C 02020 LD A,H
1A98 32701A 02021 LD (OVRLYOLD),A ;Update current tempy
1A9B 21001E 02022 LD HL,OVERLAY ;Init to SYSx entry
1A9E 283A 02023 JR Z,EXOVR3 ;Go exec if resident
02024 ;
02025 ; Execute a system overlay
02026 ;
1AA0 D5 02027 EXOVR PUSH DE
1AA1 C5 02028 PUSH BC
1AA2 E60F 02029 AND 0FH ;Get right nybble
1AA4 CB5F 02030 BIT 3,A ;Check for SYS0-7
1AA6 2802 02031 JR Z,EXOVR1 ; w/o changing carry
1AA8 C618 02032 ADD A,18H ;Adjust for sys8-15
1AAA 329300 02033 EXOVR1 LD (SFCB$+7),A
1AAD 47 02034 LD B,A ;Set DEC for directory
1AAE 3E20 02035 LD A,20H ;Set bit 5 of FCB+1
1AB0 328D00 02036 LD (SFCB$+1),A
1AB3 ED62 02037 SBC HL,HL ;Carry is clear here
1AB5 229600 02038 LD (SFCB$+10),HL ;Zero NRN
1AB8 4C 02039 LD C,H ;Init for drive 0
1AB9 CDBB18 02040 CALL @DIRRD ;Read dir entry
1ABC 201A 02041 JR NZ,EXERR ;Go if error
1ABE 7E 02042 LD A,(HL) ;Was overlay purged?
1ABF E650 02043 AND 50H ; or is it non-system?
1AC1 EE50 02044 XOR 50H
1AC3 3E07 02045 LD A,7 ;Init "deleted error
1AC5 2011 02046 JR NZ,EXERR
1AC7 7D 02047 LD A,L
1AC8 C616 02048 ADD A,22 ;Point to 1st extent
1ACA 6F 02049 LD L,A
1ACB 119A00 02050 LD DE,SFCB$+14 ;Extent field in FCB
1ACE CDE11A 02051 CALL PAT1 ;Stuff 1st two extents
1AD1 0600 02052 EXOVR2 LD B,0 ;P/u ISAM # or zero
1AD3 1E8C 02053 LD E,SFCB$&0FFH
1AD5 CD561B 02054 CALL LOADER ;Read system overlay
1AD8 C1 02055 EXERR POP BC
1AD9 D1 02056 POP DE
1ADA 22751A 02057 EXOVR3 LD (TRANSFR+1),HL ;Stuff overlay entry pt
1ADD E1 02058 POP HL
1ADE C8 02059 RET Z
1ADF 1816 02060 JR SYSERR ;Go if I/O error on read
02061 ;
02062 ; Routine to calculate 1st two extents of SYS file
02063 ;
1AE1 CDEC1A 02064 PAT1 CALL PAT1A ;Move first extent
1AE4 E61F 02065 AND 1FH ;Compute # of granules
1AE6 3C 02066 INC A
1AE7 12 02067 LD (DE),A ;And store in FCB
1AE8 13 02068 INC DE
1AE9 AF 02069 XOR A
1AEA 12 02070 LD (DE),A
1AEB 13 02071 INC DE
1AEC CDEF1A 02072 PAT1A CALL PAT1B ;Move second extent
1AEF 7E 02073 PAT1B LD A,(HL)
1AF0 12 02074 LD (DE),A
1AF1 23 02075 INC HL
1AF2 13 02076 INC DE
1AF3 C9 02077 RET
02078 ;
02079 ; System error display routine
02080 ; The NOP is provided so an intercept routine vector
02081 ; may be patched in during program development
02082 ;
1AF4 3E2B 02083 SVCERR LD A,43 ;SVC error
1AF6 00 02084 NOP
1AF7 E63F 02085 SYSERR AND 3FH ;Strip excess bits
1AF9 21191B 02086 LD HL,ERRNUM ;Pack error number
1AFC CDC207 02087 CALL @HEX8 ; into message
1AFF 21131B 02088 LD HL,SYSERR$
1B02 CD0005 02089 CALL @LOGOT ;Log the error & ABORT
1B05 318003 02090 LD SP,STACK$ ;reset stack
1B08 21FFFF 02091 @ABORT LD HL,-1
1B0B 3E93 02092 @EXIT LD A,93H ;Exit to DOS
1B0D EF 02093 RST 40
02094 ;
1B0E E1 02095 POPERR POP HL ;Pop extended error
1B0F F5 02096 @ERROR PUSH AF ;Save the error code
1B10 3E96 02097 LD A,96H ;Display the error number
1B12 EF 02098 RST 40
02099 ;
1B13 45 02100 SYSERR$ DM 'Error '
72 72 6F 72 20
1B19 78 02101 ERRNUM DM 'xxH',CR
78 48 0D
02102 ;
02103 ; Routine to RUN a program
02104 ;
1B1D E5 02105 @RUN PUSH HL ;Save register pair
1B1E 217C00 02106 LD HL,SFLAG$
1B21 CBD6 02107 SET 2,(HL) ;Turn on RUN flag bit
1B23 CD381B 02108 CALL @LOAD ;Load the program module
1B26 E3 02109 EX (SP),HL ;Put traadr on the stack
02110 ;
02111 ; Note: The error code is set to NOT abort. Errors
02112 ; will be passed back to the calling module after
02113 ; @ERROR. Note that HL will contain the error #.
02114 ;
1B27 20E5 02115 JR NZ,POPERR
02116 ;
02117 ; Place the INBUF$ pointer in register pair BC
02118 ;
1B29 012004 02119 LD BC,INBUF$ ;Reflect buffer pointer
02120 ;
02121 ; Get TRAADR then test if we need to go to DEBUG
02122 ;
1B2C 3A7C00 02123 LD A,(SFLAG$)
1B2F CB4F 02124 BIT 1,A ;Go to the program if
1B31 C0 02125 RET NZ ; its EXEC only access
1B32 CB7F 02126 BIT 7,A ; else test if DEBUG
1B34 C23000 02127 JP NZ,@RST30 ; is on & go to it
1B37 C9 02128 RET ; else go to program
02129 ;
02130 ; This routine LOADs a Load Module Format file
02131 ;
1B38 0600 02132 @LOAD LD B,0 ;LRL=256
1B3A 217C00 02133 LD HL,SFLAG$
1B3D CBC6 02134 SET 0,(HL) ;Don't set "file open"
1B3F 21001D 02135 LD HL,SBUFF$ ;Set buffer to system
1B42 CD8A19 02136 CALL @OPEN ;Open the file
1B45 D5 02137 PUSH DE ;Save FCB pointer
1B46 CC561B 02138 CALL Z,LOADER ;Load if no OPEN error
1B49 D1 02139 POP DE ;Restore FCB pointer
1B4A C8 02140 RET Z ;Back if no error
1B4B 6F 02141 LD L,A ;Xfer the error code
1B4C 2600 02142 LD H,0
1B4E F6C0 02143 OR 0C0H ;Set RETurn & abbrev
1B50 FED8 02144 CP 0D8H ;Change "file not in dir"
1B52 C0 02145 RET NZ ; to "program not found"
1B53 C607 02146 ADD A,7
1B55 C9 02147 RET
02148 ;
02149 ; System command file loader
02150 ;
1B56 78 02151 LOADER LD A,B ;Set overlay # (0 on non
1B57 32B31B 02152 LD (LDR14+1),A ; SYStem file)
1B5A D5 02153 PUSH DE ;Save IX & xfer FCB to IX
1B5B DDE3 02154 EX (SP),IX
1B5D 11FF1D 02155 LD DE,SBUFF$+255 ;Init to end of buffer
1B60 CD6F1B 02156 CALL LDR01 ;Do the load
1B63 DDE1 02157 POP IX ;Recover IX
1B65 C9 02158 RET
02159 ;
02160 ; Routine to ignore the LMF record
02161 ;
1B66 CDD61B 02162 LDR05 CALL LDR15 ;Get length of "comment"
1B69 47 02163 LD B,A
1B6A CDD61B 02164 LDR06 CALL LDR15 ;Read & ignore that many
1B6D 10FB 02165 DJNZ LDR06 ; bytes then fall thru
02166 ;
02167 ; Routine to parse LMF record types
02168 ;
1B6F CDD61B 02169 LDR01 CALL LDR15 ;Get record type
1B72 FE01 02170 LDR02 CP 1 ;Start of block?
1B74 281F 02171 JR Z,LDR08
1B76 FE02 02172 CP 2 ;Start of TRAADR?
1B78 2814 02173 LDR03 JR Z,LDR07
1B7A FE04 02174 CP 4 ;End of LIB member?
1B7C 282A 02175 JR Z,LDR12
1B7E FE08 02176 CP 8 ;Begin ISAM table entry?
1B80 2828 02177 JR Z,LDR13
1B82 FE0A 02178 CP 10 ;End of ISAM map?
1B84 2804 02179 JR Z,LDR04
1B86 FE20 02180 CP 20H ;Ignore all other control
1B88 38DC 02181 JR C,LDR05
1B8A 3E22 02182 LDR04 LD A,22H ;Load file format err
1B8C B7 02183 OR A
1B8D C9 02184 RET
02185 ;
02186 ; Grab transfer address
02187 ;
1B8E CDD61B 02188 LDR07 CALL LDR15 ;Bypass 2nd X'02'
1B91 CDE81B 02189 CALL GETADR ;P/u transfer address
1B94 C9 02190 RET ;Ret Z or NZ
02191 ;
02192 ; Grab load block
02193 ;
1B95 CDD61B 02194 LDR08 CALL LDR15 ;P/u block len
1B98 47 02195 LD B,A
1B99 CDE81B 02196 CALL GETADR ;P/u load address
1B9C C0 02197 RET NZ
1B9D 05 02198 DEC B ;Adj length for adr
1B9E 05 02199 DEC B
1B9F CDD61B 02200 LDR09 CALL LDR15 ;P/u block byte
1BA2 77 02201 LD (HL),A
1BA3 23 02202 INC HL
1BA4 10F9 02203 DJNZ LDR09 ;Loop until block end
1BA6 18C7 02204 JR LDR01
02205 ;
1BA8 E1 02206 LDR12 POP HL
1BA9 C9 02207 RET
02208 ;
02209 ; Routine to check ISAM table match
02210 ;
1BAA CDD61B 02211 LDR13 CALL LDR15 ;Get record length
1BAD 47 02212 LD B,A
1BAE CDD61B 02213 CALL LDR15 ;Get ISAM number
1BB1 05 02214 DEC B ; & decrement counter
1BB2 FE00 02215 LDR14 CP 0 ;Either ISAM# or 0
1BB4 20B4 02216 JR NZ,LDR06 ;Go if not a match
1BB6 CDE81B 02217 CALL GETADR ; else get the TRAADR
1BB9 E5 02218 PUSH HL ; & save it
1BBA CCE81B 02219 CALL Z,GETADR ;Get the NRN for member
1BBD 2027 02220 JR NZ,LODERR
1BBF CDD61B 02221 CALL LDR15 ;Get the sector offset
1BC2 5F 02222 LD E,A ;Update pointer offset
1BC3 C5 02223 PUSH BC
1BC4 44 02224 LD B,H ;Xfer NRN position needed
1BC5 4D 02225 LD C,L
1BC6 D5 02226 PUSH DE ;Save buffer ptr offset
1BC7 DDE5 02227 PUSH IX
1BC9 D1 02228 POP DE ;P/u FCB into DE
1BCA CD5B14 02229 CALL @POSN ;Position to ISAM rec
1BCD D1 02230 POP DE ;Rcvr buffer ptr offset
1BCE C1 02231 POP BC
1BCF 2015 02232 JR NZ,LODERR
1BD1 CDDB1B 02233 CALL LDR17 ;Read the sector
1BD4 189C 02234 JR LDR02 ;Now go read the member
02235 ;
02236 ; Routine to get the next file byte
02237 ;
1BD6 1C 02238 LDR15 INC E ;Bump buf pointer
1BD7 2802 02239 JR Z,LDR17 ;Read sector if needed
1BD9 1A 02240 LDR16 LD A,(DE) ;P/U byte from buffer
1BDA C9 02241 RET
1BDB E5 02242 LDR17 PUSH HL ;Save regs
1BDC D5 02243 PUSH DE
1BDD C5 02244 PUSH BC
1BDE CD7513 02245 CALL NXTSECT ;Read next record
1BE1 C1 02246 POP BC ;Restore regs
1BE2 D1 02247 POP DE
1BE3 E1 02248 POP HL
1BE4 28F3 02249 JR Z,LDR16 ;Bypass if no error
1BE6 C1 02250 LODERR POP BC ;Pop return address
1BE7 C9 02251 RET
02252 ;
02253 ; Routine to get an address field
02254 ;
1BE8 CDD61B 02255 GETADR CALL LDR15 ;Get low order byte
1BEB 6F 02256 LD L,A
1BEC CDD61B 02257 CALL LDR15 ;Get hi order byte
1BEF 67 02258 LD H,A
1BF0 BF 02259 CP A
1BF1 C9 02260 RET
02261 ;
02262 ; BOOT code brings back the ROM
02263 ;
4300 02264 MOD3BUF EQU 4300H
1BF2 21FB03 02265 @IPL LD HL,BOOTCOD ;Code to toggle in ROM
1BF5 110043 02266 LD DE,MOD3BUF ;Buffer used by ROM
1BF8 D5 02267 PUSH DE ;This is return address
1BF9 010500 02268 LD BC,BOOTLEN
1BFC EDB0 02269 LDIR ;Transfer boot code and
1BFE C9 02270 RET ; jump to it
02271 ;
02272 ; End of loader module
02273 ;
1BFF 02276 *GET TASKER:3
02277 ;TASKER/ASM - LS-DOS 6.2
02278 ;
02279 ; Interrupt task table, IM 1
02280 ;
1BFF 02281 CORE$ DEFL $
004E 02282 ORG TCB$
004E E91C 02283 DW NOTASK,NOTASK,NOTASK,NOTASK
E91C E91C E91C
0056 E91C 02284 DW NOTASK,NOTASK,NOTASK,NOTASK
E91C E91C E91C
005E E91C 02285 DW NOTASK,NOTASK,TYPTSK$,NOTASK
E91C 260B E91C
1BFF 02286 ORG CORE$
02287 ;
02288 ; Model IV task processor
02289 ;
02290 RST38@
1BFF E3 02291 EX (SP),HL
1C00 22AF07 02292 LD (PCSAVE$),HL ;Save for TRACE
1C03 E3 02293 EX (SP),HL
1C04 E5 02294 PUSH HL ;Save HL for now
1C05 F5 02295 PUSH AF ;Save AF for now
1C06 217700 02296 LD HL,NFLAG$ ;Show the system we
1C09 CBF6 02297 SET 6,(HL) ; are in the TASKER
1C0B 210202 02298 LD HL,LBANK$ ;P/U & save the current
1C0E 7E 02299 LD A,(HL) ; logical bank #
1C0F 3600 02300 LD (HL),0
1C11 F5 02301 PUSH AF
1C12 217800 02302 LD HL,OPREG$ ;Get current memory
1C15 7E 02303 LD A,(HL)
1C16 F5 02304 PUSH AF ; config & save
1C17 E68C 02305 AND 8CH ;Strip bits 0, 1, 4-6
1C19 F603 02306 OR 3 ;Bring up regular 64K
1C1B 77 02307 LD (HL),A
1C1C D384 02308 OUT (@OPREG),A
00E0 02309 INTLAT EQU 0E0H
1C1E DBE0 02310 IN A,(INTLAT) ;Get interrupt latch
1C20 2F 02311 CPL ;Mod IV is reverse
1C21 213C00 02312 LD HL,INTIM$ ;Store state of int
1C24 77 02313 LD (HL),A
1C25 2C 02314 INC L ;Advance to int mask
1C26 A6 02315 AND (HL) ;Mask the latch bits
1C27 2808 02316 JR Z,TSTBRK ;Go if nothing interptd
1C29 2C 02317 NXTVCT INC L ;Ck on INTVC$
1C2A 1F 02318 RRA ;Ck if device interrupted
1C2B 381C 02319 JR C,ACTVTSK
1C2D 2C 02320 NXTMSK INC L ;Ck all 8 bits of mask
1C2E B7 02321 OR A ;When fin, ck overhead
1C2F 20F8 02322 JR NZ,NXTVCT ; task routine
02323 ;
1C31 CDD607 02324 TSTBRK CALL KCK@ ;Test ,
1C34 202A 02325 JR NZ,BREAK? ;Go if break
1C36 F1 02326 TSKEXIT POP AF ;Get previous mem config
1C37 327800 02327 LD (OPREG$),A ; & restore to it
1C3A D384 02328 OUT (@OPREG),A
1C3C F1 02329 POP AF
1C3D 320202 02330 LD (LBANK$),A
1C40 217700 02331 LD HL,NFLAG$ ;Now leaving the TASKER
1C43 CBB6 02332 RES 6,(HL) ; show the system
1C45 F1 02333 POP AF ;Restore previous regs
1C46 E1 02334 POP HL
1C47 FB 02335 EI
1C48 C9 02336 RETINST RET
02337 ;
02338 ;
02339 ; Found active INTVC$
02340 ;
1C49 F5 02341 ACTVTSK PUSH AF ;Save the regs
1C4A C5 02342 PUSH BC
1C4B D5 02343 PUSH DE
1C4C E5 02344 PUSH HL
1C4D DDE5 02345 PUSH IX
1C4F 11581C 02346 LD DE,POPREGS ;Stack return vector
1C52 D5 02347 PUSH DE
1C53 5E 02348 LD E,(HL) ;P/u INTVC pointer vector
1C54 2C 02349 INC L
1C55 56 02350 LD D,(HL)
1C56 EB 02351 EX DE,HL ;Shift it to HL
1C57 E9 02352 JP (HL) ;Go to service routine
02353 ;
02354 ; Register restoral after service routine
02355 ;
1C58 DDE1 02356 POPREGS POP IX
1C5A E1 02357 POP HL
1C5B D1 02358 POP DE
1C5C C1 02359 POP BC
1C5D F1 02360 POP AF
1C5E 18CD 02361 JR NXTMSK ;Loop to next mask bit
02362 ;
02363 ; BREAK key detected
02364 ;
1C60 3008 02365 BREAK? JR NC,GOTBRK ;Go if only
1C62 C5 02366 PUSH BC ;Was
1C63 F3 02367 DI
1C64 CDB819 02368